snd_wavelet.c (5930B)
1 /* 2 =========================================================================== 3 Copyright (C) 1999-2005 Id Software, Inc. 4 5 This file is part of Quake III Arena source code. 6 7 Quake III Arena source code is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the License, 10 or (at your option) any later version. 11 12 Quake III Arena source code is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Foobar; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 =========================================================================== 21 */ 22 23 #include "snd_local.h" 24 25 long myftol( float f ); 26 27 #define C0 0.4829629131445341 28 #define C1 0.8365163037378079 29 #define C2 0.2241438680420134 30 #define C3 -0.1294095225512604 31 32 void daub4(float b[], unsigned long n, int isign) 33 { 34 float wksp[4097]; 35 float *a=b-1; // numerical recipies so a[1] = b[0] 36 37 unsigned long nh,nh1,i,j; 38 39 if (n < 4) return; 40 41 nh1=(nh=n >> 1)+1; 42 if (isign >= 0) { 43 for (i=1,j=1;j<=n-3;j+=2,i++) { 44 wksp[i] = C0*a[j]+C1*a[j+1]+C2*a[j+2]+C3*a[j+3]; 45 wksp[i+nh] = C3*a[j]-C2*a[j+1]+C1*a[j+2]-C0*a[j+3]; 46 } 47 wksp[i ] = C0*a[n-1]+C1*a[n]+C2*a[1]+C3*a[2]; 48 wksp[i+nh] = C3*a[n-1]-C2*a[n]+C1*a[1]-C0*a[2]; 49 } else { 50 wksp[1] = C2*a[nh]+C1*a[n]+C0*a[1]+C3*a[nh1]; 51 wksp[2] = C3*a[nh]-C0*a[n]+C1*a[1]-C2*a[nh1]; 52 for (i=1,j=3;i<nh;i++) { 53 wksp[j++] = C2*a[i]+C1*a[i+nh]+C0*a[i+1]+C3*a[i+nh1]; 54 wksp[j++] = C3*a[i]-C0*a[i+nh]+C1*a[i+1]-C2*a[i+nh1]; 55 } 56 } 57 for (i=1;i<=n;i++) { 58 a[i]=wksp[i]; 59 } 60 } 61 62 void wt1(float a[], unsigned long n, int isign) 63 { 64 unsigned long nn; 65 int inverseStartLength = n/4; 66 if (n < inverseStartLength) return; 67 if (isign >= 0) { 68 for (nn=n;nn>=inverseStartLength;nn>>=1) daub4(a,nn,isign); 69 } else { 70 for (nn=inverseStartLength;nn<=n;nn<<=1) daub4(a,nn,isign); 71 } 72 } 73 74 /* The number of bits required by each value */ 75 static unsigned char numBits[] = { 76 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 77 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 78 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 79 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 80 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 81 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 82 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 83 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 84 }; 85 86 byte MuLawEncode(short s) { 87 unsigned long adjusted; 88 byte sign, exponent, mantissa; 89 90 sign = (s<0)?0:0x80; 91 92 if (s<0) s=-s; 93 adjusted = (long)s << (16-sizeof(short)*8); 94 adjusted += 128L + 4L; 95 if (adjusted > 32767) adjusted = 32767; 96 exponent = numBits[(adjusted>>7)&0xff] - 1; 97 mantissa = (adjusted>>(exponent+3))&0xf; 98 return ~(sign | (exponent<<4) | mantissa); 99 } 100 101 short MuLawDecode(byte uLaw) { 102 signed long adjusted; 103 byte exponent, mantissa; 104 105 uLaw = ~uLaw; 106 exponent = (uLaw>>4) & 0x7; 107 mantissa = (uLaw&0xf) + 16; 108 adjusted = (mantissa << (exponent +3)) - 128 - 4; 109 110 return (uLaw & 0x80)? adjusted : -adjusted; 111 } 112 113 short mulawToShort[256]; 114 static qboolean madeTable = qfalse; 115 116 static int NXStreamCount; 117 118 void NXPutc(NXStream *stream, char out) { 119 stream[NXStreamCount++] = out; 120 } 121 122 123 void encodeWavelet( sfx_t *sfx, short *packets) { 124 float wksp[4097], temp; 125 int i, samples, size; 126 sndBuffer *newchunk, *chunk; 127 byte *out; 128 129 if (!madeTable) { 130 for (i=0;i<256;i++) { 131 mulawToShort[i] = (float)MuLawDecode((byte)i); 132 } 133 madeTable = qtrue; 134 } 135 chunk = NULL; 136 137 samples = sfx->soundLength; 138 while(samples>0) { 139 size = samples; 140 if (size>(SND_CHUNK_SIZE*2)) { 141 size = (SND_CHUNK_SIZE*2); 142 } 143 144 if (size<4) { 145 size = 4; 146 } 147 148 newchunk = SND_malloc(); 149 if (sfx->soundData == NULL) { 150 sfx->soundData = newchunk; 151 } else { 152 chunk->next = newchunk; 153 } 154 chunk = newchunk; 155 for(i=0; i<size; i++) { 156 wksp[i] = *packets; 157 packets++; 158 } 159 wt1(wksp, size, 1); 160 out = (byte *)chunk->sndChunk; 161 162 for(i=0;i<size;i++) { 163 temp = wksp[i]; 164 if (temp > 32767) temp = 32767; else if (temp<-32768) temp = -32768; 165 out[i] = MuLawEncode((short)temp); 166 } 167 168 chunk->size = size; 169 samples -= size; 170 } 171 } 172 173 void decodeWavelet(sndBuffer *chunk, short *to) { 174 float wksp[4097]; 175 int i; 176 byte *out; 177 178 int size = chunk->size; 179 180 out = (byte *)chunk->sndChunk; 181 for(i=0;i<size;i++) { 182 wksp[i] = mulawToShort[out[i]]; 183 } 184 185 wt1(wksp, size, -1); 186 187 if (!to) return; 188 189 for(i=0; i<size; i++) { 190 to[i] = wksp[i]; 191 } 192 } 193 194 195 void encodeMuLaw( sfx_t *sfx, short *packets) { 196 int i, samples, size, grade, poop; 197 sndBuffer *newchunk, *chunk; 198 byte *out; 199 200 if (!madeTable) { 201 for (i=0;i<256;i++) { 202 mulawToShort[i] = (float)MuLawDecode((byte)i); 203 } 204 madeTable = qtrue; 205 } 206 207 chunk = NULL; 208 samples = sfx->soundLength; 209 grade = 0; 210 211 while(samples>0) { 212 size = samples; 213 if (size>(SND_CHUNK_SIZE*2)) { 214 size = (SND_CHUNK_SIZE*2); 215 } 216 217 newchunk = SND_malloc(); 218 if (sfx->soundData == NULL) { 219 sfx->soundData = newchunk; 220 } else { 221 chunk->next = newchunk; 222 } 223 chunk = newchunk; 224 out = (byte *)chunk->sndChunk; 225 for(i=0; i<size; i++) { 226 poop = packets[0]+grade; 227 if (poop>32767) { 228 poop = 32767; 229 } else if (poop<-32768) { 230 poop = -32768; 231 } 232 out[i] = MuLawEncode((short)poop); 233 grade = poop - mulawToShort[out[i]]; 234 packets++; 235 } 236 chunk->size = size; 237 samples -= size; 238 } 239 } 240 241 void decodeMuLaw(sndBuffer *chunk, short *to) { 242 int i; 243 byte *out; 244 245 int size = chunk->size; 246 247 out = (byte *)chunk->sndChunk; 248 for(i=0;i<size;i++) { 249 to[i] = mulawToShort[out[i]]; 250 } 251 } 252 253