00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "snd_local.h"
00024
00025 long myftol( float f );
00026
00027 #define C0 0.4829629131445341
00028 #define C1 0.8365163037378079
00029 #define C2 0.2241438680420134
00030 #define C3 -0.1294095225512604
00031
00032 void daub4(float b[], unsigned long n, int isign)
00033 {
00034 float wksp[4097];
00035 float *a=b-1;
00036
00037 unsigned long nh,nh1,i,j;
00038
00039 if (n < 4) return;
00040
00041 nh1=(nh=n >> 1)+1;
00042 if (isign >= 0) {
00043 for (i=1,j=1;j<=n-3;j+=2,i++) {
00044 wksp[i] = C0*a[j]+C1*a[j+1]+C2*a[j+2]+C3*a[j+3];
00045 wksp[i+nh] = C3*a[j]-C2*a[j+1]+C1*a[j+2]-C0*a[j+3];
00046 }
00047 wksp[i ] = C0*a[n-1]+C1*a[n]+C2*a[1]+C3*a[2];
00048 wksp[i+nh] = C3*a[n-1]-C2*a[n]+C1*a[1]-C0*a[2];
00049 } else {
00050 wksp[1] = C2*a[nh]+C1*a[n]+C0*a[1]+C3*a[nh1];
00051 wksp[2] = C3*a[nh]-C0*a[n]+C1*a[1]-C2*a[nh1];
00052 for (i=1,j=3;i<nh;i++) {
00053 wksp[j++] = C2*a[i]+C1*a[i+nh]+C0*a[i+1]+C3*a[i+nh1];
00054 wksp[j++] = C3*a[i]-C0*a[i+nh]+C1*a[i+1]-C2*a[i+nh1];
00055 }
00056 }
00057 for (i=1;i<=n;i++) {
00058 a[i]=wksp[i];
00059 }
00060 }
00061
00062 void wt1(float a[], unsigned long n, int isign)
00063 {
00064 unsigned long nn;
00065 int inverseStartLength = n/4;
00066 if (n < inverseStartLength) return;
00067 if (isign >= 0) {
00068 for (nn=n;nn>=inverseStartLength;nn>>=1) daub4(a,nn,isign);
00069 } else {
00070 for (nn=inverseStartLength;nn<=n;nn<<=1) daub4(a,nn,isign);
00071 }
00072 }
00073
00074
00075 static unsigned char numBits[] = {
00076 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,
00077 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,
00078 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,
00079 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,
00080 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,
00081 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,
00082 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,
00083 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,
00084 };
00085
00086 byte MuLawEncode(short s) {
00087 unsigned long adjusted;
00088 byte sign, exponent, mantissa;
00089
00090 sign = (s<0)?0:0x80;
00091
00092 if (s<0) s=-s;
00093 adjusted = (long)s << (16-sizeof(short)*8);
00094 adjusted += 128L + 4L;
00095 if (adjusted > 32767) adjusted = 32767;
00096 exponent = numBits[(adjusted>>7)&0xff] - 1;
00097 mantissa = (adjusted>>(exponent+3))&0xf;
00098 return ~(sign | (exponent<<4) | mantissa);
00099 }
00100
00101 short MuLawDecode(byte uLaw) {
00102 signed long adjusted;
00103 byte exponent, mantissa;
00104
00105 uLaw = ~uLaw;
00106 exponent = (uLaw>>4) & 0x7;
00107 mantissa = (uLaw&0xf) + 16;
00108 adjusted = (mantissa << (exponent +3)) - 128 - 4;
00109
00110 return (uLaw & 0x80)? adjusted : -adjusted;
00111 }
00112
00113 short mulawToShort[256];
00114 static qboolean madeTable = qfalse;
00115
00116 static int NXStreamCount;
00117
00118 void NXPutc(NXStream *stream, char out) {
00119 stream[NXStreamCount++] = out;
00120 }
00121
00122
00123 void encodeWavelet( sfx_t *sfx, short *packets) {
00124 float wksp[4097], temp;
00125 int i, samples, size;
00126 sndBuffer *newchunk, *chunk;
00127 byte *out;
00128
00129 if (!madeTable) {
00130 for (i=0;i<256;i++) {
00131 mulawToShort[i] = (float)MuLawDecode((byte)i);
00132 }
00133 madeTable = qtrue;
00134 }
00135 chunk = NULL;
00136
00137 samples = sfx->soundLength;
00138 while(samples>0) {
00139 size = samples;
00140 if (size>(SND_CHUNK_SIZE*2)) {
00141 size = (SND_CHUNK_SIZE*2);
00142 }
00143
00144 if (size<4) {
00145 size = 4;
00146 }
00147
00148 newchunk = SND_malloc();
00149 if (sfx->soundData == NULL) {
00150 sfx->soundData = newchunk;
00151 } else {
00152 chunk->next = newchunk;
00153 }
00154 chunk = newchunk;
00155 for(i=0; i<size; i++) {
00156 wksp[i] = *packets;
00157 packets++;
00158 }
00159 wt1(wksp, size, 1);
00160 out = (byte *)chunk->sndChunk;
00161
00162 for(i=0;i<size;i++) {
00163 temp = wksp[i];
00164 if (temp > 32767) temp = 32767; else if (temp<-32768) temp = -32768;
00165 out[i] = MuLawEncode((short)temp);
00166 }
00167
00168 chunk->size = size;
00169 samples -= size;
00170 }
00171 }
00172
00173 void decodeWavelet(sndBuffer *chunk, short *to) {
00174 float wksp[4097];
00175 int i;
00176 byte *out;
00177
00178 int size = chunk->size;
00179
00180 out = (byte *)chunk->sndChunk;
00181 for(i=0;i<size;i++) {
00182 wksp[i] = mulawToShort[out[i]];
00183 }
00184
00185 wt1(wksp, size, -1);
00186
00187 if (!to) return;
00188
00189 for(i=0; i<size; i++) {
00190 to[i] = wksp[i];
00191 }
00192 }
00193
00194
00195 void encodeMuLaw( sfx_t *sfx, short *packets) {
00196 int i, samples, size, grade, poop;
00197 sndBuffer *newchunk, *chunk;
00198 byte *out;
00199
00200 if (!madeTable) {
00201 for (i=0;i<256;i++) {
00202 mulawToShort[i] = (float)MuLawDecode((byte)i);
00203 }
00204 madeTable = qtrue;
00205 }
00206
00207 chunk = NULL;
00208 samples = sfx->soundLength;
00209 grade = 0;
00210
00211 while(samples>0) {
00212 size = samples;
00213 if (size>(SND_CHUNK_SIZE*2)) {
00214 size = (SND_CHUNK_SIZE*2);
00215 }
00216
00217 newchunk = SND_malloc();
00218 if (sfx->soundData == NULL) {
00219 sfx->soundData = newchunk;
00220 } else {
00221 chunk->next = newchunk;
00222 }
00223 chunk = newchunk;
00224 out = (byte *)chunk->sndChunk;
00225 for(i=0; i<size; i++) {
00226 poop = packets[0]+grade;
00227 if (poop>32767) {
00228 poop = 32767;
00229 } else if (poop<-32768) {
00230 poop = -32768;
00231 }
00232 out[i] = MuLawEncode((short)poop);
00233 grade = poop - mulawToShort[out[i]];
00234 packets++;
00235 }
00236 chunk->size = size;
00237 samples -= size;
00238 }
00239 }
00240
00241 void decodeMuLaw(sndBuffer *chunk, short *to) {
00242 int i;
00243 byte *out;
00244
00245 int size = chunk->size;
00246
00247 out = (byte *)chunk->sndChunk;
00248 for(i=0;i<size;i++) {
00249 to[i] = mulawToShort[out[i]];
00250 }
00251 }
00252
00253