r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / quicktime / twos.c
blobdb034f3eba89a6716311bf86a46b36a35a6f8bdf
1 #include "funcprotos.h"
2 #include "quicktime.h"
3 #include "twos.h"
5 /* =================================== private for twos */
8 typedef struct
10 char *work_buffer;
11 long buffer_size;
12 } quicktime_twos_codec_t;
14 static int byte_order(void)
15 { /* 1 if little endian */
16 int16_t byteordertest;
17 int byteorder;
19 byteordertest = 0x0001;
20 byteorder = *((unsigned char *)&byteordertest);
21 return byteorder;
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;
39 return 0;
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;
51 free(codec);
52 return 0;
55 static int swap_bytes(char *buffer, long samples, int channels, int bits)
57 long i = 0;
58 char byte1, byte2, byte3;
59 char *buffer1, *buffer2, *buffer3;
61 if(!byte_order()) return 0;
63 switch(bits)
65 case 8:
66 break;
68 case 16:
69 buffer1 = buffer;
70 buffer2 = buffer + 1;
71 while(i < samples * channels * 2)
73 byte1 = buffer2[i];
74 buffer2[i] = buffer1[i];
75 buffer1[i] = byte1;
76 i += 2;
78 break;
80 case 24:
81 buffer1 = buffer;
82 buffer2 = buffer + 2;
83 while(i < samples * channels * 3)
85 byte1 = buffer2[i];
86 buffer2[i] = buffer1[i];
87 buffer1[i] = byte1;
88 i += 3;
90 break;
92 default:
93 break;
95 return 0;
99 static int decode(quicktime_t *file,
100 int16_t *output_i,
101 float *output_f,
102 long samples,
103 int track,
104 int channel)
106 int result = 0;
107 long i, j;
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));
115 * sleep(1);
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 */
124 if(file->use_avi)
125 swap_bytes(codec->work_buffer,
126 samples,
127 track_map->channels,
128 quicktime_audio_bits(file, track));
130 switch(quicktime_audio_bits(file, track))
132 case 8:
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;
138 j += step;
141 else
142 if(output_f && !result)
144 for(i = 0, j = channel; i < samples; i++)
146 output_f[i] = ((float)codec->work_buffer[j]) / 0x7f;
147 j += step;
150 break;
152 case 16:
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]);
159 j += step;
162 else
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;
169 j += step;
172 break;
174 case 24:
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]);
181 j += step;
184 else
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;
192 j += step;
195 break;
197 default:
198 break;
202 return result;
205 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
207 static int encode(quicktime_t *file,
208 int16_t **input_i,
209 float **input_f,
210 int track,
211 long samples)
213 int result = 0;
214 long i, j, offset;
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;
218 int sample;
219 float sample_f;
221 get_work_buffer(file, track, samples * step);
223 if(input_i)
225 for(i = 0; i < track_map->channels; i++)
227 switch(quicktime_audio_bits(file, track))
229 case 8:
230 for(j = 0; j < samples; j++)
232 sample = input_i[i][j] >> 8;
233 codec->work_buffer[j * step + i] = sample;
235 break;
236 case 16:
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;
243 break;
244 case 24:
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;
252 break;
256 else
258 for(i = 0; i < track_map->channels; i++)
260 switch(quicktime_audio_bits(file, track))
262 case 8:
263 for(j = 0; j < samples; j++)
265 sample_f = input_f[i][j];
266 if(sample_f < 0)
267 sample = (int)(sample_f * 0x7f - 0.5);
268 else
269 sample = (int)(sample_f * 0x7f + 0.5);
270 CLAMP(sample, -0x7f, 0x7f);
271 codec->work_buffer[j * step + i] = sample;
273 break;
274 case 16:
275 for(j = 0; j < samples; j++)
277 sample_f = input_f[i][j];
278 if(sample_f < 0)
279 sample = (int)(sample_f * 0x7fff - 0.5);
280 else
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;
286 break;
287 case 24:
288 for(j = 0; j < samples; j++)
290 sample_f = input_f[i][j];
291 if(sample_f < 0)
292 sample = (int)(sample_f * 0x7fffff - 0.5);
293 else
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;
300 break;
305 /* Handle AVI byte order */
306 if(file->use_avi)
307 swap_bytes(codec->work_buffer,
308 samples,
309 track_map->channels,
310 quicktime_audio_bits(file, track));
312 result = quicktime_write_audio(file, codec->work_buffer, samples, track);
314 return result;
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;