Merge branch 'ct' of git.pipapo.org:cinelerra-ct into ct
[cinelerra_cv/ct.git] / quicktime / rawaudio.c
blob0fabf0c1ba3b8bfb9c897de47b67dc0184671c5b
1 #include "quicktime.h"
2 #include "rawaudio.h"
4 typedef struct
6 char *work_buffer;
7 long buffer_size;
8 } quicktime_rawaudio_codec_t;
10 /* =================================== private for rawaudio */
12 int rawaudio_byte_order(void)
13 { /* 1 if little endian */
14 int16_t byteordertest;
15 int byteorder;
17 byteordertest = 0x0001;
18 byteorder = *((unsigned char *)&byteordertest);
19 return byteorder;
22 int rawaudio_swap_bytes(char *buffer, long samples, int channels, int bits)
24 long i;
25 char byte1, byte2, byte3;
26 char *buffer1, *buffer2, *buffer3;
28 if(!rawaudio_byte_order()) return 0;
30 switch(bits)
32 case 8:
33 break;
35 case 16:
36 buffer1 = buffer;
37 buffer2 = buffer + 1;
38 while(i < samples * 2)
40 byte1 = buffer2[i];
41 buffer2[i] = buffer1[i];
42 buffer1[i] = byte1;
43 i += 2;
45 break;
47 case 24:
48 buffer1 = buffer;
49 buffer2 = buffer + 2;
50 while(i < samples * 3)
52 byte1 = buffer2[i];
53 buffer2[i] = buffer1[i];
54 buffer1[i] = byte1;
55 i += 3;
57 break;
59 default:
60 break;
62 return 0;
65 static int get_work_buffer(quicktime_t *file, int track, long bytes)
67 quicktime_rawaudio_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
69 if(codec->work_buffer && codec->buffer_size != bytes)
71 free(codec->work_buffer);
72 codec->work_buffer = 0;
75 if(!codec->work_buffer)
77 codec->buffer_size = bytes;
78 if(!(codec->work_buffer = malloc(bytes))) return 1;
80 return 0;
83 /* =================================== public for rawaudio */
85 static int quicktime_delete_codec_rawaudio(quicktime_audio_map_t *atrack)
87 quicktime_rawaudio_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
89 if(codec->work_buffer) free(codec->work_buffer);
90 codec->work_buffer = 0;
91 codec->buffer_size = 0;
92 free(codec);
93 return 0;
96 static int quicktime_decode_rawaudio(quicktime_t *file,
97 int16_t *output_i,
98 float *output_f,
99 long samples,
100 int track,
101 int channel)
103 int result = 0;
104 long i, j;
105 quicktime_audio_map_t *track_map = &(file->atracks[track]);
106 quicktime_rawaudio_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
107 int step = file->atracks[track].channels * quicktime_audio_bits(file, track) / 8;
109 get_work_buffer(file, track, samples * step);
110 result = !quicktime_read_audio(file, codec->work_buffer, samples, track);
111 // Undo increment since this is done in codecs.c
112 track_map->current_position -= samples;
114 switch(quicktime_audio_bits(file, track))
116 case 8:
117 if(output_i && !result)
119 for(i = 0, j = 0; i < samples; i++)
121 output_i[i] = ((int16_t)((unsigned char)codec->work_buffer[j]) << 8);
122 j += step;
123 output_i[i] -= 0x8000;
126 else
127 if(output_f && !result)
129 for(i = 0, j = 0; i < samples; i++)
131 output_f[i] = (float)((unsigned char)codec->work_buffer[j]) - 0x80;
132 output_f[i] /= 0x7f;
133 j += step;
136 break;
138 case 16:
139 if(output_i && !result)
141 for(i = 0, j = 0; i < samples; i++)
143 output_i[i] = (int16_t)(codec->work_buffer[j]) << 8 |
144 (unsigned char)(codec->work_buffer[j + 1]);
145 j += step;
146 output_i[i] -= 0x8000;
149 else
150 if(output_f && !result)
152 for(i = 0, j = 0; i < samples; i++)
154 output_f[i] = (float)((int16_t)(codec->work_buffer[j]) << 8 |
155 (unsigned char)(codec->work_buffer[j + 1])) - 0x8000;
156 output_f[i] /= 0x7fff;
157 j += step;
160 break;
162 case 24:
163 if(output_i && !result)
165 for(i = 0, j = 0; i < samples; i++)
167 output_i[i] = ((int16_t)(codec->work_buffer[j]) << 8) |
168 (unsigned char)(codec->work_buffer[j + 1]);
169 output_i[i] -= 0x8000;
170 j += step;
173 else
174 if(output_f && !result)
176 for(i = 0, j = 0; i < samples; i++)
178 output_f[i] = (float)(((int)(codec->work_buffer[j]) << 16) |
179 ((unsigned int)(codec->work_buffer[j + 1]) << 8) |
180 (unsigned char)(codec->work_buffer[j + 2])) - 0x800000;
181 output_f[i] /= 0x7fffff;
182 j += step;
185 break;
187 default:
188 break;
190 /*printf("quicktime_decode_rawaudio 2\n"); */
192 return result;
195 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
197 static int quicktime_encode_rawaudio(quicktime_t *file,
198 int16_t **input_i,
199 float **input_f,
200 int track,
201 long samples)
203 int result = 0;
204 long i, j, offset;
205 quicktime_audio_map_t *track_map = &(file->atracks[track]);
206 quicktime_rawaudio_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
207 int step = file->atracks[track].channels * quicktime_audio_bits(file, track) / 8;
208 int sample;
209 float sample_f;
211 get_work_buffer(file, track, samples * step);
213 if(input_i)
215 for(i = 0; i < track_map->channels; i++)
217 switch(quicktime_audio_bits(file, track))
219 case 8:
220 for(j = 0; j < samples; j++)
222 sample = input_i[i][j] >> 8;
223 sample += 0x80;
224 codec->work_buffer[j * step + i] = sample;
226 break;
227 case 16:
228 for(j = 0; j < samples; j++)
230 sample = input_i[i][j];
231 sample += 0x8000;
232 codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8;
233 codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff;
235 break;
236 case 24:
237 for(j = 0; j < samples; j++)
239 sample = input_i[i][j];
240 sample += 0x8000;
241 codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff00) >> 8;
242 codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff);
243 codec->work_buffer[j * step + i * 3 + 2] = 0;
245 break;
249 else
251 for(i = 0; i < track_map->channels; i++)
253 switch(quicktime_audio_bits(file, track))
255 case 8:
256 for(j = 0; j < samples; j++)
258 sample_f = input_f[i][j];
259 if(sample_f < 0)
260 sample = (int)(sample_f * 0x7f - 0.5);
261 else
262 sample = (int)(sample_f * 0x7f + 0.5);
263 CLAMP(sample, -0x7f, 0x7f);
264 sample += 0x80;
265 codec->work_buffer[j * step + i] = sample;
267 break;
268 case 16:
269 for(j = 0; j < samples; j++)
271 sample_f = input_f[i][j];
272 if(sample_f < 0)
273 sample = (int)(sample_f * 0x7fff - 0.5);
274 else
275 sample = (int)(sample_f * 0x7fff + 0.5);
276 CLAMP(sample, -0x7fff, 0x7fff);
277 sample += 0x8000;
278 codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8;
279 codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff;
281 break;
282 case 24:
283 for(j = 0; j < samples; j++)
285 sample_f = input_f[i][j];
286 if(sample_f < 0)
287 sample = (int)(sample_f * 0x7fffff - 0.5);
288 else
289 sample = (int)(sample_f * 0x7fffff + 0.5);
290 CLAMP(sample, -0x7fffff, 0x7fffff);
291 sample += 0x800000;
292 codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff0000) >> 16;
293 codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff00) >> 8;
294 codec->work_buffer[j * step + i * 3 + 2] = ((unsigned int)sample) & 0xff;
296 break;
301 result = quicktime_write_audio(file, codec->work_buffer, samples, track);
302 return result;
306 void quicktime_init_codec_rawaudio(quicktime_audio_map_t *atrack)
308 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
309 quicktime_rawaudio_codec_t *codec;
311 /* Init public items */
312 codec_base->priv = calloc(1, sizeof(quicktime_rawaudio_codec_t));
313 codec_base->delete_acodec = quicktime_delete_codec_rawaudio;
314 codec_base->decode_video = 0;
315 codec_base->encode_video = 0;
316 codec_base->decode_audio = quicktime_decode_rawaudio;
317 codec_base->encode_audio = quicktime_encode_rawaudio;
318 codec_base->fourcc = QUICKTIME_RAW;
319 codec_base->title = "8 bit unsigned";
320 codec_base->desc = "8 bit unsigned for video";
321 codec_base->wav_id = 0x01;
323 /* Init private items */
324 codec = codec_base->priv;