7 int FileBase::ima4_step[89] =
9 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
10 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
11 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
12 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
13 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
14 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
15 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
16 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
17 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
20 int FileBase::ima4_index[16] =
22 -1, -1, -1, -1, 2, 4, 6, 8,
23 -1, -1, -1, -1, 2, 4, 6, 8
28 int FileBase::init_ima4()
30 ima4_block_samples = 1024;
31 ima4_block_size = (ima4_block_samples - 1) * asset->channels / 2 + 4;
32 last_ima4_samples = 0;
33 last_ima4_indexes = 0;
36 int FileBase::delete_ima4()
38 if(last_ima4_samples) delete last_ima4_samples;
39 if(last_ima4_indexes) delete last_ima4_indexes;
40 last_ima4_samples = 0;
41 last_ima4_indexes = 0;
44 int FileBase::ima4_decode_block(int16_t *output, unsigned char *input)
47 // int predictor[asset->channels];
48 // int index[asset->channels];
49 // int step[asset->channels];
51 // unsigned char *block_ptr;
52 // unsigned char *input_end = input + ima4_block_size;
53 // int buffer_advance = asset->channels;
54 // int16_t *suboutput;
56 // // Get the chunk header
57 // for(int i = 0; i < asset->channels; i++)
59 // predictor[i] = *input++;
60 // predictor[i] |= (int)(*input++) << 8;
61 // index[i] = *input++;
62 // if(index[i] > 88) index[i] = 88;
63 // if(predictor[i] & 0x8000) predictor[i] -= 0x10000;
64 // step[i] = ima4_step[index[i]];
65 // *output++ = predictor[i];
69 // // Read the input buffer sequentially, one nibble at a time
70 // while(input < input_end)
72 // for(i = 0; i < asset->channels; i++)
74 // suboutput = output + i;
76 // for(j = 0; j < 4; j++)
78 // ima4_decode_sample(&predictor[i], *input & 0x0f, &index[i], &step[i]);
79 // *suboutput = predictor[i];
80 // suboutput += buffer_advance;
81 // ima4_decode_sample(&predictor[i], (*input++ >> 4) & 0x0f, &index[i], &step[i]);
82 // *suboutput = predictor[i];
83 // suboutput += buffer_advance;
87 // output += 8 * asset->channels;
91 int FileBase::ima4_decode_sample(int *predictor, int nibble, int *index, int *step)
95 // Get new index value
96 *index += ima4_index[nibble];
98 if(*index < 0) *index = 0;
100 if(*index > 88) *index = 88;
102 // Get sign and magnitude from nibble
107 difference = *step >> 3;
108 if(nibble & 4) difference += *step;
109 if(nibble & 2) difference += *step >> 1;
110 if(nibble & 1) difference += *step >> 2;
114 *predictor -= difference;
116 *predictor += difference;
118 if(*predictor > 32767) *predictor = 32767;
120 if(*predictor < -32768) *predictor = -32768;
122 // Update the step value
123 *step = ima4_step[*index];
129 int FileBase::ima4_encode_block(unsigned char *output, int16_t *input, int step, int channel)
132 int16_t *input_end = input + ima4_block_size;
134 int buffer_advance = asset->channels;
136 if(!last_ima4_samples)
138 last_ima4_samples = new int[asset->channels];
139 for(i = 0; i < asset->channels; i++) last_ima4_samples[i] = 0;
142 if(!last_ima4_indexes)
144 last_ima4_indexes = new int[asset->channels];
145 for(i = 0; i < asset->channels; i++) last_ima4_indexes[i] = 0;
148 for(i = 0; i < asset->channels; i++)
150 *output++ = last_ima4_samples[i] & 0xff;
151 *output++ = (last_ima4_samples[i] >> 8) & 0xff;
152 *output++ = last_ima4_indexes[i];
156 while(input < input_end)
158 for(i = 0; i < asset->channels; i++)
160 subinput = input + i;
161 for(j = 0; j < 4; j++)
163 ima4_encode_sample(&(last_ima4_samples[i]),
164 &(last_ima4_indexes[i]),
168 subinput += buffer_advance;
171 ima4_encode_sample(&(last_ima4_samples[i]),
172 &(last_ima4_indexes[i]),
176 subinput += buffer_advance;
177 *output++ |= (nibble << 4);
180 input += 8 * asset->channels;
186 int FileBase::ima4_encode_sample(int *last_sample, int *last_index, int *nibble, int next_sample)
188 int difference, new_difference, mask, step;
190 difference = next_sample - *last_sample;
192 step = ima4_step[*last_index];
193 new_difference = step >> 3;
198 difference = -difference;
204 if(difference >= step)
208 new_difference += step;
216 *last_sample -= new_difference;
218 *last_sample += new_difference;
220 if(*last_sample > 32767) *last_sample = 32767;
222 if(*last_sample < -32767) *last_sample = -32767;
224 *last_index += ima4_index[*nibble];
226 if(*last_index < 0) *last_index = 0;
228 if(*last_index > 88) *last_index= 88;
233 // Convert the number of samples in a chunk into the number of bytes in that
234 // chunk. The number of samples in a chunk should end on a block boundary.
235 int64_t FileBase::ima4_samples_to_bytes(int64_t samples, int channels)
237 int64_t bytes = (int64_t)(samples / ima4_block_samples) * ima4_block_size * channels;
241 int64_t FileBase::ima4_bytes_to_samples(int64_t bytes, int channels)
243 int64_t samples = (int64_t)(bytes / channels / ima4_block_size) * ima4_block_samples;