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. */
10 int16_t *write_buffer
;
11 unsigned char *read_buffer
; /* Temporary buffer for drive reads. */
13 /* Starting information for all channels during encoding a chunk. */
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. */
20 long write_size
; /* Size of write buffer. */
21 long read_size
; /* Size of read buffer. */
22 } quicktime_wmx2_codec_t
;
24 static int quicktime_wmx2_step
[89] =
26 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
27 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
28 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
29 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
30 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
31 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
32 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
33 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
34 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
37 static int quicktime_wmx2_index
[16] =
39 -1, -1, -1, -1, 2, 4, 6, 8,
40 -1, -1, -1, -1, 2, 4, 6, 8
43 /* ================================== private for wmx2 */
46 static int wmx2_decode_sample(int *predictor
, int *nibble
, int *index
, int *step
)
50 /* Get new index value */
51 *index
+= quicktime_wmx2_index
[*nibble
];
53 if(*index
< 0) *index
= 0;
55 if(*index
> 88) *index
= 88;
57 /* Get sign and magnitude from *nibble */
59 *nibble
= *nibble
& 7;
62 difference
= *step
>> 3;
63 if(*nibble
& 4) difference
+= *step
;
64 if(*nibble
& 2) difference
+= *step
>> 1;
65 if(*nibble
& 1) difference
+= *step
>> 2;
69 *predictor
-= difference
;
71 *predictor
+= difference
;
73 if(*predictor
> 32767) *predictor
= 32767;
75 if(*predictor
< -32768) *predictor
= -32768;
77 /* Update the step value */
78 *step
= quicktime_wmx2_step
[*index
];
84 static int wmx2_decode_block(quicktime_audio_map_t
*atrack
, int16_t *output
, unsigned char *input
, int samples
)
89 int i
, nibble
, nibble_count
, block_size
;
90 unsigned char *block_ptr
;
91 int16_t *output_end
= output
+ samples
;
92 quicktime_wmx2_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
94 /* Get the chunk header */
95 predictor
= *input
++ << 8;
96 predictor
|= *input
++;
97 if(predictor
& 0x8000) predictor
-= 0x10000;
99 if(index
> 88) index
= 88;
101 /*printf("input %d %d\n", predictor, index); */
102 step
= quicktime_wmx2_step
[index
];
104 /* Read the input buffer sequentially, one nibble at a time */
106 while(output
< output_end
)
108 nibble
= nibble_count
? (*input
++ >> 4) & 0x0f : *input
& 0x0f;
110 wmx2_decode_sample(&predictor
, &nibble
, &index
, &step
);
111 *output
++ = predictor
;
117 static int wmx2_encode_sample(int *last_sample
, int *last_index
, int *nibble
, int next_sample
)
119 int difference
, new_difference
, mask
, step
;
121 difference
= next_sample
- *last_sample
;
123 step
= quicktime_wmx2_step
[*last_index
];
124 new_difference
= step
>> 3;
129 difference
= -difference
;
135 if(difference
>= step
)
139 new_difference
+= step
;
147 *last_sample
-= new_difference
;
149 *last_sample
+= new_difference
;
151 if(*last_sample
> 32767) *last_sample
= 32767;
153 if(*last_sample
< -32767) *last_sample
= -32767;
155 *last_index
+= quicktime_wmx2_index
[*nibble
];
157 if(*last_index
< 0) *last_index
= 0;
159 if(*last_index
> 88) *last_index
= 88;
164 static int wmx2_encode_block(quicktime_audio_map_t
*atrack
, unsigned char *output
, int16_t *input
, int step
, int channel
, int samples
)
166 quicktime_wmx2_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
167 int i
, nibble_count
= 0, nibble
, header
;
169 /* Get a fake starting sample */
170 header
= codec
->last_samples
[channel
];
171 /*printf("output %d %d\n", header, codec->last_indexes[channel]); */
172 /* Force rounding. */
173 /* if(header < 0x7fc0) header += 0x40; */
174 /* header &= 0xff80; */
175 if(header
< 0) header
+= 0x10000;
176 *output
++ = (header
& 0xff00) >> 8;
177 *output
++ = (header
& 0xff);
178 *output
++ = (codec
->last_indexes
[channel
] & 0x7f);
180 for(i
= 0; i
< samples
; i
++)
182 wmx2_encode_sample(&(codec
->last_samples
[channel
]),
183 &(codec
->last_indexes
[channel
]),
188 *output
++ |= (nibble
<< 4);
199 /* Convert the number of samples in a chunk into the number of bytes in that */
200 /* chunk. The number of samples in a chunk should end on a block boundary. */
201 static long wmx2_samples_to_bytes(long samples
, int channels
)
203 long bytes
= samples
/ 2;
204 if(bytes
* 2 < samples
) bytes
++;
206 bytes
+= HEADER_SIZE
* channels
;
210 /* Decode the chunk into the work buffer */
211 static int wmx2_decode_chunk(quicktime_t
*file
, int track
, long chunk
, int channel
)
215 long chunk_samples
, chunk_bytes
;
216 unsigned char *chunk_ptr
, *block_ptr
;
217 quicktime_trak_t
*trak
= file
->atracks
[track
].track
;
218 quicktime_wmx2_codec_t
*codec
=
219 ((quicktime_codec_t
*)file
->atracks
[track
].codec
)->priv
;
221 /* Get the byte count to read. */
222 chunk_samples
= quicktime_chunk_samples(trak
, chunk
);
223 chunk_bytes
= wmx2_samples_to_bytes(chunk_samples
, file
->atracks
[track
].channels
);
225 /* Get the buffer to read into. */
226 if(codec
->write_buffer
&& codec
->write_size
< chunk_samples
)
228 free(codec
->write_buffer
);
229 codec
->write_buffer
= 0;
232 if(!codec
->write_buffer
)
234 codec
->write_size
= chunk_samples
;
235 codec
->write_buffer
= malloc(sizeof(int16_t) * codec
->write_size
);
238 if(codec
->read_buffer
&& codec
->read_size
< chunk_bytes
)
240 free(codec
->read_buffer
);
241 codec
->read_buffer
= 0;
244 if(!codec
->read_buffer
)
246 codec
->read_size
= chunk_bytes
;
247 codec
->read_buffer
= malloc(codec
->read_size
);
250 /* codec->work_size now holds the number of samples in the last chunk */
251 /* codec->read_size now holds number of bytes in the last read buffer */
253 /* Read the entire chunk regardless of where the desired sample range starts. */
254 result
= quicktime_read_chunk(file
, codec
->read_buffer
, track
, chunk
, 0, chunk_bytes
);
256 /* Now decode the chunk, one block at a time, until the total samples in the chunk */
261 block_ptr
= codec
->read_buffer
;
262 for(j
= 0; j
< file
->atracks
[track
].channels
; j
++)
265 wmx2_decode_block(&(file
->atracks
[track
]), codec
->write_buffer
, block_ptr
, chunk_samples
);
267 block_ptr
+= chunk_bytes
/ file
->atracks
[track
].channels
;
270 codec
->buffer_channel
= channel
;
271 codec
->chunk
= chunk
;
277 /* =================================== public for wmx2 */
279 static int decode(quicktime_t
*file
,
287 long chunk
, chunk_sample
, chunk_bytes
, chunk_samples
;
288 long i
, chunk_start
, chunk_end
;
289 quicktime_trak_t
*trak
= file
->atracks
[track
].track
;
290 quicktime_wmx2_codec_t
*codec
=
291 ((quicktime_codec_t
*)file
->atracks
[track
].codec
)->priv
;
293 /* Get the first chunk with this routine and then increase the chunk number. */
294 quicktime_chunk_of_sample(&chunk_sample
, &chunk
, trak
, file
->atracks
[track
].current_position
);
296 /* Read chunks until the output is full. */
297 for(i
= 0; i
< samples
&& !result
; )
299 /* Get chunk we're on. */
300 chunk_samples
= quicktime_chunk_samples(trak
, chunk
);
302 if(!codec
->write_buffer
||
303 codec
->chunk
!= chunk
||
304 codec
->buffer_channel
!= channel
)
306 /* read a new chunk if necessary */
307 result
= wmx2_decode_chunk(file
, track
, chunk
, channel
);
310 /* Get boundaries from the chunk */
312 if(chunk_sample
< file
->atracks
[track
].current_position
)
313 chunk_start
= file
->atracks
[track
].current_position
- chunk_sample
;
315 chunk_end
= chunk_samples
;
316 if(chunk_sample
+ chunk_end
> file
->atracks
[track
].current_position
+ samples
)
317 chunk_end
= file
->atracks
[track
].current_position
+ samples
- chunk_sample
;
319 /* Read from the chunk */
322 while(chunk_start
< chunk_end
)
324 output_i
[i
++] = codec
->write_buffer
[chunk_start
++];
330 while(chunk_start
< chunk_end
)
332 output_f
[i
++] = (float)codec
->write_buffer
[chunk_start
++] / 32767;
337 chunk_sample
+= chunk_samples
;
343 static int encode(quicktime_t
*file
,
353 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
354 quicktime_wmx2_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
355 quicktime_trak_t
*trak
= track_map
->track
;
357 unsigned char *output_ptr
;
358 quicktime_atom_t chunk_atom
;
360 /* Get buffer sizes */
361 if(codec
->write_buffer
&& codec
->write_size
< samples
* track_map
->channels
)
363 /* Create new buffer */
364 long new_size
= samples
* track_map
->channels
;
365 int16_t *new_buffer
= malloc(sizeof(int16_t) * new_size
);
368 free(codec
->write_buffer
);
369 codec
->write_buffer
= new_buffer
;
370 codec
->write_size
= new_size
;
373 if(!codec
->write_buffer
)
375 /* No buffer in the first place. */
376 codec
->write_size
= samples
* track_map
->channels
;
377 codec
->write_buffer
= malloc(sizeof(int16_t) * codec
->write_size
);
380 /* Get output size */
381 chunk_bytes
= wmx2_samples_to_bytes(samples
, track_map
->channels
);
382 if(codec
->read_buffer
&& codec
->read_size
< chunk_bytes
)
384 free(codec
->read_buffer
);
385 codec
->read_buffer
= 0;
388 if(!codec
->read_buffer
)
390 codec
->read_buffer
= malloc(chunk_bytes
);
391 codec
->read_size
= chunk_bytes
;
394 if(!codec
->last_samples
)
396 codec
->last_samples
= malloc(sizeof(int) * track_map
->channels
);
397 for(i
= 0; i
< track_map
->channels
; i
++)
399 codec
->last_samples
[i
] = 0;
403 if(!codec
->last_indexes
)
405 codec
->last_indexes
= malloc(sizeof(int) * track_map
->channels
);
406 for(i
= 0; i
< track_map
->channels
; i
++)
408 codec
->last_indexes
[i
] = 0;
412 /* Arm the input buffer */
413 step
= track_map
->channels
;
414 for(j
= 0; j
< track_map
->channels
; j
++)
416 input_ptr
= codec
->write_buffer
+ j
;
420 for(i
= 0; i
< samples
; i
++)
422 *input_ptr
= input_i
[j
][i
];
429 for(i
= 0; i
< samples
; i
++)
431 *input_ptr
= (int16_t)(input_f
[j
][i
] * 32767);
437 /* Encode from the input buffer to the read_buffer. */
438 input_ptr
= codec
->write_buffer
;
439 output_ptr
= codec
->read_buffer
;
441 for(j
= 0; j
< track_map
->channels
; j
++)
443 wmx2_encode_block(track_map
, output_ptr
, input_ptr
+ j
, track_map
->channels
, j
, samples
);
445 output_ptr
+= chunk_bytes
/ track_map
->channels
;
450 offset
= quicktime_position(file
);
451 quicktime_write_chunk_header(file
, trak
, &chunk_atom
);
452 result
= quicktime_write_data(file
, codec
->read_buffer
, chunk_bytes
);
456 result
= 1; /* defeat fwrite's return */
457 quicktime_write_chunk_footer(file
,
459 track_map
->current_chunk
,
462 track_map
->current_chunk
++;
468 static int delete_codec(quicktime_audio_map_t
*atrack
)
470 quicktime_wmx2_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
471 if(codec
->write_buffer
) free(codec
->write_buffer
);
472 if(codec
->read_buffer
) free(codec
->read_buffer
);
473 if(codec
->last_samples
) free(codec
->last_samples
);
474 if(codec
->last_indexes
) free(codec
->last_indexes
);
475 codec
->last_samples
= 0;
476 codec
->last_indexes
= 0;
477 codec
->read_buffer
= 0;
478 codec
->write_buffer
= 0;
480 codec
->buffer_channel
= 0; /* Channel of work buffer */
481 codec
->write_size
= 0; /* Size of work buffer */
482 codec
->read_size
= 0;
487 void quicktime_init_codec_wmx2(quicktime_audio_map_t
*atrack
)
489 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
491 /* Init public items */
492 codec_base
->priv
= calloc(1, sizeof(quicktime_wmx2_codec_t
));
493 codec_base
->delete_acodec
= delete_codec
;
494 codec_base
->decode_video
= 0;
495 codec_base
->encode_video
= 0;
496 codec_base
->decode_audio
= decode
;
497 codec_base
->encode_audio
= encode
;
498 codec_base
->fourcc
= QUICKTIME_WMX2
;
499 codec_base
->title
= "IMA4 on steroids";
500 codec_base
->desc
= "IMA4 on steroids. (Not standardized)";
501 codec_base
->wav_id
= 0x11;