home *** CD-ROM | disk | FTP | other *** search
/ Geek 6 / Geek-006.iso / linux / video / xmovie-1.5.3.tar.gz / xmovie-1.5.3.tar / xmovie-1.5.3 / quicktime / ulaw.c < prev    next >
C/C++ Source or Header  |  2000-11-29  |  9KB  |  334 lines

  1. #include "ulaw.h"
  2.  
  3. /* ==================================== private for ulaw */
  4.  
  5. #define uBIAS 0x84
  6. #define uCLIP 32635
  7.  
  8. int ulaw_init_ulawtoint16(quicktime_t *file, int track)
  9. {
  10.     int i;
  11.     quicktime_audio_map_t *atrack = &(file->atracks[track]);
  12.     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
  13.  
  14. /* We use the floating point table to get values for the 16 bit table */
  15.     ulaw_init_ulawtofloat(file, track);
  16.     if(!codec->ulawtoint16_table)
  17.     {
  18.         codec->ulawtoint16_table = malloc(sizeof(QUICKTIME_INT16) * 256);
  19.         codec->ulawtoint16_ptr = codec->ulawtoint16_table;
  20.  
  21.         for(i = 0; i < 256; i++)
  22.         {
  23.             codec->ulawtoint16_table[i] = (int)(32768 * codec->ulawtofloat_ptr[i]);
  24.         }
  25.     }
  26.     return 0;
  27. }
  28.  
  29. QUICKTIME_INT16 ulaw_bytetoint16(quicktime_ulaw_codec_t *codec, unsigned char input)
  30. {
  31.     return codec->ulawtoint16_ptr[input];
  32. }
  33.  
  34. int ulaw_init_ulawtofloat(quicktime_t *file, int track)
  35. {
  36.     int i;
  37.     float value;
  38.     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
  39.  
  40.     if(!codec->ulawtofloat_table)
  41.     {
  42.         static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
  43.         int sign, exponent, mantissa, sample;
  44.         unsigned char ulawbyte;
  45.  
  46.         codec->ulawtofloat_table = malloc(sizeof(float) * 256);
  47.         codec->ulawtofloat_ptr = codec->ulawtofloat_table;
  48.         for(i = 0; i < 256; i++)
  49.         {
  50.             ulawbyte = (unsigned char)i;
  51.             ulawbyte = ~ulawbyte;
  52.             sign = (ulawbyte & 0x80);
  53.             exponent = (ulawbyte >> 4) & 0x07;
  54.             mantissa = ulawbyte & 0x0F;
  55.             sample = exp_lut[exponent] + (mantissa << (exponent + 3));
  56.             if(sign != 0) sample = -sample;
  57.  
  58.             codec->ulawtofloat_ptr[i] = (float)sample / 32768;
  59.         }
  60.     }
  61.     return 0;
  62. }
  63.  
  64. float ulaw_bytetofloat(quicktime_ulaw_codec_t *codec, unsigned char input)
  65. {
  66.     return codec->ulawtofloat_ptr[input];
  67. }
  68.  
  69. int ulaw_init_int16toulaw(quicktime_t *file, int track)
  70. {
  71.     quicktime_audio_map_t *atrack = &(file->atracks[track]);
  72.     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
  73.  
  74.     if(!codec->int16toulaw_table)
  75.     {
  76.         int sign, exponent, mantissa;
  77.         unsigned char ulawbyte;
  78.         int sample;
  79.         int i;
  80.         int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
  81.                                4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  82.                                5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  83.                                5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  84.                                6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  85.                                6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  86.                                6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  87.                                6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  88.                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  89.                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  90.                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  91.                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  92.                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  93.                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  94.                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  95.                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
  96.  
  97.          codec->int16toulaw_table = malloc(65536);
  98.         codec->int16toulaw_ptr = codec->int16toulaw_table + 32768;
  99.  
  100.         for(i = -32768; i < 32768; i++)
  101.         {
  102.             sample = i;
  103. /* Get the sample into sign-magnitude. */
  104.             sign = (sample >> 8) & 0x80;        /* set aside the sign */
  105.             if(sign != 0) sample = -sample;        /* get magnitude */
  106.             if(sample > uCLIP) sample = uCLIP;        /* clip the magnitude */
  107.  
  108. /* Convert from 16 bit linear to ulaw. */
  109.             sample = sample + uBIAS;
  110.             exponent = exp_lut[(sample >> 7) & 0xFF];
  111.             mantissa = (sample >> (exponent + 3)) & 0x0F;
  112.             ulawbyte = ~(sign | (exponent << 4) | mantissa);
  113. #ifdef ZEROTRAP
  114.             if (ulawbyte == 0) ulawbyte = 0x02;        /* optional CCITT trap */
  115. #endif
  116.  
  117.             codec->int16toulaw_ptr[i] = ulawbyte;
  118.         }
  119.     }
  120.     return 0;
  121. }
  122.  
  123. float ulaw_int16tobyte(quicktime_ulaw_codec_t *codec, QUICKTIME_INT16 input)
  124. {
  125.     return codec->int16toulaw_ptr[input];
  126. }
  127.  
  128. float ulaw_floattobyte(quicktime_ulaw_codec_t *codec, float input)
  129. {
  130.     return codec->int16toulaw_ptr[(int)(input * 32768)];
  131. }
  132.  
  133.  
  134. int ulaw_get_read_buffer(quicktime_t *file, int track, long samples)
  135. {
  136.     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
  137.  
  138.     if(codec->read_buffer && codec->read_size != samples)
  139.     {
  140.         free(codec->read_buffer);
  141.         codec->read_buffer = 0;
  142.     }
  143.     
  144.     if(!codec->read_buffer) 
  145.     {
  146.         long bytes = samples * file->atracks[track].channels;
  147.         codec->read_size = samples;
  148.         if(!(codec->read_buffer = malloc(bytes))) return 1;
  149.     }
  150.     return 0;
  151. }
  152.  
  153. int ulaw_delete_tables(quicktime_audio_map_t *atrack)
  154. {
  155.     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
  156.  
  157.     if(codec->ulawtofloat_table) 
  158.     { 
  159.         free(codec->ulawtofloat_table); 
  160.     }
  161.     if(codec->ulawtoint16_table) 
  162.     { 
  163.         free(codec->ulawtoint16_table); 
  164.     }
  165.     if(codec->int16toulaw_table) 
  166.     { 
  167.         free(codec->int16toulaw_table); 
  168.     }
  169.     if(codec->read_buffer) free(codec->read_buffer);
  170.     codec->int16toulaw_table = 0;
  171.     codec->ulawtoint16_table = 0;
  172.     codec->ulawtofloat_table = 0;
  173.     codec->read_buffer = 0;
  174.     codec->read_size = 0;
  175.     return 0;
  176. }
  177.  
  178. /* =================================== public for ulaw */
  179.  
  180. static int quicktime_delete_codec_ulaw(quicktime_audio_map_t *atrack)
  181. {
  182.     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
  183.  
  184.     ulaw_delete_tables(atrack);
  185.     free(codec);
  186.     return 0;
  187. }
  188.  
  189. static int quicktime_decode_ulaw(quicktime_t *file, 
  190.                     QUICKTIME_INT16 *output_i, 
  191.                     float *output_f, 
  192.                     long samples, 
  193.                     int track, 
  194.                     int channel)
  195. {
  196.     int result = 0;
  197.     long i;
  198.     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
  199.  
  200.     result = ulaw_get_read_buffer(file, track, samples);
  201.     
  202.     if(output_f) result += ulaw_init_ulawtofloat(file, track);
  203.     if(output_i) result += ulaw_init_ulawtoint16(file, track);
  204.  
  205.     if(!result)
  206.     {
  207.         result = quicktime_read_audio(file, codec->read_buffer, samples, track);
  208.         if(result) result = 0; else result = 1;  /* defeat fread's return */
  209.  
  210. /*printf("quicktime_decode_ulaw %d\n", result); */
  211.         if(!result)
  212.         {
  213.             if(output_f)
  214.             {
  215.                 unsigned char *input = &(codec->read_buffer[channel]);
  216.                 float *output_ptr = output_f;
  217.                 float *output_end = output_f + samples;
  218.                 int step = file->atracks[track].channels;
  219.  
  220.                 while(output_ptr < output_end)
  221.                 {
  222.                     *output_ptr++ = ulaw_bytetofloat(codec, *input);
  223.                     input += step;
  224.                 }
  225.             }
  226.             else
  227.             if(output_i)
  228.             {
  229.                 unsigned char *input = &(codec->read_buffer[channel]);
  230.                 QUICKTIME_INT16 *output_ptr = output_i;
  231.                 QUICKTIME_INT16 *output_end = output_i + samples;
  232.                 int step = file->atracks[track].channels;
  233.  
  234.                 while(output_ptr < output_end)
  235.                 {
  236.                     *output_ptr++ = ulaw_bytetoint16(codec, *input);
  237.                     input += step;
  238.                 }
  239.             }
  240.         }
  241.     }
  242.  
  243.     return result;
  244. }
  245.  
  246. static int quicktime_encode_ulaw(quicktime_t *file, 
  247.                             QUICKTIME_INT16 **input_i, 
  248.                             float **input_f, 
  249.                             int track, 
  250.                             long samples)
  251. {
  252.     int result = 0;
  253.     int channel, step;
  254.     long offset;
  255.     long i;
  256.     quicktime_ulaw_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
  257.  
  258.     result = ulaw_init_int16toulaw(file, track);
  259.     result += ulaw_get_read_buffer(file, track, samples);
  260.  
  261.     if(!result)
  262.     {
  263.         step = file->atracks[track].channels;
  264.  
  265.         if(input_f)
  266.         {
  267.             for(channel = 0; channel < file->atracks[track].channels; channel++)
  268.             {
  269.                 float *input_ptr = input_f[channel];
  270.                 float *input_end = input_f[channel] + samples;
  271.                 unsigned char *output = codec->read_buffer + channel;
  272.  
  273.                 while(input_ptr < input_end)
  274.                 {
  275.                     *output = ulaw_floattobyte(codec, *input_ptr++);
  276.                     output += step;
  277.                 }
  278.             }
  279.         }
  280.         else
  281.         if(input_i)
  282.         {
  283.             for(channel = 0; channel < file->atracks[track].channels; channel++)
  284.             {
  285.                 QUICKTIME_INT16 *input_ptr = input_i[channel];
  286.                 QUICKTIME_INT16 *input_end = input_i[channel] + samples;
  287.                 unsigned char *output = codec->read_buffer + channel;
  288.  
  289.                 while(input_ptr < input_end)
  290.                 {
  291.                     *output = ulaw_int16tobyte(codec, *input_ptr++);
  292.                     output += step;
  293.                 }
  294.             }
  295.         }
  296.  
  297.         offset = quicktime_position(file);
  298.         result = quicktime_write_data(file, codec->read_buffer, samples * file->atracks[track].channels);
  299.         if(result) result = 0; else result = 1; /* defeat fwrite's return */
  300.         quicktime_update_tables(file,
  301.                             file->atracks[track].track, 
  302.                             offset, 
  303.                             file->atracks[track].current_chunk, 
  304.                             file->atracks[track].current_position, 
  305.                             samples, 
  306.                             0);
  307.         file->atracks[track].current_chunk++;        
  308.     }
  309.  
  310.     return result;
  311. }
  312.  
  313.  
  314. void quicktime_init_codec_ulaw(quicktime_audio_map_t *atrack)
  315. {
  316.     quicktime_ulaw_codec_t *codec;
  317.  
  318. /* Init public items */
  319.     ((quicktime_codec_t*)atrack->codec)->priv = calloc(1, sizeof(quicktime_ulaw_codec_t));
  320.     ((quicktime_codec_t*)atrack->codec)->delete_acodec = quicktime_delete_codec_ulaw;
  321.     ((quicktime_codec_t*)atrack->codec)->decode_video = 0;
  322.     ((quicktime_codec_t*)atrack->codec)->encode_video = 0;
  323.     ((quicktime_codec_t*)atrack->codec)->decode_audio = quicktime_decode_ulaw;
  324.     ((quicktime_codec_t*)atrack->codec)->encode_audio = quicktime_encode_ulaw;
  325.  
  326. /* Init private items */
  327.     codec = ((quicktime_codec_t*)atrack->codec)->priv;
  328.     codec->int16toulaw_table = 0;
  329.     codec->ulawtoint16_table = 0;
  330.     codec->ulawtofloat_table = 0;
  331.     codec->read_buffer = 0;
  332.     codec->read_size = 0;
  333. }
  334.