/* =========================================================================== Copyright (C) 1999-2005 Id Software, Inc. This file is part of Quake III Arena source code. Quake III Arena source code is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Quake III Arena source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Quake III Arena source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ #include "snd_local.h" #define C0 0.4829629131445341 #define C1 0.8365163037378079 #define C2 0.2241438680420134 #define C3 -0.1294095225512604 void daub4( float b[], unsigned long n, int isign ) { float wksp[ 4097 ] = { 0.0f }; float *a = b - 1; // numerical recipies so a[1] = b[0] unsigned long nh, nh1, i, j; if( n < 4 ) return; nh1 = ( nh = n >> 1 ) + 1; if( isign >= 0 ) { for( i = 1, j = 1; j <= n - 3; j += 2, i++ ) { wksp[ i ] = C0*a[ j ] + C1*a[ j + 1 ] + C2*a[ j + 2 ] + C3*a[ j + 3 ]; wksp[ i + nh ] = C3*a[ j ] - C2*a[ j + 1 ] + C1*a[ j + 2 ] - C0*a[ j + 3 ]; } wksp[ i ] = C0*a[ n - 1 ] + C1*a[ n ] + C2*a[ 1 ] + C3*a[ 2 ]; wksp[ i + nh ] = C3*a[ n - 1 ] - C2*a[ n ] + C1*a[ 1 ] - C0*a[ 2 ]; } else { wksp[ 1 ] = C2*a[ nh ] + C1*a[ n ] + C0*a[ 1 ] + C3*a[ nh1 ]; wksp[ 2 ] = C3*a[ nh ] - C0*a[ n ] + C1*a[ 1 ] - C2*a[ nh1 ]; for( i = 1, j = 3; i= 0 ) { for( nn = n; nn >= inverseStartLength; nn >>= 1 ) daub4( a, nn, isign ); } else { for( nn = inverseStartLength; nn <= n; nn <<= 1 ) daub4( a, nn, isign ); } } /* The number of bits required by each value */ static unsigned char numBits[] = { 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, 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, 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, 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, 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, 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, 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, 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, }; byte MuLawEncode( short s ) { unsigned long adjusted; byte sign, exponent, mantissa; sign = ( s<0 ) ? 0 : 0x80; if( s<0 ) s = -s; adjusted = ( long )s << ( 16 - sizeof( short ) * 8 ); adjusted += 128L + 4L; if( adjusted > 32767 ) adjusted = 32767; exponent = numBits[ ( adjusted >> 7 ) & 0xff ] - 1; mantissa = ( adjusted >> ( exponent + 3 ) ) & 0xf; return ~( sign | ( exponent << 4 ) | mantissa ); } short MuLawDecode( byte uLaw ) { signed long adjusted; byte exponent, mantissa; uLaw = ~uLaw; exponent = ( uLaw >> 4 ) & 0x7; mantissa = ( uLaw & 0xf ) + 16; adjusted = ( mantissa << ( exponent + 3 ) ) - 128 - 4; return ( uLaw & 0x80 ) ? adjusted : -adjusted; } short mulawToShort[ 256 ]; static qboolean madeTable = qfalse; static int NXStreamCount; void NXPutc( NXStream *stream, char out ) { stream[ NXStreamCount++ ] = out; } void encodeWavelet( sfx_t *sfx, short *packets ) { float wksp[ 4097 ] = { 0 }, temp; int i, samples, size; sndBuffer *newchunk, *chunk; byte *out; if( !madeTable ) { for( i = 0; i<256; i++ ) { mulawToShort[ i ] = ( float )MuLawDecode( ( byte )i ); } madeTable = qtrue; } chunk = NULL; samples = sfx->soundLength; while( samples>0 ) { size = samples; if( size>( SND_CHUNK_SIZE * 2 ) ) { size = ( SND_CHUNK_SIZE * 2 ); } if( size<4 ) { size = 4; } newchunk = SND_malloc(); if( sfx->soundData == NULL ) { sfx->soundData = newchunk; } else if( chunk != NULL ) { chunk->next = newchunk; } chunk = newchunk; for( i = 0; isndChunk; for( i = 0; i 32767 ) temp = 32767; else if( temp<-32768 ) temp = -32768; out[ i ] = MuLawEncode( ( short )temp ); } chunk->size = size; samples -= size; } } void decodeWavelet( sndBuffer *chunk, short *to ) { float wksp[ 4097 ] = { 0 }; int i; byte *out; int size = chunk->size; out = ( byte * )chunk->sndChunk; for( i = 0; isoundLength; grade = 0; while( samples>0 ) { size = samples; if( size>( SND_CHUNK_SIZE * 2 ) ) { size = ( SND_CHUNK_SIZE * 2 ); } newchunk = SND_malloc(); if( sfx->soundData == NULL ) { sfx->soundData = newchunk; } else if( chunk != NULL ) { chunk->next = newchunk; } chunk = newchunk; out = ( byte * )chunk->sndChunk; for( i = 0; i32767 ) { poop = 32767; } else if( poop<-32768 ) { poop = -32768; } out[ i ] = MuLawEncode( ( short )poop ); grade = poop - mulawToShort[ out[ i ] ]; packets++; } chunk->size = size; samples -= size; } } void decodeMuLaw( sndBuffer *chunk, short *to ) { int i; byte *out; int size = chunk->size; out = ( byte * )chunk->sndChunk; for( i = 0; i