1 #include "funcprotos.h"
5 /* =================================== private for twos */
12 } quicktime_twos_codec_t
;
14 static int byte_order(void)
15 { /* 1 if little endian */
16 int16_t byteordertest
;
19 byteordertest
= 0x0001;
20 byteorder
= *((unsigned char *)&byteordertest
);
24 static int get_work_buffer(quicktime_t
*file
, int track
, long bytes
)
26 quicktime_twos_codec_t
*codec
= ((quicktime_codec_t
*)file
->atracks
[track
].codec
)->priv
;
28 if(codec
->work_buffer
&& codec
->buffer_size
!= bytes
)
30 free(codec
->work_buffer
);
31 codec
->work_buffer
= 0;
34 if(!codec
->work_buffer
)
36 codec
->buffer_size
= bytes
;
37 if(!(codec
->work_buffer
= malloc(bytes
))) return 1;
42 /* =================================== public for twos */
44 static int delete_codec(quicktime_audio_map_t
*atrack
)
46 quicktime_twos_codec_t
*codec
= ((quicktime_codec_t
*)atrack
->codec
)->priv
;
48 if(codec
->work_buffer
) free(codec
->work_buffer
);
49 codec
->work_buffer
= 0;
50 codec
->buffer_size
= 0;
55 static int swap_bytes(char *buffer
, long samples
, int channels
, int bits
)
58 char byte1
, byte2
, byte3
;
59 char *buffer1
, *buffer2
, *buffer3
;
61 if(!byte_order()) return 0;
71 while(i
< samples
* channels
* 2)
74 buffer2
[i
] = buffer1
[i
];
83 while(i
< samples
* channels
* 3)
86 buffer2
[i
] = buffer1
[i
];
99 static int decode(quicktime_t
*file
,
108 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
109 quicktime_twos_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
110 int step
= track_map
->channels
* quicktime_audio_bits(file
, track
) / 8;
112 get_work_buffer(file
, track
, samples
* step
);
114 * printf("decode 1 %d\n", quicktime_audio_bits(file, track));
117 result
= !quicktime_read_audio(file
, codec
->work_buffer
, samples
, track
);
120 /* Undo increment since this is done in codecs.c */
121 track_map
->current_position
-= samples
;
123 /* Handle AVI byte order */
125 swap_bytes(codec
->work_buffer
,
128 quicktime_audio_bits(file
, track
));
130 switch(quicktime_audio_bits(file
, track
))
133 if(output_i
&& !result
)
135 for(i
= 0, j
= channel
; i
< samples
; i
++)
137 output_i
[i
] = ((int16_t)codec
->work_buffer
[j
]) << 8;
142 if(output_f
&& !result
)
144 for(i
= 0, j
= channel
; i
< samples
; i
++)
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 output_i
[i
] = ((int16_t)codec
->work_buffer
[j
]) << 8 |
158 ((unsigned char)codec
->work_buffer
[j
+ 1]);
163 if(output_f
&& !result
)
165 for(i
= 0, j
= channel
* 2; i
< samples
; i
++)
167 output_f
[i
] = (float)((((int16_t)codec
->work_buffer
[j
]) << 8) |
168 ((unsigned char)codec
->work_buffer
[j
+ 1])) / 0x7fff;
175 if(output_i
&& !result
)
177 for(i
= 0, j
= channel
* 3; i
< samples
; i
++)
179 output_i
[i
] = (((int16_t)codec
->work_buffer
[j
]) << 8) |
180 ((unsigned char)codec
->work_buffer
[j
+ 1]);
185 if(output_f
&& !result
)
187 for(i
= 0, j
= channel
* 3; i
< samples
; i
++)
189 output_f
[i
] = (float)((((int)codec
->work_buffer
[j
]) << 16) |
190 (((unsigned char)codec
->work_buffer
[j
+ 1]) << 8) |
191 ((unsigned char)codec
->work_buffer
[j
+ 2])) / 0x7fffff;
205 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
207 static int encode(quicktime_t
*file
,
215 quicktime_audio_map_t
*track_map
= &(file
->atracks
[track
]);
216 quicktime_twos_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
217 int step
= track_map
->channels
* quicktime_audio_bits(file
, track
) / 8;
221 get_work_buffer(file
, track
, samples
* step
);
225 for(i
= 0; i
< track_map
->channels
; i
++)
227 switch(quicktime_audio_bits(file
, track
))
230 for(j
= 0; j
< samples
; j
++)
232 sample
= input_i
[i
][j
] >> 8;
233 codec
->work_buffer
[j
* step
+ i
] = sample
;
237 for(j
= 0; j
< samples
; j
++)
239 sample
= input_i
[i
][j
];
240 codec
->work_buffer
[j
* step
+ i
* 2] = ((unsigned int)sample
& 0xff00) >> 8;
241 codec
->work_buffer
[j
* step
+ i
* 2 + 1] = ((unsigned int)sample
) & 0xff;
245 for(j
= 0; j
< samples
; j
++)
247 sample
= input_i
[i
][j
];
248 codec
->work_buffer
[j
* step
+ i
* 3] = ((unsigned int)sample
& 0xff00) >> 8;
249 codec
->work_buffer
[j
* step
+ i
* 3 + 1] = ((unsigned int)sample
& 0xff);
250 codec
->work_buffer
[j
* step
+ i
* 3 + 2] = 0;
258 for(i
= 0; i
< track_map
->channels
; i
++)
260 switch(quicktime_audio_bits(file
, track
))
263 for(j
= 0; j
< samples
; j
++)
265 sample_f
= input_f
[i
][j
];
267 sample
= (int)(sample_f
* 0x7f - 0.5);
269 sample
= (int)(sample_f
* 0x7f + 0.5);
270 CLAMP(sample
, -0x7f, 0x7f);
271 codec
->work_buffer
[j
* step
+ i
] = sample
;
275 for(j
= 0; j
< samples
; j
++)
277 sample_f
= input_f
[i
][j
];
279 sample
= (int)(sample_f
* 0x7fff - 0.5);
281 sample
= (int)(sample_f
* 0x7fff + 0.5);
282 CLAMP(sample
, -0x7fff, 0x7fff);
283 codec
->work_buffer
[j
* step
+ i
* 2] = ((unsigned int)sample
& 0xff00) >> 8;
284 codec
->work_buffer
[j
* step
+ i
* 2 + 1] = ((unsigned int)sample
) & 0xff;
288 for(j
= 0; j
< samples
; j
++)
290 sample_f
= input_f
[i
][j
];
292 sample
= (int)(sample_f
* 0x7fffff - 0.5);
294 sample
= (int)(sample_f
* 0x7fffff + 0.5);
295 CLAMP(sample
, -0x7fffff, 0x7fffff);
296 codec
->work_buffer
[j
* step
+ i
* 3] = ((unsigned int)sample
& 0xff0000) >> 16;
297 codec
->work_buffer
[j
* step
+ i
* 3 + 1] = ((unsigned int)sample
& 0xff00) >> 8;
298 codec
->work_buffer
[j
* step
+ i
* 3 + 2] = ((unsigned int)sample
) & 0xff;
305 /* Handle AVI byte order */
307 swap_bytes(codec
->work_buffer
,
310 quicktime_audio_bits(file
, track
));
312 result
= quicktime_write_audio(file
, codec
->work_buffer
, samples
, track
);
317 void quicktime_init_codec_twos(quicktime_audio_map_t
*atrack
)
319 quicktime_twos_codec_t
*codec
;
320 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)atrack
->codec
;
322 /* Init public items */
323 codec_base
->delete_acodec
= delete_codec
;
324 codec_base
->decode_audio
= decode
;
325 codec_base
->encode_audio
= encode
;
326 codec_base
->fourcc
= QUICKTIME_TWOS
;
327 codec_base
->title
= "Twos complement";
328 codec_base
->desc
= "Twos complement";
329 codec_base
->wav_id
= 0x01;
331 /* Init private items */
332 codec
= codec_base
->priv
= calloc(1, sizeof(quicktime_twos_codec_t
));
333 codec
->work_buffer
= 0;
334 codec
->buffer_size
= 0;