Merge branch 'ct' of git.pipapo.org:cinelerra-ct into ct
[cinelerra_cv/ct.git] / quicktime / ulaw.c
blob02d0fac15f424f9e5f71c05d6ff2497fc5e5e97e
1 #include "funcprotos.h"
2 #include "quicktime.h"
3 #include "ulaw.h"
4 #include <stdint.h>
6 typedef struct
8 float *ulawtofloat_table;
9 float *ulawtofloat_ptr;
10 int16_t *ulawtoint16_table;
11 int16_t *ulawtoint16_ptr;
12 unsigned char *int16toulaw_table;
13 unsigned char *int16toulaw_ptr;
14 unsigned char *read_buffer;
15 long read_size;
16 } quicktime_ulaw_codec_t;
18 /* ==================================== private for ulaw */
20 #define uBIAS 0x84
21 #define uCLIP 32635
23 int ulaw_init_ulawtoint16(quicktime_t *file, int track)
25 int i;
26 quicktime_audio_map_t *atrack = &(file->atracks[track]);
27 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
29 /* We use the floating point table to get values for the 16 bit table */
30 ulaw_init_ulawtofloat(file, track);
31 if(!codec->ulawtoint16_table)
33 codec->ulawtoint16_table = malloc(sizeof(int16_t) * 256);
34 codec->ulawtoint16_ptr = codec->ulawtoint16_table;
36 for(i = 0; i < 256; i++)
38 codec->ulawtoint16_table[i] = (int)(32768 * codec->ulawtofloat_ptr[i]);
41 return 0;
44 int16_t ulaw_bytetoint16(quicktime_ulaw_codec_t *codec, unsigned char input)
46 return codec->ulawtoint16_ptr[input];
49 int ulaw_init_ulawtofloat(quicktime_t *file, int track)
51 int i;
52 float value;
53 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
55 if(!codec->ulawtofloat_table)
57 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
58 int sign, exponent, mantissa, sample;
59 unsigned char ulawbyte;
61 codec->ulawtofloat_table = malloc(sizeof(float) * 256);
62 codec->ulawtofloat_ptr = codec->ulawtofloat_table;
63 for(i = 0; i < 256; i++)
65 ulawbyte = (unsigned char)i;
66 ulawbyte = ~ulawbyte;
67 sign = (ulawbyte & 0x80);
68 exponent = (ulawbyte >> 4) & 0x07;
69 mantissa = ulawbyte & 0x0F;
70 sample = exp_lut[exponent] + (mantissa << (exponent + 3));
71 if(sign != 0) sample = -sample;
73 codec->ulawtofloat_ptr[i] = (float)sample / 32768;
76 return 0;
79 float ulaw_bytetofloat(quicktime_ulaw_codec_t *codec, unsigned char input)
81 return codec->ulawtofloat_ptr[input];
84 int ulaw_init_int16toulaw(quicktime_t *file, int track)
86 quicktime_audio_map_t *atrack = &(file->atracks[track]);
87 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
89 if(!codec->int16toulaw_table)
91 int sign, exponent, mantissa;
92 unsigned char ulawbyte;
93 int sample;
94 int i;
95 int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
96 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
97 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
98 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
99 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
100 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
101 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
102 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
103 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
104 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
105 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
106 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
107 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
108 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
109 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
110 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
112 codec->int16toulaw_table = malloc(65536);
113 codec->int16toulaw_ptr = codec->int16toulaw_table + 32768;
115 for(i = -32768; i < 32768; i++)
117 sample = i;
118 /* Get the sample into sign-magnitude. */
119 sign = (sample >> 8) & 0x80; /* set aside the sign */
120 if(sign != 0) sample = -sample; /* get magnitude */
121 if(sample > uCLIP) sample = uCLIP; /* clip the magnitude */
123 /* Convert from 16 bit linear to ulaw. */
124 sample = sample + uBIAS;
125 exponent = exp_lut[(sample >> 7) & 0xFF];
126 mantissa = (sample >> (exponent + 3)) & 0x0F;
127 ulawbyte = ~(sign | (exponent << 4) | mantissa);
128 #ifdef ZEROTRAP
129 if (ulawbyte == 0) ulawbyte = 0x02; /* optional CCITT trap */
130 #endif
132 codec->int16toulaw_ptr[i] = ulawbyte;
135 return 0;
138 float ulaw_int16tobyte(quicktime_ulaw_codec_t *codec, int16_t input)
140 return codec->int16toulaw_ptr[input];
143 float ulaw_floattobyte(quicktime_ulaw_codec_t *codec, float input)
145 return codec->int16toulaw_ptr[(int)(input * 32768)];
149 int ulaw_get_read_buffer(quicktime_t *file, int track, long samples)
151 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
153 if(codec->read_buffer && codec->read_size != samples)
155 free(codec->read_buffer);
156 codec->read_buffer = 0;
159 if(!codec->read_buffer)
161 int64_t bytes = samples * file->atracks[track].channels;
162 codec->read_size = samples;
163 if(!(codec->read_buffer = malloc(bytes))) return 1;
165 return 0;
168 int ulaw_delete_tables(quicktime_audio_map_t *atrack)
170 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
172 if(codec->ulawtofloat_table)
174 free(codec->ulawtofloat_table);
176 if(codec->ulawtoint16_table)
178 free(codec->ulawtoint16_table);
180 if(codec->int16toulaw_table)
182 free(codec->int16toulaw_table);
184 if(codec->read_buffer) free(codec->read_buffer);
185 codec->int16toulaw_table = 0;
186 codec->ulawtoint16_table = 0;
187 codec->ulawtofloat_table = 0;
188 codec->read_buffer = 0;
189 codec->read_size = 0;
190 return 0;
193 /* =================================== public for ulaw */
195 static int quicktime_delete_codec_ulaw(quicktime_audio_map_t *atrack)
197 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
199 ulaw_delete_tables(atrack);
200 free(codec);
201 return 0;
204 static int quicktime_decode_ulaw(quicktime_t *file,
205 int16_t *output_i,
206 float *output_f,
207 long samples,
208 int track,
209 int channel)
211 int result = 0;
212 long i;
213 quicktime_audio_map_t *track_map = &(file->atracks[track]);
214 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
216 result = ulaw_get_read_buffer(file, track, samples);
218 if(output_f) result += ulaw_init_ulawtofloat(file, track);
219 if(output_i) result += ulaw_init_ulawtoint16(file, track);
221 if(!result)
223 result = !quicktime_read_audio(file, codec->read_buffer, samples, track);
224 // Undo increment since this is done in codecs.c
225 track_map->current_position -= samples;
227 /*printf("quicktime_decode_ulaw %d\n", result); */
228 if(!result)
230 if(output_f)
232 unsigned char *input = &(codec->read_buffer[channel]);
233 float *output_ptr = output_f;
234 float *output_end = output_f + samples;
235 int step = file->atracks[track].channels;
237 while(output_ptr < output_end)
239 *output_ptr++ = ulaw_bytetofloat(codec, *input);
240 input += step;
243 else
244 if(output_i)
246 unsigned char *input = &(codec->read_buffer[channel]);
247 int16_t *output_ptr = output_i;
248 int16_t *output_end = output_i + samples;
249 int step = file->atracks[track].channels;
251 while(output_ptr < output_end)
253 *output_ptr++ = ulaw_bytetoint16(codec, *input);
254 input += step;
260 return result;
263 static int quicktime_encode_ulaw(quicktime_t *file,
264 int16_t **input_i,
265 float **input_f,
266 int track,
267 long samples)
269 int result = 0;
270 int channel, step;
271 int64_t i;
272 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
273 quicktime_atom_t chunk_atom;
274 quicktime_audio_map_t *track_map = &file->atracks[track];
275 quicktime_trak_t *trak = track_map->track;
277 result = ulaw_init_int16toulaw(file, track);
278 result += ulaw_get_read_buffer(file, track, samples);
280 if(!result)
282 step = file->atracks[track].channels;
284 if(input_f)
286 for(channel = 0; channel < file->atracks[track].channels; channel++)
288 float *input_ptr = input_f[channel];
289 float *input_end = input_f[channel] + samples;
290 unsigned char *output = codec->read_buffer + channel;
292 while(input_ptr < input_end)
294 *output = ulaw_floattobyte(codec, *input_ptr++);
295 output += step;
299 else
300 if(input_i)
302 for(channel = 0; channel < file->atracks[track].channels; channel++)
304 int16_t *input_ptr = input_i[channel];
305 int16_t *input_end = input_i[channel] + samples;
306 unsigned char *output = codec->read_buffer + channel;
308 while(input_ptr < input_end)
310 *output = ulaw_int16tobyte(codec, *input_ptr++);
311 output += step;
316 quicktime_write_chunk_header(file, trak, &chunk_atom);
317 result = quicktime_write_data(file,
318 codec->read_buffer,
319 samples * file->atracks[track].channels);
320 quicktime_write_chunk_footer(file,
321 trak,
322 track_map->current_chunk,
323 &chunk_atom,
324 samples);
326 /* defeat fwrite's return */
327 if(result)
328 result = 0;
329 else
330 result = 1;
332 file->atracks[track].current_chunk++;
335 return result;
339 void quicktime_init_codec_ulaw(quicktime_audio_map_t *atrack)
341 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
342 quicktime_ulaw_codec_t *codec;
344 /* Init public items */
345 codec_base->priv = calloc(1, sizeof(quicktime_ulaw_codec_t));
346 codec_base->delete_acodec = quicktime_delete_codec_ulaw;
347 codec_base->decode_video = 0;
348 codec_base->encode_video = 0;
349 codec_base->decode_audio = quicktime_decode_ulaw;
350 codec_base->encode_audio = quicktime_encode_ulaw;
351 codec_base->fourcc = QUICKTIME_ULAW;
352 codec_base->title = "uLaw";
353 codec_base->desc = "uLaw";
354 codec_base->wav_id = 0x07;
356 /* Init private items */
357 codec = ((quicktime_codec_t*)atrack->codec)->priv;