00001 #include "funcprotos.h"
00002 #include "ima4.h"
00003 #include "quicktime.h"
00004
00005 typedef struct
00006 {
00007
00008
00009
00010 int16_t *work_buffer;
00011 unsigned char *read_buffer;
00012
00013
00014 int *last_samples, *last_indexes;
00015 long chunk;
00016 int buffer_channel;
00017
00018
00019
00020 long work_size;
00021 long work_overflow;
00022 long read_size;
00023 } quicktime_ima4_codec_t;
00024
00025 static int ima4_step[89] =
00026 {
00027 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
00028 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
00029 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
00030 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
00031 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
00032 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
00033 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
00034 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
00035 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
00036 };
00037
00038 static int ima4_index[16] =
00039 {
00040 -1, -1, -1, -1, 2, 4, 6, 8,
00041 -1, -1, -1, -1, 2, 4, 6, 8
00042 };
00043
00044
00045
00046 #define BLOCK_SIZE 0x22
00047 #define SAMPLES_PER_BLOCK 0x40
00048
00049
00050
00051
00052 void ima4_decode_sample(int *predictor, int *nibble, int *index, int *step)
00053 {
00054 int difference, sign;
00055
00056
00057 *index += ima4_index[*nibble];
00058
00059 if(*index < 0) *index = 0;
00060 else
00061 if(*index > 88) *index = 88;
00062
00063
00064 sign = *nibble & 8;
00065 *nibble = *nibble & 7;
00066
00067
00068 difference = *step >> 3;
00069 if(*nibble & 4) difference += *step;
00070 if(*nibble & 2) difference += *step >> 1;
00071 if(*nibble & 1) difference += *step >> 2;
00072
00073
00074 if(sign)
00075 *predictor -= difference;
00076 else
00077 *predictor += difference;
00078
00079 if(*predictor > 32767) *predictor = 32767;
00080 else
00081 if(*predictor < -32768) *predictor = -32768;
00082
00083
00084 *step = ima4_step[*index];
00085 }
00086
00087 void ima4_decode_block(quicktime_audio_map_t *atrack, int16_t *output, unsigned char *input)
00088 {
00089 int predictor;
00090 int index;
00091 int step;
00092 int i, nibble, nibble_count, block_size;
00093 unsigned char *block_ptr;
00094 unsigned char *input_end = input + BLOCK_SIZE;
00095 quicktime_ima4_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
00096
00097
00098 predictor = *input++ << 8;
00099 predictor |= *input++;
00100
00101 index = predictor & 0x7f;
00102 if(index > 88) index = 88;
00103
00104 predictor &= 0xff80;
00105 if(predictor & 0x8000) predictor -= 0x10000;
00106 step = ima4_step[index];
00107
00108
00109 nibble_count = 0;
00110 while(input < input_end)
00111 {
00112 nibble = nibble_count ? (*input++ >> 4) & 0x0f : *input & 0x0f;
00113
00114 ima4_decode_sample(&predictor, &nibble, &index, &step);
00115 *output++ = predictor;
00116
00117 nibble_count ^= 1;
00118 }
00119 }
00120
00121
00122 void ima4_encode_sample(int *last_sample, int *last_index, int *nibble, int next_sample)
00123 {
00124 int difference, new_difference, mask, step;
00125
00126 difference = next_sample - *last_sample;
00127 *nibble = 0;
00128 step = ima4_step[*last_index];
00129 new_difference = step >> 3;
00130
00131 if(difference < 0)
00132 {
00133 *nibble = 8;
00134 difference = -difference;
00135 }
00136
00137 mask = 4;
00138 while(mask)
00139 {
00140 if(difference >= step)
00141 {
00142 *nibble |= mask;
00143 difference -= step;
00144 new_difference += step;
00145 }
00146
00147 step >>= 1;
00148 mask >>= 1;
00149 }
00150
00151 if(*nibble & 8)
00152 *last_sample -= new_difference;
00153 else
00154 *last_sample += new_difference;
00155
00156 if(*last_sample > 32767) *last_sample = 32767;
00157 else
00158 if(*last_sample < -32767) *last_sample = -32767;
00159
00160 *last_index += ima4_index[*nibble];
00161
00162 if(*last_index < 0) *last_index = 0;
00163 else
00164 if(*last_index > 88) *last_index= 88;
00165 }
00166
00167 void ima4_encode_block(quicktime_audio_map_t *atrack, unsigned char *output, int16_t *input, int step, int channel)
00168 {
00169 quicktime_ima4_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
00170 int i, nibble_count = 0, nibble, header;
00171
00172
00173 header = codec->last_samples[channel];
00174
00175 if(header < 0x7fc0) header += 0x40;
00176 if(header < 0) header += 0x10000;
00177 header &= 0xff80;
00178 *output++ = (header & 0xff00) >> 8;
00179 *output++ = (header & 0x80) + (codec->last_indexes[channel] & 0x7f);
00180
00181 for(i = 0; i < SAMPLES_PER_BLOCK; i++)
00182 {
00183 ima4_encode_sample(&(codec->last_samples[channel]),
00184 &(codec->last_indexes[channel]),
00185 &nibble,
00186 *input);
00187
00188 if(nibble_count)
00189 *output++ |= (nibble << 4);
00190 else
00191 *output = nibble;
00192
00193 input += step;
00194 nibble_count ^= 1;
00195 }
00196 }
00197
00198
00199
00200 long ima4_samples_to_bytes(long samples, int channels)
00201 {
00202 long bytes = samples / SAMPLES_PER_BLOCK * BLOCK_SIZE * channels;
00203 return bytes;
00204 }
00205
00206
00207 int ima4_decode_chunk(quicktime_t *file, int track, long chunk, int channel)
00208 {
00209 int result = 0;
00210 int i, j;
00211 long chunk_samples, chunk_bytes;
00212 unsigned char *chunk_ptr, *block_ptr;
00213 quicktime_trak_t *trak = file->atracks[track].track;
00214 quicktime_ima4_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
00215
00216
00217 chunk_samples = quicktime_chunk_samples(trak, chunk);
00218 chunk_bytes = ima4_samples_to_bytes(chunk_samples, file->atracks[track].channels);
00219
00220
00221 if(codec->work_buffer && codec->work_size < chunk_samples)
00222 {
00223 free(codec->work_buffer);
00224 codec->work_buffer = 0;
00225 }
00226
00227 if(!codec->work_buffer)
00228 {
00229 codec->work_size = chunk_samples;
00230 codec->work_buffer = malloc(sizeof(int16_t) * codec->work_size);
00231 }
00232
00233 if(codec->read_buffer && codec->read_size < chunk_bytes)
00234 {
00235 free(codec->read_buffer);
00236 codec->read_buffer = 0;
00237 }
00238
00239 if(!codec->read_buffer)
00240 {
00241 codec->read_size = chunk_bytes;
00242 codec->read_buffer = malloc(codec->read_size);
00243 }
00244
00245
00246
00247
00248
00249 result = quicktime_read_chunk(file, codec->read_buffer, track, chunk, 0, chunk_bytes);
00250
00251
00252
00253
00254 if(!result)
00255 {
00256 block_ptr = codec->read_buffer;
00257 for(i = 0; i < chunk_samples; i += SAMPLES_PER_BLOCK)
00258 {
00259 for(j = 0; j < file->atracks[track].channels; j++)
00260 {
00261 if(j == channel)
00262 ima4_decode_block(&(file->atracks[track]), &(codec->work_buffer[i]), block_ptr);
00263
00264 block_ptr += BLOCK_SIZE;
00265 }
00266 }
00267 }
00268 codec->buffer_channel = channel;
00269 codec->chunk = chunk;
00270
00271 return result;
00272 }
00273
00274
00275
00276
00277 static int delete_codec(quicktime_audio_map_t *atrack)
00278 {
00279 quicktime_ima4_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
00280
00281 if(codec->work_buffer) free(codec->work_buffer);
00282 if(codec->read_buffer) free(codec->read_buffer);
00283 if(codec->last_samples) free(codec->last_samples);
00284 if(codec->last_indexes) free(codec->last_indexes);
00285 codec->last_samples = 0;
00286 codec->last_indexes = 0;
00287 codec->read_buffer = 0;
00288 codec->work_buffer = 0;
00289 codec->chunk = 0;
00290 codec->buffer_channel = 0;
00291 codec->work_size = 0;
00292 codec->read_size = 0;
00293 free(codec);
00294 return 0;
00295 }
00296
00297 static int decode(quicktime_t *file,
00298 int16_t *output_i,
00299 float *output_f,
00300 long samples,
00301 int track,
00302 int channel)
00303 {
00304 int result = 0;
00305 int64_t chunk, chunk_sample, chunk_bytes, chunk_samples;
00306 int64_t i, chunk_start, chunk_end;
00307 quicktime_trak_t *trak = file->atracks[track].track;
00308 quicktime_ima4_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
00309
00310
00311 quicktime_chunk_of_sample(&chunk_sample, &chunk, trak, file->atracks[track].current_position);
00312
00313
00314 for(i = 0; i < samples && !result; )
00315 {
00316
00317 chunk_samples = quicktime_chunk_samples(trak, chunk);
00318
00319 if(!codec->work_buffer ||
00320 codec->chunk != chunk ||
00321 codec->buffer_channel != channel)
00322 {
00323
00324 result = ima4_decode_chunk(file, track, chunk, channel);
00325 }
00326
00327
00328 chunk_start = 0;
00329 if(chunk_sample < file->atracks[track].current_position)
00330 chunk_start = file->atracks[track].current_position - chunk_sample;
00331
00332 chunk_end = chunk_samples;
00333 if(chunk_sample + chunk_end > file->atracks[track].current_position + samples)
00334 chunk_end = file->atracks[track].current_position + samples - chunk_sample;
00335
00336
00337 if(output_i)
00338 {
00339
00340 while(chunk_start < chunk_end)
00341 {
00342 output_i[i++] = codec->work_buffer[chunk_start++];
00343 }
00344
00345 }
00346 else
00347 if(output_f)
00348 {
00349 while(chunk_start < chunk_end)
00350 {
00351 output_f[i++] = (float)codec->work_buffer[chunk_start++] / 32767;
00352 }
00353 }
00354
00355 chunk++;
00356 chunk_sample += chunk_samples;
00357 }
00358
00359 return result;
00360 }
00361
00362 static int encode(quicktime_t *file,
00363 int16_t **input_i,
00364 float **input_f,
00365 int track,
00366 long samples)
00367 {
00368 int result = 0;
00369 int64_t i, j, step;
00370 int64_t chunk_bytes;
00371 int64_t overflow_start;
00372 int64_t offset;
00373 int64_t chunk_samples;
00374 quicktime_audio_map_t *track_map = &(file->atracks[track]);
00375 quicktime_ima4_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
00376 quicktime_trak_t *trak = track_map->track;
00377 int16_t *input_ptr;
00378 unsigned char *output_ptr;
00379 quicktime_atom_t chunk_atom;
00380
00381
00382 if(codec->work_buffer && codec->work_size < (samples + codec->work_overflow + 1) * track_map->channels)
00383 {
00384
00385 int64_t new_size = (samples + codec->work_overflow + 1) * track_map->channels;
00386 int16_t *new_buffer = malloc(sizeof(int16_t) * new_size);
00387
00388
00389 for(i = 0; i < codec->work_overflow * track_map->channels; i++)
00390 new_buffer[i] = codec->work_buffer[i];
00391
00392
00393 free(codec->work_buffer);
00394 codec->work_buffer = new_buffer;
00395 codec->work_size = new_size;
00396 }
00397 else
00398 if(!codec->work_buffer)
00399 {
00400
00401 codec->work_size = (samples + codec->work_overflow) * track_map->channels;
00402
00403 if(codec->work_size < SAMPLES_PER_BLOCK * track_map->channels)
00404 codec->work_size = SAMPLES_PER_BLOCK * track_map->channels;
00405 codec->work_buffer = malloc(sizeof(int16_t) * codec->work_size);
00406 }
00407
00408
00409 chunk_bytes = ima4_samples_to_bytes(samples + codec->work_overflow, track_map->channels);
00410 if(codec->read_buffer && codec->read_size < chunk_bytes)
00411 {
00412 free(codec->read_buffer);
00413 codec->read_buffer = 0;
00414 }
00415
00416 if(!codec->read_buffer)
00417 {
00418 codec->read_buffer = malloc(chunk_bytes);
00419 codec->read_size = chunk_bytes;
00420 }
00421
00422 if(!codec->last_samples)
00423 {
00424 codec->last_samples = malloc(sizeof(int) * track_map->channels);
00425 for(i = 0; i < track_map->channels; i++)
00426 {
00427 codec->last_samples[i] = 0;
00428 }
00429 }
00430
00431 if(!codec->last_indexes)
00432 {
00433 codec->last_indexes = malloc(sizeof(int) * track_map->channels);
00434 for(i = 0; i < track_map->channels; i++)
00435 {
00436 codec->last_indexes[i] = 0;
00437 }
00438 }
00439
00440
00441 step = track_map->channels;
00442 for(j = 0; j < track_map->channels; j++)
00443 {
00444 input_ptr = codec->work_buffer + codec->work_overflow * track_map->channels + j;
00445
00446 if(input_i)
00447 {
00448 for(i = 0; i < samples; i++)
00449 {
00450 *input_ptr = input_i[j][i];
00451 input_ptr += step;
00452 }
00453 }
00454 else
00455 if(input_f)
00456 {
00457 for(i = 0; i < samples; i++)
00458 {
00459 *input_ptr = (int16_t)(input_f[j][i] * 32767);
00460 input_ptr += step;
00461 }
00462 }
00463 }
00464
00465
00466
00467 input_ptr = codec->work_buffer;
00468 output_ptr = codec->read_buffer;
00469
00470 for(i = 0;
00471 i + SAMPLES_PER_BLOCK <= samples + codec->work_overflow;
00472 i += SAMPLES_PER_BLOCK)
00473 {
00474 for(j = 0; j < track_map->channels; j++)
00475 {
00476 ima4_encode_block(track_map, output_ptr, input_ptr + j, track_map->channels, j);
00477
00478 output_ptr += BLOCK_SIZE;
00479 }
00480 input_ptr += SAMPLES_PER_BLOCK * track_map->channels;
00481 }
00482
00483
00484 chunk_samples = (int64_t)((samples + codec->work_overflow) / SAMPLES_PER_BLOCK) * SAMPLES_PER_BLOCK;
00485
00486
00487
00488
00489 if(chunk_samples)
00490 {
00491 quicktime_write_chunk_header(file, trak, &chunk_atom);
00492 result = quicktime_write_data(file, codec->read_buffer, chunk_bytes);
00493 quicktime_write_chunk_footer(file,
00494 trak,
00495 track_map->current_chunk,
00496 &chunk_atom,
00497 chunk_samples);
00498
00499 if(result)
00500 result = 0;
00501 else
00502 result = 1;
00503
00504 track_map->current_chunk++;
00505 }
00506
00507
00508 overflow_start = i;
00509 input_ptr = codec->work_buffer;
00510 for(i = overflow_start * track_map->channels ;
00511 i < (samples + codec->work_overflow) * track_map->channels;
00512 i++)
00513 {
00514 *input_ptr++ = codec->work_buffer[i];
00515 }
00516 codec->work_overflow = samples + codec->work_overflow - overflow_start;
00517
00518 return result;
00519 }
00520
00521 void flush(quicktime_t *file, int track)
00522 {
00523 quicktime_audio_map_t *track_map = &(file->atracks[track]);
00524 quicktime_ima4_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
00525 int result = 0;
00526 int i;
00527
00528
00529 if(codec->work_overflow)
00530 {
00531
00532 i = codec->work_overflow * track_map->channels;
00533 while(i < SAMPLES_PER_BLOCK * track_map->channels)
00534 {
00535 codec->work_buffer[i++] = 0;
00536 }
00537 codec->work_overflow = i / track_map->channels + 1;
00538
00539 result = encode(file, 0, 0, track, 0);
00540 }
00541 }
00542
00543 void quicktime_init_codec_ima4(quicktime_audio_map_t *atrack)
00544 {
00545 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
00546 quicktime_ima4_codec_t *codec;
00547
00548
00549 codec_base->priv = calloc(1, sizeof(quicktime_ima4_codec_t));
00550 codec_base->delete_acodec = delete_codec;
00551 codec_base->decode_video = 0;
00552 codec_base->encode_video = 0;
00553 codec_base->decode_audio = decode;
00554 codec_base->encode_audio = encode;
00555 codec_base->flush = flush;
00556 codec_base->fourcc = QUICKTIME_IMA4;
00557 codec_base->title = "IMA 4";
00558 codec_base->desc = "IMA 4";
00559 codec_base->wav_id = 0x11;
00560
00561
00562 codec = codec_base->priv;
00563 }