1 #include "funcprotos.h"
5 /* =================================== private for twos */
13 } quicktime_twos_codec_t;
15 static int byte_order(void)
16 { /* 1 if little endian */
17 int16_t byteordertest;
20 byteordertest = 0x0001;
21 byteorder = *((unsigned char *)&byteordertest);
25 static int get_work_buffer(quicktime_t *file, int track, long bytes)
27 quicktime_twos_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
29 if(codec->work_buffer && codec->buffer_size != bytes)
31 free(codec->work_buffer);
32 codec->work_buffer = 0;
35 if(!codec->work_buffer)
37 codec->buffer_size = bytes;
38 if(!(codec->work_buffer = malloc(bytes))) return 1;
43 /* =================================== public for twos */
45 static void delete_codec(quicktime_audio_map_t *atrack)
47 quicktime_twos_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
49 if(codec->work_buffer) free(codec->work_buffer);
50 codec->work_buffer = 0;
51 codec->buffer_size = 0;
55 static int swap_bytes(char *buffer, long samples, int channels, int bits)
58 char byte1, *buffer1, *buffer2;
60 if(!byte_order()) return 0;
66 while(i < samples * channels * 2) {
68 buffer2[i] = buffer1[i];
77 while(i < samples * channels * 3) {
79 buffer2[i] = buffer1[i];
91 static int decode(quicktime_t *file,
100 quicktime_audio_map_t *track_map = &(file->atracks[track]);
101 quicktime_twos_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
102 int step = track_map->channels * quicktime_audio_bits(file, track) / 8;
104 get_work_buffer(file, track, samples * step);
106 * printf("decode 1 %d\n", quicktime_audio_bits(file, track));
109 result = !quicktime_read_audio(file, codec->work_buffer, samples, track);
112 /* Undo increment since this is done in codecs.c */
113 track_map->current_position -= samples;
115 /* Handle AVI byte order */
117 swap_bytes(codec->work_buffer,
120 quicktime_audio_bits(file, track));
122 switch(quicktime_audio_bits(file, track))
125 if(output_i && !result)
127 for(i = 0, j = channel; i < samples; i++)
130 output_i[i] = (int16_t)(((unsigned char)codec->work_buffer[j]) << 8) -
133 output_i[i] = ((int16_t)codec->work_buffer[j]) << 8;
138 if(output_f && !result)
140 for(i = 0, j = channel; i < samples; i++)
143 output_f[i] = ((float)((unsigned char)codec->work_buffer[j]) - 0x7f) /
146 output_f[i] = ((float)codec->work_buffer[j]) / 0x7f;
153 if(output_i && !result)
155 for(i = 0, j = channel * 2; i < samples; i++)
157 if(codec->little_endian)
159 output_i[i] = ((int16_t)codec->work_buffer[j + 1]) << 8 |
160 ((unsigned char)codec->work_buffer[j]);
164 output_i[i] = ((int16_t)codec->work_buffer[j]) << 8 |
165 ((unsigned char)codec->work_buffer[j + 1]);
171 if(output_f && !result)
173 for(i = 0, j = channel * 2; i < samples; i++)
175 if(codec->little_endian)
177 output_f[i] = (float)((((int16_t)codec->work_buffer[j + 1]) << 8) |
178 ((unsigned char)codec->work_buffer[j])) / 0x7fff;
182 output_f[i] = (float)((((int16_t)codec->work_buffer[j]) << 8) |
183 ((unsigned char)codec->work_buffer[j + 1])) / 0x7fff;
192 if(output_i && !result)
194 for(i = 0, j = channel * 3; i < samples; i++)
196 output_i[i] = (((int16_t)codec->work_buffer[j]) << 8) |
197 ((unsigned char)codec->work_buffer[j + 1]);
202 if(output_f && !result)
204 for(i = 0, j = channel * 3; i < samples; i++)
206 output_f[i] = (float)((((int)codec->work_buffer[j]) << 16) |
207 (((unsigned char)codec->work_buffer[j + 1]) << 8) |
208 ((unsigned char)codec->work_buffer[j + 2])) / 0x7fffff;
222 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
224 static int encode(quicktime_t *file,
232 quicktime_audio_map_t *track_map = &(file->atracks[track]);
233 quicktime_twos_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
234 int step = track_map->channels * quicktime_audio_bits(file, track) / 8;
238 get_work_buffer(file, track, samples * step);
242 for(i = 0; i < track_map->channels; i++)
244 switch(quicktime_audio_bits(file, track))
247 for(j = 0; j < samples; j++)
249 sample = input_i[i][j] >> 8;
250 codec->work_buffer[j * step + i] = sample;
254 for(j = 0; j < samples; j++)
256 sample = input_i[i][j];
257 codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8;
258 codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff;
262 for(j = 0; j < samples; j++)
264 sample = input_i[i][j];
265 codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff00) >> 8;
266 codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff);
267 codec->work_buffer[j * step + i * 3 + 2] = 0;
275 for(i = 0; i < track_map->channels; i++)
277 switch(quicktime_audio_bits(file, track))
280 for(j = 0; j < samples; j++)
282 sample_f = input_f[i][j];
284 sample = (int)(sample_f * 0x7f - 0.5);
286 sample = (int)(sample_f * 0x7f + 0.5);
287 CLAMP(sample, -0x7f, 0x7f);
288 codec->work_buffer[j * step + i] = sample;
292 for(j = 0; j < samples; j++)
294 sample_f = input_f[i][j];
296 sample = (int)(sample_f * 0x7fff - 0.5);
298 sample = (int)(sample_f * 0x7fff + 0.5);
299 CLAMP(sample, -0x7fff, 0x7fff);
300 codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8;
301 codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff;
305 for(j = 0; j < samples; j++)
307 sample_f = input_f[i][j];
309 sample = (int)(sample_f * 0x7fffff - 0.5);
311 sample = (int)(sample_f * 0x7fffff + 0.5);
312 CLAMP(sample, -0x7fffff, 0x7fffff);
313 codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff0000) >> 16;
314 codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff00) >> 8;
315 codec->work_buffer[j * step + i * 3 + 2] = ((unsigned int)sample) & 0xff;
322 /* Handle AVI byte order */
324 swap_bytes(codec->work_buffer,
327 quicktime_audio_bits(file, track));
329 result = quicktime_write_audio(file, codec->work_buffer, samples, track);
334 static void init_common(quicktime_audio_map_t *atrack,
339 quicktime_twos_codec_t *codec;
340 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
342 /* Init public items */
343 codec_base->delete_acodec = delete_codec;
344 codec_base->decode_audio = decode;
345 codec_base->encode_audio = encode;
346 codec_base->fourcc = fourcc;
347 codec_base->title = title;
348 codec_base->desc = description;
349 codec_base->wav_id = 0x01;
351 /* Init private items */
352 codec = codec_base->priv = calloc(1, sizeof(quicktime_twos_codec_t));
353 codec->work_buffer = 0;
354 codec->buffer_size = 0;
355 if(quicktime_match_32(fourcc, QUICKTIME_SOWT))
356 codec->little_endian = 1;
359 void quicktime_init_codec_twos(quicktime_audio_map_t *atrack)
361 init_common(atrack, QUICKTIME_TWOS, "Twos complement", "Twos complement");
364 void quicktime_init_codec_sowt(quicktime_audio_map_t *atrack)
366 init_common(atrack, QUICKTIME_SOWT, "Twos complement", "Twos complement");