1 /****************************************************************************
3 * ____ ___ ____ __ ______ ___ ____ ____/ / *
4 * / __ `__ \/ __ `/ |/ / __ `__ \/ __ \/ __ / *
5 * / / / / / / /_/ /> </ / / / / / /_/ / /_/ / *
6 * /_/ /_/ /_/\__,_/_/|_/_/ /_/ /_/\____/\__,_/ *
8 * Copyright (c) 2008, Mukunda Johnson (mukunda@maxmod.org) *
10 * Permission to use, copy, modify, and/or distribute this software for any *
11 * purpose with or without fee is hereby granted, provided that the above *
12 * copyright notice and this permission notice appear in all copies. *
14 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES *
15 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF *
16 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR *
17 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES *
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN *
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *
20 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *
21 ****************************************************************************/
23 // thanks GBATEK for the ima-adpcm specification
30 const s8 IndexTable[8] = {
31 -1, -1, -1, -1, 2, 4, 6, 8
34 const u16 AdpcmTable[89] = {
35 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
36 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
37 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
38 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
39 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
40 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
41 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
42 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
43 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
46 static int read_sample( Sample* sample, int position )
49 if( sample->format & SAMPF_16BIT )
51 s = ((s16*)sample->data)[position];
56 int a = ((s8*)sample->data)[position];
59 if( s < -32767 ) s = -32767; // is this necessary?...
63 static int minmax( int value, int low, int high )
65 if( value < low ) value = low;
66 if( value > high ) value = high;
70 static int calc_delta( int diff, int step )
72 int delta = (step >> 3); // t/8
74 if( diff >= step ) { // t/1
78 if( diff >= (step>>1) ) { // t/2
82 if( diff >= (step>>2) ) { // t/4
89 //----------------------------------------------------------------------
90 // Compresses a sample with IMA-ADPCM
91 // Make sure the data has proper alignment/length!
92 //----------------------------------------------------------------------
93 void adpcm_compress_sample( Sample* sample )
94 //----------------------------------------------------------------------
109 // allocate space for sample (compressed size)
110 output = (u8*)malloc( sample->sample_length/2+4 );
112 prev_value = read_sample( sample, 0 );
115 { // determine best (or close to best) initial table value
120 smallest_error = 9999999;
123 diff = read_sample( sample, 1 ) - read_sample( sample, 0 );
125 for( i = 0; i < 88; i++ )
127 tmp_error = calc_delta( diff, i ) - diff;
128 if( tmp_error < smallest_error )
130 smallest_error = tmp_error;
137 (*((u32*)output)) = prev_value // initial PCM16 value
138 | (index << 16); // initial table index value
140 step = AdpcmTable[index];
142 for( x = 0; x < sample->sample_length; x++ )
144 curr_value = read_sample( sample, x );
146 diff = curr_value - prev_value;
149 // negate difference & set negative bit
155 // clear negative flag
160 difference calculation:
161 Diff = AdpcmTable[Index]/8
162 IF (data4bit AND 1) THEN Diff = Diff + AdpcmTable[Index]/4
163 IF (data4bit AND 2) THEN Diff = Diff + AdpcmTable[Index]/2
164 IF (data4bit AND 4) THEN Diff = Diff + AdpcmTable[Index]/1
167 delta = (step >> 3); // t/8 (always)
169 if( diff >= step ) { // t/1
174 if( diff >= (step>>1) ) { // t/2
179 if( diff >= (step>>2) ) { // t/4
185 // add/subtract delta
186 prev_value += (data&8) ? -delta : delta;
189 prev_value = minmax( prev_value, -0x7FFF, 0x7FFF );
191 // add index table value (and clamp)
192 index = minmax( index + IndexTable[data & 7], 0, 88 );
194 // read new step value
195 step = AdpcmTable[index];
199 output[(x>>1)+4] |= (data) << 4;
201 output[(x>>1)+4] = (data);
205 free( sample->data );
208 sample->data = output;
211 sample->format = SAMP_FORMAT_ADPCM;
214 sample->sample_length = (sample->sample_length/2) +4;
215 sample->loop_start /= 2;
216 sample->loop_end /= 2;
218 // step loop past adpcm header
219 sample->loop_start += 4;
220 sample->loop_end += 4;