1 #include "funcprotos.h"
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;
16 } quicktime_ulaw_codec_t;
18 /* ==================================== private for ulaw */
23 int ulaw_init_ulawtofloat(quicktime_t *file, int track)
26 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
28 if(!codec->ulawtofloat_table)
30 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
31 int sign, exponent, mantissa, sample;
32 unsigned char ulawbyte;
34 codec->ulawtofloat_table = malloc(sizeof(float) * 256);
35 codec->ulawtofloat_ptr = codec->ulawtofloat_table;
36 for(i = 0; i < 256; i++)
38 ulawbyte = (unsigned char)i;
40 sign = (ulawbyte & 0x80);
41 exponent = (ulawbyte >> 4) & 0x07;
42 mantissa = ulawbyte & 0x0F;
43 sample = exp_lut[exponent] + (mantissa << (exponent + 3));
44 if(sign != 0) sample = -sample;
46 codec->ulawtofloat_ptr[i] = (float)sample / 32768;
52 float ulaw_bytetofloat(quicktime_ulaw_codec_t *codec, unsigned char input)
54 return codec->ulawtofloat_ptr[input];
57 int ulaw_init_ulawtoint16(quicktime_t *file, int track)
60 quicktime_audio_map_t *atrack = &(file->atracks[track]);
61 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
63 /* We use the floating point table to get values for the 16 bit table */
64 ulaw_init_ulawtofloat(file, track);
65 if(!codec->ulawtoint16_table)
67 codec->ulawtoint16_table = malloc(sizeof(int16_t) * 256);
68 codec->ulawtoint16_ptr = codec->ulawtoint16_table;
70 for(i = 0; i < 256; i++)
72 codec->ulawtoint16_table[i] = (int)(32768 * codec->ulawtofloat_ptr[i]);
78 int16_t ulaw_bytetoint16(quicktime_ulaw_codec_t *codec, unsigned char input)
80 return codec->ulawtoint16_ptr[input];
83 int ulaw_init_int16toulaw(quicktime_t *file, int track)
85 quicktime_audio_map_t *atrack = &(file->atracks[track]);
86 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
88 if(!codec->int16toulaw_table)
90 int sign, exponent, mantissa;
91 unsigned char ulawbyte;
94 int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
95 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
96 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
97 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
98 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
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 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
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};
111 codec->int16toulaw_table = malloc(65536);
112 codec->int16toulaw_ptr = codec->int16toulaw_table + 32768;
114 for(i = -32768; i < 32768; i++)
117 /* Get the sample into sign-magnitude. */
118 sign = (sample >> 8) & 0x80; /* set aside the sign */
119 if(sign != 0) sample = -sample; /* get magnitude */
120 if(sample > uCLIP) sample = uCLIP; /* clip the magnitude */
122 /* Convert from 16 bit linear to ulaw. */
123 sample = sample + uBIAS;
124 exponent = exp_lut[(sample >> 7) & 0xFF];
125 mantissa = (sample >> (exponent + 3)) & 0x0F;
126 ulawbyte = ~(sign | (exponent << 4) | mantissa);
128 if (ulawbyte == 0) ulawbyte = 0x02; /* optional CCITT trap */
131 codec->int16toulaw_ptr[i] = ulawbyte;
137 float ulaw_int16tobyte(quicktime_ulaw_codec_t *codec, int16_t input)
139 return codec->int16toulaw_ptr[input];
142 float ulaw_floattobyte(quicktime_ulaw_codec_t *codec, float input)
144 return codec->int16toulaw_ptr[(int)(input * 32768)];
148 int ulaw_get_read_buffer(quicktime_t *file, int track, long samples)
150 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
152 if(codec->read_buffer && codec->read_size != samples)
154 free(codec->read_buffer);
155 codec->read_buffer = 0;
158 if(!codec->read_buffer)
160 int64_t bytes = samples * file->atracks[track].channels;
161 codec->read_size = samples;
162 if(!(codec->read_buffer = malloc(bytes))) return 1;
167 int ulaw_delete_tables(quicktime_audio_map_t *atrack)
169 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
171 if(codec->ulawtofloat_table)
173 free(codec->ulawtofloat_table);
175 if(codec->ulawtoint16_table)
177 free(codec->ulawtoint16_table);
179 if(codec->int16toulaw_table)
181 free(codec->int16toulaw_table);
183 if(codec->read_buffer) free(codec->read_buffer);
184 codec->int16toulaw_table = 0;
185 codec->ulawtoint16_table = 0;
186 codec->ulawtofloat_table = 0;
187 codec->read_buffer = 0;
188 codec->read_size = 0;
192 /* =================================== public for ulaw */
194 static void quicktime_delete_codec_ulaw(quicktime_audio_map_t *atrack)
196 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
198 ulaw_delete_tables(atrack);
202 static int quicktime_decode_ulaw(quicktime_t *file,
210 quicktime_audio_map_t *track_map = &(file->atracks[track]);
211 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
213 result = ulaw_get_read_buffer(file, track, samples);
215 if(output_f) result += ulaw_init_ulawtofloat(file, track);
216 if(output_i) result += ulaw_init_ulawtoint16(file, track);
220 result = !quicktime_read_audio(file, (char*)codec->read_buffer, samples, track);
221 // Undo increment since this is done in codecs.c
222 track_map->current_position -= samples;
224 /*printf("quicktime_decode_ulaw %d\n", result); */
229 unsigned char *input = &(codec->read_buffer[channel]);
230 float *output_ptr = output_f;
231 float *output_end = output_f + samples;
232 int step = file->atracks[track].channels;
234 while(output_ptr < output_end)
236 *output_ptr++ = ulaw_bytetofloat(codec, *input);
243 unsigned char *input = &(codec->read_buffer[channel]);
244 int16_t *output_ptr = output_i;
245 int16_t *output_end = output_i + samples;
246 int step = file->atracks[track].channels;
248 while(output_ptr < output_end)
250 *output_ptr++ = ulaw_bytetoint16(codec, *input);
260 static int quicktime_encode_ulaw(quicktime_t *file,
268 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
269 quicktime_atom_t chunk_atom;
270 quicktime_audio_map_t *track_map = &file->atracks[track];
271 quicktime_trak_t *trak = track_map->track;
273 result = ulaw_init_int16toulaw(file, track);
274 result += ulaw_get_read_buffer(file, track, samples);
278 step = file->atracks[track].channels;
282 for(channel = 0; channel < file->atracks[track].channels; channel++)
284 float *input_ptr = input_f[channel];
285 float *input_end = input_f[channel] + samples;
286 unsigned char *output = codec->read_buffer + channel;
288 while(input_ptr < input_end)
290 *output = ulaw_floattobyte(codec, *input_ptr++);
298 for(channel = 0; channel < file->atracks[track].channels; channel++)
300 int16_t *input_ptr = input_i[channel];
301 int16_t *input_end = input_i[channel] + samples;
302 unsigned char *output = codec->read_buffer + channel;
304 while(input_ptr < input_end)
306 *output = ulaw_int16tobyte(codec, *input_ptr++);
312 quicktime_write_chunk_header(file, trak, &chunk_atom);
313 result = quicktime_write_data(file, (char*)codec->read_buffer,
314 samples * file->atracks[track].channels);
315 quicktime_write_chunk_footer(file, trak,
316 track_map->current_chunk, &chunk_atom, samples);
318 /* defeat fwrite's return */
324 file->atracks[track].current_chunk++;
331 void quicktime_init_codec_ulaw(quicktime_audio_map_t *atrack)
333 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
334 // quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
336 /* Init public items */
337 codec_base->priv = calloc(1, sizeof(quicktime_ulaw_codec_t));
338 codec_base->delete_acodec = quicktime_delete_codec_ulaw;
339 codec_base->decode_video = 0;
340 codec_base->encode_video = 0;
341 codec_base->decode_audio = quicktime_decode_ulaw;
342 codec_base->encode_audio = quicktime_encode_ulaw;
343 codec_base->fourcc = QUICKTIME_ULAW;
344 codec_base->title = "uLaw";
345 codec_base->desc = "uLaw";
346 codec_base->wav_id = 0x07;
348 /* Init private items */