1 #include "funcprotos.h"
7 /* During decoding the work_buffer contains the most recently read chunk. */
8 /* During encoding the work_buffer contains interlaced overflow samples */
9 /* from the last chunk written. */
11 unsigned char *read_buffer
; /* Temporary buffer for drive reads. */
13 /* Starting information for all channels during encoding. */
14 int *last_samples
, *last_indexes
;
15 long chunk
; /* Number of chunk in work buffer */
16 int buffer_channel
; /* Channel of work buffer */
18 /* Number of samples in largest chunk read. */
19 /* Number of samples plus overflow in largest chunk write, interlaced. */
21 long work_overflow
; /* Number of overflow samples from the last chunk written. */
22 long read_size
; /* Size of read buffer. */
23 } quicktime_ima4_codec_t
;
25 static int ima4_step
[89] =
27 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
28 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
29 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
30 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
31 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
32 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
33 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
34 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
35 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
38 static int ima4_index
[16] =
40 -1, -1, -1, -1, 2, 4, 6, 8,
41 -1, -1, -1, -1, 2, 4, 6, 8
44 /* Known by divine revelation */
46 #define BLOCK_SIZE 0x22
47 #define SAMPLES_PER_BLOCK 0x40
49 /* ================================== private for ima4 */
52 void ima4_decode_sample(int *predictor
, int *nibble
, int *index
, int *step
)
56 /* Get new index value */
57 *index
+= ima4_index
[*nibble
];
59 if(*index
< 0) *index
= 0;
61 if(*index
> 88) *index
= 88;
63 /* Get sign and magnitude from *nibble */
65 *nibble
= *nibble
& 7;
68 difference
= *step
>> 3;
69 if(*nibble
& 4) difference
+= *step
;
70 if(*nibble
& 2) difference
+= *step
>> 1;
71 if(*nibble
& 1) difference
+= *step
>> 2;
75 *predictor
-= difference
;
77 *predictor
+= difference
;
79 if(*predictor
> 32767) *predictor
= 32767;
81 if(*predictor
< -32768) *predictor
= -32768;
83 /* Update the step value */
84 *step
= ima4_step
[*index
];
87 void ima4_decode_block(quicktime_audio_map_t
*atrack
, int16_t *output
, unsigned char *input
)
92 int i
, nibble
, nibble_count
, block_size
;
93 unsigned char *block_ptr
;
94 unsigned char *input_end
= input
+ BLOCK_SIZE
;
95 quicktime_ima4_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
97 /* Get the chunk header */
98 predictor
= *input
++ << 8;
99 predictor
|= *input
++;
101 index
= predictor
& 0x7f;
102 if(index
> 88) index
= 88;
105 if(predictor
& 0x8000) predictor
-= 0x10000;
106 step
= ima4_step
[index
];
108 /* Read the input buffer sequentially, one nibble at a time */
110 while(input
< input_end
)
112 nibble
= nibble_count
? (*input
++ >> 4) & 0x0f : *input
& 0x0f;
114 ima4_decode_sample(&predictor
, &nibble
, &index
, &step
);
115 *output
++ = predictor
;
122 void ima4_encode_sample(int *last_sample
, int *last_index
, int *nibble
, int next_sample
)
124 int difference
, new_difference
, mask
, step
;
126 difference
= next_sample
- *last_sample
;
128 step
= ima4_step
[*last_index
];
129 new_difference
= step
>> 3;
134 difference
= -difference
;
140 if(difference
>= step
)
144 new_difference
+= step
;
152 *last_sample
-= new_difference
;
154 *last_sample
+= new_difference
;
156 if(*last_sample
> 32767) *last_sample
= 32767;
158 if(*last_sample
< -32767) *last_sample
= -32767;
160 *last_index
+= ima4_index
[*nibble
];
162 if(*last_index
< 0) *last_index
= 0;
164 if(*last_index
> 88) *last_index
= 88;
167 void ima4_encode_block(quicktime_audio_map_t
*atrack
, unsigned char *output
, int16_t *input
, int step
, int channel
)
169 quicktime_ima4_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
170 int i
, nibble_count
= 0, nibble
, header
;
172 /* Get a fake starting sample */
173 header
= codec
->last_samples
[channel
];
174 /* Force rounding. */
175 if(header
< 0x7fc0) header
+= 0x40;
176 if(header
< 0) header
+= 0x10000;
178 *output
++ = (header
& 0xff00) >> 8;
179 *output
++ = (header
& 0x80) + (codec
->last_indexes
[channel
] & 0x7f);
181 for(i
= 0; i
< SAMPLES_PER_BLOCK
; i
++)
183 ima4_encode_sample(&(codec
->last_samples
[channel
]),
184 &(codec
->last_indexes
[channel
]),
189 *output
++ |= (nibble
<< 4);
198 /* Convert the number of samples in a chunk into the number of bytes in that */
199 /* chunk. The number of samples in a chunk should end on a block boundary. */
200 long ima4_samples_to_bytes(long samples
, int channels
)
202 long bytes
= samples
/ SAMPLES_PER_BLOCK
* BLOCK_SIZE
* channels
;
206 /* Decode the chunk into the work buffer */
207 int ima4_decode_chunk(quicktime_t
*file
, int track
, long chunk
, int channel
)
211 long chunk_samples
, chunk_bytes
;
212 unsigned char *chunk_ptr
, *block_ptr
;
213 quicktime_trak_t
*trak
= file
->atracks
[track
].track
;
214 quicktime_ima4_codec_t
*codec
= ((quicktime_codec_t
*)file
->atracks
[track
].codec
)->priv
;
216 /* Get the byte count to read. */
217 chunk_samples
= quicktime_chunk_samples(trak
, chunk
);
218 chunk_bytes
= ima4_samples_to_bytes(chunk_samples
, file
->atracks
[track
].channels
);
220 /* Get the buffer to read into. */
221 if(codec
->work_buffer
&& codec
->work_size
< chunk_samples
)
223 free(codec
->work_buffer
);
224 codec
->work_buffer
= 0;
227 if(!codec
->work_buffer
)
229 codec
->work_size
= chunk_samples
;
230 codec
->work_buffer
= malloc(sizeof(int16_t) * codec
->work_size
);
233 if(codec
->read_buffer
&& codec
->read_size
< chunk_bytes
)
235 free(codec
->read_buffer
);
236 codec
->read_buffer
= 0;
239 if(!codec
->read_buffer
)
241 codec
->read_size
= chunk_bytes
;
242 codec
->read_buffer
= malloc(codec
->read_size
);
245 /* codec->work_size now holds the number of samples in the last chunk */
246 /* codec->read_size now holds number of bytes in the last read buffer */
248 /* Read the entire chunk regardless of where the desired sample range starts. */
249 result
= quicktime_read_chunk(file
, codec
->read_buffer
, track
, chunk
, 0, chunk_bytes
);
251 /* Now decode the chunk, one block at a time, until the total samples in the chunk */
256 block_ptr
= codec
->read_buffer
;
257 for(i
= 0; i
< chunk_samples
; i
+= SAMPLES_PER_BLOCK
)
259 for(j
= 0; j
< file
->atracks
[track
].channels
; j
++)
262 ima4_decode_block(&(file
->atracks
[track
]), &(codec
->work_buffer
[i
]), block_ptr
);
264 block_ptr
+= BLOCK_SIZE
;
268 codec
->buffer_channel
= channel
;
269 codec
->chunk
= chunk
;
275 /* =================================== public for ima4 */
277 static int delete_codec(quicktime_audio_map_t
*atrack
)
279 quicktime_ima4_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
281 if(codec
->work_buffer
) free(codec
->work_buffer
);
282 if(codec
->read_buffer
) free(codec
->read_buffer
);
283 if(codec
->last_samples
) free(codec
->last_samples
);
284 if(codec
->last_indexes
) free(codec
->last_indexes
);
285 codec
->last_samples
= 0;
286 codec
->last_indexes
= 0;
287 codec
->read_buffer
= 0;
288 codec
->work_buffer
= 0;
290 codec
->buffer_channel
= 0; /* Channel of work buffer */
291 codec
->work_size
= 0; /* Size of work buffer */
292 codec
->read_size
= 0;
297 static int decode(quicktime_t
*file
,
305 int64_t chunk
, chunk_sample
, chunk_bytes
, chunk_samples
;
306 int64_t i
, chunk_start
, chunk_end
;
307 quicktime_trak_t
*trak
= file
->atracks
[track
].track
;
308 quicktime_ima4_codec_t
*codec
= ((quicktime_codec_t
*)file
->atracks
[track
].codec
)->priv
;
310 /* Get the first chunk with this routine and then increase the chunk number. */
311 quicktime_chunk_of_sample(&chunk_sample
, &chunk
, trak
, file
->atracks
[track
].current_position
);
313 /* Read chunks and extract ranges of samples until the output is full. */
314 for(i
= 0; i
< samples
&& !result
; )
316 /* Get chunk we're on. */
317 chunk_samples
= quicktime_chunk_samples(trak
, chunk
);
319 if(!codec
->work_buffer
||
320 codec
->chunk
!= chunk
||
321 codec
->buffer_channel
!= channel
)
323 /* read a new chunk if necessary */
324 result
= ima4_decode_chunk(file
, track
, chunk
, channel
);
327 /* Get boundaries from the chunk */
329 if(chunk_sample
< file
->atracks
[track
].current_position
)
330 chunk_start
= file
->atracks
[track
].current_position
- chunk_sample
;
332 chunk_end
= chunk_samples
;
333 if(chunk_sample
+ chunk_end
> file
->atracks
[track
].current_position
+ samples
)
334 chunk_end
= file
->atracks
[track
].current_position
+ samples
- chunk_sample
;
336 /* Read from the chunk */
339 /*printf("decode_ima4 1 chunk %ld %ld-%ld output %ld\n", chunk, chunk_start + chunk_sample, chunk_end + chunk_sample, i); */
340 while(chunk_start
< chunk_end
)
342 output_i
[i
++] = codec
->work_buffer
[chunk_start
++];
344 /*printf("decode_ima4 2\n"); */
349 while(chunk_start
< chunk_end
)
351 output_f
[i
++] = (float)codec
->work_buffer
[chunk_start
++] / 32767;
356 chunk_sample
+= chunk_samples
;
362 static int encode(quicktime_t
*file
,
371 int64_t overflow_start
;
373 int64_t chunk_samples
; /* Samples in the current chunk to be written */
374 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
375 quicktime_ima4_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
376 quicktime_trak_t
*trak
= track_map
->track
;
378 unsigned char *output_ptr
;
379 quicktime_atom_t chunk_atom
;
381 /* Get buffer sizes */
382 if(codec
->work_buffer
&& codec
->work_size
< (samples
+ codec
->work_overflow
+ 1) * track_map
->channels
)
384 /* Create new buffer */
385 int64_t new_size
= (samples
+ codec
->work_overflow
+ 1) * track_map
->channels
;
386 int16_t *new_buffer
= malloc(sizeof(int16_t) * new_size
);
389 for(i
= 0; i
< codec
->work_overflow
* track_map
->channels
; i
++)
390 new_buffer
[i
] = codec
->work_buffer
[i
];
393 free(codec
->work_buffer
);
394 codec
->work_buffer
= new_buffer
;
395 codec
->work_size
= new_size
;
398 if(!codec
->work_buffer
)
400 /* No buffer in the first place. */
401 codec
->work_size
= (samples
+ codec
->work_overflow
) * track_map
->channels
;
402 /* Make the allocation enough for at least the flush routine. */
403 if(codec
->work_size
< SAMPLES_PER_BLOCK
* track_map
->channels
)
404 codec
->work_size
= SAMPLES_PER_BLOCK
* track_map
->channels
;
405 codec
->work_buffer
= malloc(sizeof(int16_t) * codec
->work_size
);
408 /* Get output size */
409 chunk_bytes
= ima4_samples_to_bytes(samples
+ codec
->work_overflow
, track_map
->channels
);
410 if(codec
->read_buffer
&& codec
->read_size
< chunk_bytes
)
412 free(codec
->read_buffer
);
413 codec
->read_buffer
= 0;
416 if(!codec
->read_buffer
)
418 codec
->read_buffer
= malloc(chunk_bytes
);
419 codec
->read_size
= chunk_bytes
;
422 if(!codec
->last_samples
)
424 codec
->last_samples
= malloc(sizeof(int) * track_map
->channels
);
425 for(i
= 0; i
< track_map
->channels
; i
++)
427 codec
->last_samples
[i
] = 0;
431 if(!codec
->last_indexes
)
433 codec
->last_indexes
= malloc(sizeof(int) * track_map
->channels
);
434 for(i
= 0; i
< track_map
->channels
; i
++)
436 codec
->last_indexes
[i
] = 0;
440 /* Arm the input buffer after the last overflow */
441 step
= track_map
->channels
;
442 for(j
= 0; j
< track_map
->channels
; j
++)
444 input_ptr
= codec
->work_buffer
+ codec
->work_overflow
* track_map
->channels
+ j
;
448 for(i
= 0; i
< samples
; i
++)
450 *input_ptr
= input_i
[j
][i
];
457 for(i
= 0; i
< samples
; i
++)
459 *input_ptr
= (int16_t)(input_f
[j
][i
] * 32767);
465 /* Encode from the input buffer to the read_buffer up to a multiple of */
467 input_ptr
= codec
->work_buffer
;
468 output_ptr
= codec
->read_buffer
;
471 i
+ SAMPLES_PER_BLOCK
<= samples
+ codec
->work_overflow
;
472 i
+= SAMPLES_PER_BLOCK
)
474 for(j
= 0; j
< track_map
->channels
; j
++)
476 ima4_encode_block(track_map
, output_ptr
, input_ptr
+ j
, track_map
->channels
, j
);
478 output_ptr
+= BLOCK_SIZE
;
480 input_ptr
+= SAMPLES_PER_BLOCK
* track_map
->channels
;
484 chunk_samples
= (int64_t)((samples
+ codec
->work_overflow
) / SAMPLES_PER_BLOCK
) * SAMPLES_PER_BLOCK
;
486 /*printf("quicktime_encode_ima4 1 %ld\n", chunk_samples); */
487 /* The block division may result in 0 samples getting encoded. */
488 /* Don't write 0 samples. */
491 quicktime_write_chunk_header(file
, trak
, &chunk_atom
);
492 result
= quicktime_write_data(file
, codec
->read_buffer
, chunk_bytes
);
493 quicktime_write_chunk_footer(file
,
495 track_map
->current_chunk
,
502 result
= 1; /* defeat fwrite's return */
504 track_map
->current_chunk
++;
507 /* Move the last overflow to the front */
509 input_ptr
= codec
->work_buffer
;
510 for(i
= overflow_start
* track_map
->channels
;
511 i
< (samples
+ codec
->work_overflow
) * track_map
->channels
;
514 *input_ptr
++ = codec
->work_buffer
[i
];
516 codec
->work_overflow
= samples
+ codec
->work_overflow
- overflow_start
;
521 void flush(quicktime_t
*file
, int track
)
523 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
524 quicktime_ima4_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
528 /*printf("quicktime_flush_ima4 %ld\n", codec->work_overflow); */
529 if(codec
->work_overflow
)
531 /* Zero out enough to get a block */
532 i
= codec
->work_overflow
* track_map
->channels
;
533 while(i
< SAMPLES_PER_BLOCK
* track_map
->channels
)
535 codec
->work_buffer
[i
++] = 0;
537 codec
->work_overflow
= i
/ track_map
->channels
+ 1;
538 /* Write the work_overflow only. */
539 result
= encode(file
, 0, 0, track
, 0);
543 void quicktime_init_codec_ima4(quicktime_audio_map_t
*atrack
)
545 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
546 quicktime_ima4_codec_t
*codec
;
548 /* Init public items */
549 codec_base
->priv
= calloc(1, sizeof(quicktime_ima4_codec_t
));
550 codec_base
->delete_acodec
= delete_codec
;
551 codec_base
->decode_video
= 0;
552 codec_base
->encode_video
= 0;
553 codec_base
->decode_audio
= decode
;
554 codec_base
->encode_audio
= encode
;
555 codec_base
->flush
= flush
;
556 codec_base
->fourcc
= QUICKTIME_IMA4
;
557 codec_base
->title
= "IMA 4";
558 codec_base
->desc
= "IMA 4";
559 codec_base
->wav_id
= 0x11;
561 /* Init private items */
562 codec
= codec_base
->priv
;