Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

snd_wavelet.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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;                     // numerical recipies so a[1] = b[0]
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 /* The number of bits required by each value */
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 

Generated on Thu Aug 25 12:37:28 2005 for Quake III Arena by  doxygen 1.3.9.1