4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "byteorder.h"
28 int FileBase::ima4_step[89] =
30 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
31 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
32 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
33 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
34 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
35 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
36 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
37 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
38 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
41 int FileBase::ima4_index[16] =
43 -1, -1, -1, -1, 2, 4, 6, 8,
44 -1, -1, -1, -1, 2, 4, 6, 8
49 int FileBase::init_ima4()
51 ima4_block_samples = 1024;
52 ima4_block_size = (ima4_block_samples - 1) * asset->channels / 2 + 4;
53 last_ima4_samples = 0;
54 last_ima4_indexes = 0;
58 int FileBase::delete_ima4()
60 if(last_ima4_samples) delete last_ima4_samples;
61 if(last_ima4_indexes) delete last_ima4_indexes;
62 last_ima4_samples = 0;
63 last_ima4_indexes = 0;
67 int FileBase::ima4_decode_block(int16_t *output, unsigned char *input)
70 // int predictor[asset->channels];
71 // int index[asset->channels];
72 // int step[asset->channels];
74 // unsigned char *block_ptr;
75 // unsigned char *input_end = input + ima4_block_size;
76 // int buffer_advance = asset->channels;
77 // int16_t *suboutput;
79 // // Get the chunk header
80 // for(int i = 0; i < asset->channels; i++)
82 // predictor[i] = *input++;
83 // predictor[i] |= (int)(*input++) << 8;
84 // index[i] = *input++;
85 // if(index[i] > 88) index[i] = 88;
86 // if(predictor[i] & 0x8000) predictor[i] -= 0x10000;
87 // step[i] = ima4_step[index[i]];
88 // *output++ = predictor[i];
92 // // Read the input buffer sequentially, one nibble at a time
93 // while(input < input_end)
95 // for(i = 0; i < asset->channels; i++)
97 // suboutput = output + i;
99 // for(j = 0; j < 4; j++)
101 // ima4_decode_sample(&predictor[i], *input & 0x0f, &index[i], &step[i]);
102 // *suboutput = predictor[i];
103 // suboutput += buffer_advance;
104 // ima4_decode_sample(&predictor[i], (*input++ >> 4) & 0x0f, &index[i], &step[i]);
105 // *suboutput = predictor[i];
106 // suboutput += buffer_advance;
110 // output += 8 * asset->channels;
114 int FileBase::ima4_decode_sample(int *predictor, int nibble, int *index, int *step)
116 int difference, sign;
118 // Get new index value
119 *index += ima4_index[nibble];
121 if(*index < 0) *index = 0;
123 if(*index > 88) *index = 88;
125 // Get sign and magnitude from nibble
130 difference = *step >> 3;
131 if(nibble & 4) difference += *step;
132 if(nibble & 2) difference += *step >> 1;
133 if(nibble & 1) difference += *step >> 2;
137 *predictor -= difference;
139 *predictor += difference;
141 if(*predictor > 32767) *predictor = 32767;
143 if(*predictor < -32768) *predictor = -32768;
145 // Update the step value
146 *step = ima4_step[*index];
152 int FileBase::ima4_encode_block(unsigned char *output, int16_t *input, int step, int channel)
155 int16_t *input_end = input + ima4_block_size;
157 int buffer_advance = asset->channels;
159 if(!last_ima4_samples)
161 last_ima4_samples = new int[asset->channels];
162 for(i = 0; i < asset->channels; i++) last_ima4_samples[i] = 0;
165 if(!last_ima4_indexes)
167 last_ima4_indexes = new int[asset->channels];
168 for(i = 0; i < asset->channels; i++) last_ima4_indexes[i] = 0;
171 for(i = 0; i < asset->channels; i++)
173 *output++ = last_ima4_samples[i] & 0xff;
174 *output++ = (last_ima4_samples[i] >> 8) & 0xff;
175 *output++ = last_ima4_indexes[i];
179 while(input < input_end)
181 for(i = 0; i < asset->channels; i++)
183 subinput = input + i;
184 for(j = 0; j < 4; j++)
186 ima4_encode_sample(&(last_ima4_samples[i]),
187 &(last_ima4_indexes[i]),
191 subinput += buffer_advance;
194 ima4_encode_sample(&(last_ima4_samples[i]),
195 &(last_ima4_indexes[i]),
199 subinput += buffer_advance;
200 *output++ |= (nibble << 4);
203 input += 8 * asset->channels;
209 int FileBase::ima4_encode_sample(int *last_sample, int *last_index, int *nibble, int next_sample)
211 int difference, new_difference, mask, step;
213 difference = next_sample - *last_sample;
215 step = ima4_step[*last_index];
216 new_difference = step >> 3;
221 difference = -difference;
227 if(difference >= step)
231 new_difference += step;
239 *last_sample -= new_difference;
241 *last_sample += new_difference;
243 if(*last_sample > 32767) *last_sample = 32767;
245 if(*last_sample < -32767) *last_sample = -32767;
247 *last_index += ima4_index[*nibble];
249 if(*last_index < 0) *last_index = 0;
251 if(*last_index > 88) *last_index= 88;
256 // Convert the number of samples in a chunk into the number of bytes in that
257 // chunk. The number of samples in a chunk should end on a block boundary.
258 int64_t FileBase::ima4_samples_to_bytes(int64_t samples, int channels)
260 int64_t bytes = (int64_t)(samples / ima4_block_samples) * ima4_block_size * channels;
264 int64_t FileBase::ima4_bytes_to_samples(int64_t bytes, int channels)
266 int64_t samples = (int64_t)(bytes / channels / ima4_block_size) * ima4_block_samples;