Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

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