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_ulawtoint16(quicktime_t
*file
, int track
)
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
]);
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
)
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
;
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;
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
;
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
++)
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
);
129 if (ulawbyte
== 0) ulawbyte
= 0x02; /* optional CCITT trap */
132 codec
->int16toulaw_ptr
[i
] = ulawbyte
;
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;
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;
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
);
204 static int quicktime_decode_ulaw(quicktime_t
*file
,
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
);
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); */
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
);
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
);
263 static int quicktime_encode_ulaw(quicktime_t
*file
,
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
);
282 step
= file
->atracks
[track
].channels
;
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
++);
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
++);
316 quicktime_write_chunk_header(file
, trak
, &chunk_atom
);
317 result
= quicktime_write_data(file
,
319 samples
* file
->atracks
[track
].channels
);
320 quicktime_write_chunk_footer(file
,
322 track_map
->current_chunk
,
326 /* defeat fwrite's return */
332 file
->atracks
[track
].current_chunk
++;
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
;