00001 #include "funcprotos.h"
00002 #include "quicktime.h"
00003 #include "ulaw.h"
00004 #include <stdint.h>
00005
00006 typedef struct
00007 {
00008 float *ulawtofloat_table;
00009 float *ulawtofloat_ptr;
00010 int16_t *ulawtoint16_table;
00011 int16_t *ulawtoint16_ptr;
00012 unsigned char *int16toulaw_table;
00013 unsigned char *int16toulaw_ptr;
00014 unsigned char *read_buffer;
00015 long read_size;
00016 } quicktime_ulaw_codec_t;
00017
00018
00019
00020 #define uBIAS 0x84
00021 #define uCLIP 32635
00022
00023 int ulaw_init_ulawtoint16(quicktime_t *file, int track)
00024 {
00025 int i;
00026 quicktime_audio_map_t *atrack = &(file->atracks[track]);
00027 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
00028
00029
00030 ulaw_init_ulawtofloat(file, track);
00031 if(!codec->ulawtoint16_table)
00032 {
00033 codec->ulawtoint16_table = malloc(sizeof(int16_t) * 256);
00034 codec->ulawtoint16_ptr = codec->ulawtoint16_table;
00035
00036 for(i = 0; i < 256; i++)
00037 {
00038 codec->ulawtoint16_table[i] = (int)(32768 * codec->ulawtofloat_ptr[i]);
00039 }
00040 }
00041 return 0;
00042 }
00043
00044 int16_t ulaw_bytetoint16(quicktime_ulaw_codec_t *codec, unsigned char input)
00045 {
00046 return codec->ulawtoint16_ptr[input];
00047 }
00048
00049 int ulaw_init_ulawtofloat(quicktime_t *file, int track)
00050 {
00051 int i;
00052 float value;
00053 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
00054
00055 if(!codec->ulawtofloat_table)
00056 {
00057 static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
00058 int sign, exponent, mantissa, sample;
00059 unsigned char ulawbyte;
00060
00061 codec->ulawtofloat_table = malloc(sizeof(float) * 256);
00062 codec->ulawtofloat_ptr = codec->ulawtofloat_table;
00063 for(i = 0; i < 256; i++)
00064 {
00065 ulawbyte = (unsigned char)i;
00066 ulawbyte = ~ulawbyte;
00067 sign = (ulawbyte & 0x80);
00068 exponent = (ulawbyte >> 4) & 0x07;
00069 mantissa = ulawbyte & 0x0F;
00070 sample = exp_lut[exponent] + (mantissa << (exponent + 3));
00071 if(sign != 0) sample = -sample;
00072
00073 codec->ulawtofloat_ptr[i] = (float)sample / 32768;
00074 }
00075 }
00076 return 0;
00077 }
00078
00079 float ulaw_bytetofloat(quicktime_ulaw_codec_t *codec, unsigned char input)
00080 {
00081 return codec->ulawtofloat_ptr[input];
00082 }
00083
00084 int ulaw_init_int16toulaw(quicktime_t *file, int track)
00085 {
00086 quicktime_audio_map_t *atrack = &(file->atracks[track]);
00087 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
00088
00089 if(!codec->int16toulaw_table)
00090 {
00091 int sign, exponent, mantissa;
00092 unsigned char ulawbyte;
00093 int sample;
00094 int i;
00095 int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
00096 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
00097 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00098 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00099 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00100 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00101 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00102 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00103 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00104 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00105 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00106 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00107 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00108 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00109 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00110 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
00111
00112 codec->int16toulaw_table = malloc(65536);
00113 codec->int16toulaw_ptr = codec->int16toulaw_table + 32768;
00114
00115 for(i = -32768; i < 32768; i++)
00116 {
00117 sample = i;
00118
00119 sign = (sample >> 8) & 0x80;
00120 if(sign != 0) sample = -sample;
00121 if(sample > uCLIP) sample = uCLIP;
00122
00123
00124 sample = sample + uBIAS;
00125 exponent = exp_lut[(sample >> 7) & 0xFF];
00126 mantissa = (sample >> (exponent + 3)) & 0x0F;
00127 ulawbyte = ~(sign | (exponent << 4) | mantissa);
00128 #ifdef ZEROTRAP
00129 if (ulawbyte == 0) ulawbyte = 0x02;
00130 #endif
00131
00132 codec->int16toulaw_ptr[i] = ulawbyte;
00133 }
00134 }
00135 return 0;
00136 }
00137
00138 float ulaw_int16tobyte(quicktime_ulaw_codec_t *codec, int16_t input)
00139 {
00140 return codec->int16toulaw_ptr[input];
00141 }
00142
00143 float ulaw_floattobyte(quicktime_ulaw_codec_t *codec, float input)
00144 {
00145 return codec->int16toulaw_ptr[(int)(input * 32768)];
00146 }
00147
00148
00149 int ulaw_get_read_buffer(quicktime_t *file, int track, long samples)
00150 {
00151 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
00152
00153 if(codec->read_buffer && codec->read_size != samples)
00154 {
00155 free(codec->read_buffer);
00156 codec->read_buffer = 0;
00157 }
00158
00159 if(!codec->read_buffer)
00160 {
00161 int64_t bytes = samples * file->atracks[track].channels;
00162 codec->read_size = samples;
00163 if(!(codec->read_buffer = malloc(bytes))) return 1;
00164 }
00165 return 0;
00166 }
00167
00168 int ulaw_delete_tables(quicktime_audio_map_t *atrack)
00169 {
00170 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
00171
00172 if(codec->ulawtofloat_table)
00173 {
00174 free(codec->ulawtofloat_table);
00175 }
00176 if(codec->ulawtoint16_table)
00177 {
00178 free(codec->ulawtoint16_table);
00179 }
00180 if(codec->int16toulaw_table)
00181 {
00182 free(codec->int16toulaw_table);
00183 }
00184 if(codec->read_buffer) free(codec->read_buffer);
00185 codec->int16toulaw_table = 0;
00186 codec->ulawtoint16_table = 0;
00187 codec->ulawtofloat_table = 0;
00188 codec->read_buffer = 0;
00189 codec->read_size = 0;
00190 return 0;
00191 }
00192
00193
00194
00195 static int quicktime_delete_codec_ulaw(quicktime_audio_map_t *atrack)
00196 {
00197 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
00198
00199 ulaw_delete_tables(atrack);
00200 free(codec);
00201 return 0;
00202 }
00203
00204 static int quicktime_decode_ulaw(quicktime_t *file,
00205 int16_t *output_i,
00206 float *output_f,
00207 long samples,
00208 int track,
00209 int channel)
00210 {
00211 int result = 0;
00212 long i;
00213 quicktime_audio_map_t *track_map = &(file->atracks[track]);
00214 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
00215
00216 result = ulaw_get_read_buffer(file, track, samples);
00217
00218 if(output_f) result += ulaw_init_ulawtofloat(file, track);
00219 if(output_i) result += ulaw_init_ulawtoint16(file, track);
00220
00221 if(!result)
00222 {
00223 result = !quicktime_read_audio(file, codec->read_buffer, samples, track);
00224
00225 track_map->current_position -= samples;
00226
00227
00228 if(!result)
00229 {
00230 if(output_f)
00231 {
00232 unsigned char *input = &(codec->read_buffer[channel]);
00233 float *output_ptr = output_f;
00234 float *output_end = output_f + samples;
00235 int step = file->atracks[track].channels;
00236
00237 while(output_ptr < output_end)
00238 {
00239 *output_ptr++ = ulaw_bytetofloat(codec, *input);
00240 input += step;
00241 }
00242 }
00243 else
00244 if(output_i)
00245 {
00246 unsigned char *input = &(codec->read_buffer[channel]);
00247 int16_t *output_ptr = output_i;
00248 int16_t *output_end = output_i + samples;
00249 int step = file->atracks[track].channels;
00250
00251 while(output_ptr < output_end)
00252 {
00253 *output_ptr++ = ulaw_bytetoint16(codec, *input);
00254 input += step;
00255 }
00256 }
00257 }
00258 }
00259
00260 return result;
00261 }
00262
00263 static int quicktime_encode_ulaw(quicktime_t *file,
00264 int16_t **input_i,
00265 float **input_f,
00266 int track,
00267 long samples)
00268 {
00269 int result = 0;
00270 int channel, step;
00271 int64_t i;
00272 quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
00273 quicktime_atom_t chunk_atom;
00274 quicktime_audio_map_t *track_map = &file->atracks[track];
00275 quicktime_trak_t *trak = track_map->track;
00276
00277 result = ulaw_init_int16toulaw(file, track);
00278 result += ulaw_get_read_buffer(file, track, samples);
00279
00280 if(!result)
00281 {
00282 step = file->atracks[track].channels;
00283
00284 if(input_f)
00285 {
00286 for(channel = 0; channel < file->atracks[track].channels; channel++)
00287 {
00288 float *input_ptr = input_f[channel];
00289 float *input_end = input_f[channel] + samples;
00290 unsigned char *output = codec->read_buffer + channel;
00291
00292 while(input_ptr < input_end)
00293 {
00294 *output = ulaw_floattobyte(codec, *input_ptr++);
00295 output += step;
00296 }
00297 }
00298 }
00299 else
00300 if(input_i)
00301 {
00302 for(channel = 0; channel < file->atracks[track].channels; channel++)
00303 {
00304 int16_t *input_ptr = input_i[channel];
00305 int16_t *input_end = input_i[channel] + samples;
00306 unsigned char *output = codec->read_buffer + channel;
00307
00308 while(input_ptr < input_end)
00309 {
00310 *output = ulaw_int16tobyte(codec, *input_ptr++);
00311 output += step;
00312 }
00313 }
00314 }
00315
00316 quicktime_write_chunk_header(file, trak, &chunk_atom);
00317 result = quicktime_write_data(file,
00318 codec->read_buffer,
00319 samples * file->atracks[track].channels);
00320 quicktime_write_chunk_footer(file,
00321 trak,
00322 track_map->current_chunk,
00323 &chunk_atom,
00324 samples);
00325
00326
00327 if(result)
00328 result = 0;
00329 else
00330 result = 1;
00331
00332 file->atracks[track].current_chunk++;
00333 }
00334
00335 return result;
00336 }
00337
00338
00339 void quicktime_init_codec_ulaw(quicktime_audio_map_t *atrack)
00340 {
00341 quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
00342 quicktime_ulaw_codec_t *codec;
00343
00344
00345 codec_base->priv = calloc(1, sizeof(quicktime_ulaw_codec_t));
00346 codec_base->delete_acodec = quicktime_delete_codec_ulaw;
00347 codec_base->decode_video = 0;
00348 codec_base->encode_video = 0;
00349 codec_base->decode_audio = quicktime_decode_ulaw;
00350 codec_base->encode_audio = quicktime_encode_ulaw;
00351 codec_base->fourcc = QUICKTIME_ULAW;
00352 codec_base->title = "uLaw";
00353 codec_base->desc = "uLaw";
00354 codec_base->wav_id = 0x07;
00355
00356
00357 codec = ((quicktime_codec_t*)atrack->codec)->priv;
00358 }