"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/ulaw.c" (9 Jan 2007, 9666 Bytes) of package /linux/privat/old/quicktime4linux-2.3-src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #include "funcprotos.h"
    2 #include "quicktime.h"
    3 #include "ulaw.h"
    4 #include <stdint.h>
    5 
    6 typedef struct
    7 {
    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;
   17 
   18 /* ==================================== private for ulaw */
   19 
   20 #define uBIAS 0x84
   21 #define uCLIP 32635
   22 
   23 int ulaw_init_ulawtoint16(quicktime_t *file, int track)
   24 {
   25     int i;
   26     quicktime_audio_map_t *atrack = &(file->atracks[track]);
   27     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
   28 
   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)
   32     {
   33         codec->ulawtoint16_table = malloc(sizeof(int16_t) * 256);
   34         codec->ulawtoint16_ptr = codec->ulawtoint16_table;
   35 
   36         for(i = 0; i < 256; i++)
   37         {
   38             codec->ulawtoint16_table[i] = (int)(32768 * codec->ulawtofloat_ptr[i]);
   39         }
   40     }
   41     return 0;
   42 }
   43 
   44 int16_t ulaw_bytetoint16(quicktime_ulaw_codec_t *codec, unsigned char input)
   45 {
   46     return codec->ulawtoint16_ptr[input];
   47 }
   48 
   49 int ulaw_init_ulawtofloat(quicktime_t *file, int track)
   50 {
   51     int i;
   52     float value;
   53     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
   54 
   55     if(!codec->ulawtofloat_table)
   56     {
   57         static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
   58         int sign, exponent, mantissa, sample;
   59         unsigned char ulawbyte;
   60 
   61         codec->ulawtofloat_table = malloc(sizeof(float) * 256);
   62         codec->ulawtofloat_ptr = codec->ulawtofloat_table;
   63         for(i = 0; i < 256; i++)
   64         {
   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;
   72 
   73             codec->ulawtofloat_ptr[i] = (float)sample / 32768;
   74         }
   75     }
   76     return 0;
   77 }
   78 
   79 float ulaw_bytetofloat(quicktime_ulaw_codec_t *codec, unsigned char input)
   80 {
   81     return codec->ulawtofloat_ptr[input];
   82 }
   83 
   84 int ulaw_init_int16toulaw(quicktime_t *file, int track)
   85 {
   86     quicktime_audio_map_t *atrack = &(file->atracks[track]);
   87     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
   88 
   89     if(!codec->int16toulaw_table)
   90     {
   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};
  111 
  112         codec->int16toulaw_table = malloc(65536);
  113         codec->int16toulaw_ptr = codec->int16toulaw_table + 32768;
  114 
  115         for(i = -32768; i < 32768; i++)
  116         {
  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 */
  122 
  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
  131 
  132             codec->int16toulaw_ptr[i] = ulawbyte;
  133         }
  134     }
  135     return 0;
  136 }
  137 
  138 float ulaw_int16tobyte(quicktime_ulaw_codec_t *codec, int16_t input)
  139 {
  140     return codec->int16toulaw_ptr[input];
  141 }
  142 
  143 float ulaw_floattobyte(quicktime_ulaw_codec_t *codec, float input)
  144 {
  145     return codec->int16toulaw_ptr[(int)(input * 32768)];
  146 }
  147 
  148 
  149 int ulaw_get_read_buffer(quicktime_t *file, int track, long samples)
  150 {
  151     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
  152 
  153     if(codec->read_buffer && codec->read_size != samples)
  154     {
  155         free(codec->read_buffer);
  156         codec->read_buffer = 0;
  157     }
  158     
  159     if(!codec->read_buffer) 
  160     {
  161         int64_t bytes = samples * file->atracks[track].channels;
  162         codec->read_size = samples;
  163         if(!(codec->read_buffer = malloc(bytes))) return 1;
  164     }
  165     return 0;
  166 }
  167 
  168 int ulaw_delete_tables(quicktime_audio_map_t *atrack)
  169 {
  170     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
  171 
  172     if(codec->ulawtofloat_table) 
  173     { 
  174         free(codec->ulawtofloat_table); 
  175     }
  176     if(codec->ulawtoint16_table) 
  177     { 
  178         free(codec->ulawtoint16_table); 
  179     }
  180     if(codec->int16toulaw_table) 
  181     { 
  182         free(codec->int16toulaw_table); 
  183     }
  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;
  191 }
  192 
  193 /* =================================== public for ulaw */
  194 
  195 static int quicktime_delete_codec_ulaw(quicktime_audio_map_t *atrack)
  196 {
  197     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
  198 
  199     ulaw_delete_tables(atrack);
  200     free(codec);
  201     return 0;
  202 }
  203 
  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)
  210 {
  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;
  215 
  216     result = ulaw_get_read_buffer(file, track, samples);
  217     
  218     if(output_f) result += ulaw_init_ulawtofloat(file, track);
  219     if(output_i) result += ulaw_init_ulawtoint16(file, track);
  220 
  221     if(!result)
  222     {
  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;
  226 
  227 /*printf("quicktime_decode_ulaw %d\n", result); */
  228         if(!result)
  229         {
  230             if(output_f)
  231             {
  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;
  236 
  237                 while(output_ptr < output_end)
  238                 {
  239                     *output_ptr++ = ulaw_bytetofloat(codec, *input);
  240                     input += step;
  241                 }
  242             }
  243             else
  244             if(output_i)
  245             {
  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;
  250 
  251                 while(output_ptr < output_end)
  252                 {
  253                     *output_ptr++ = ulaw_bytetoint16(codec, *input);
  254                     input += step;
  255                 }
  256             }
  257         }
  258     }
  259 
  260     return result;
  261 }
  262 
  263 static int quicktime_encode_ulaw(quicktime_t *file, 
  264                             int16_t **input_i, 
  265                             float **input_f, 
  266                             int track, 
  267                             long samples)
  268 {
  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;
  276 
  277     result = ulaw_init_int16toulaw(file, track);
  278     result += ulaw_get_read_buffer(file, track, samples);
  279 
  280     if(!result)
  281     {
  282         step = file->atracks[track].channels;
  283 
  284         if(input_f)
  285         {
  286             for(channel = 0; channel < file->atracks[track].channels; channel++)
  287             {
  288                 float *input_ptr = input_f[channel];
  289                 float *input_end = input_f[channel] + samples;
  290                 unsigned char *output = codec->read_buffer + channel;
  291 
  292                 while(input_ptr < input_end)
  293                 {
  294                     *output = ulaw_floattobyte(codec, *input_ptr++);
  295                     output += step;
  296                 }
  297             }
  298         }
  299         else
  300         if(input_i)
  301         {
  302             for(channel = 0; channel < file->atracks[track].channels; channel++)
  303             {
  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;
  307 
  308                 while(input_ptr < input_end)
  309                 {
  310                     *output = ulaw_int16tobyte(codec, *input_ptr++);
  311                     output += step;
  312                 }
  313             }
  314         }
  315 
  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);
  325 
  326 /* defeat fwrite's return */
  327         if(result) 
  328             result = 0; 
  329         else 
  330             result = 1; 
  331 
  332         file->atracks[track].current_chunk++;       
  333     }
  334 
  335     return result;
  336 }
  337 
  338 
  339 void quicktime_init_codec_ulaw(quicktime_audio_map_t *atrack)
  340 {
  341     quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
  342     quicktime_ulaw_codec_t *codec;
  343 
  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;
  355 
  356 /* Init private items */
  357     codec = ((quicktime_codec_t*)atrack->codec)->priv;
  358 }