"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/twos.c" (20 Jan 2008, 8105 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 "twos.h"
    4 
    5 /* =================================== private for twos */
    6 
    7 
    8 typedef struct
    9 {
   10     char *work_buffer;
   11     long buffer_size;
   12 } quicktime_twos_codec_t;
   13 
   14 static int byte_order(void)
   15 {                /* 1 if little endian */
   16     int16_t byteordertest;
   17     int byteorder;
   18 
   19     byteordertest = 0x0001;
   20     byteorder = *((unsigned char *)&byteordertest);
   21     return byteorder;
   22 }
   23 
   24 static int get_work_buffer(quicktime_t *file, int track, long bytes)
   25 {
   26     quicktime_twos_codec_t *codec = ((quicktime_codec_t*)file->atracks[track].codec)->priv;
   27 
   28     if(codec->work_buffer && codec->buffer_size != bytes)
   29     {
   30         free(codec->work_buffer);
   31         codec->work_buffer = 0;
   32     }
   33     
   34     if(!codec->work_buffer) 
   35     {
   36         codec->buffer_size = bytes;
   37         if(!(codec->work_buffer = malloc(bytes))) return 1;
   38     }
   39     return 0;
   40 }
   41 
   42 /* =================================== public for twos */
   43 
   44 static int delete_codec(quicktime_audio_map_t *atrack)
   45 {
   46     quicktime_twos_codec_t *codec = ((quicktime_codec_t*)atrack->codec)->priv;
   47 
   48     if(codec->work_buffer) free(codec->work_buffer);
   49     codec->work_buffer = 0;
   50     codec->buffer_size = 0;
   51     free(codec);
   52     return 0;
   53 }
   54 
   55 static int swap_bytes(char *buffer, long samples, int channels, int bits)
   56 {
   57     long i = 0;
   58     char byte1, byte2, byte3;
   59     char *buffer1, *buffer2, *buffer3;
   60 
   61     if(!byte_order()) return 0;
   62 
   63     switch(bits)
   64     {
   65         case 8:
   66             break;
   67 
   68         case 16:
   69             buffer1 = buffer;
   70             buffer2 = buffer + 1;
   71             while(i < samples * channels * 2)
   72             {
   73                 byte1 = buffer2[i];
   74                 buffer2[i] = buffer1[i];
   75                 buffer1[i] = byte1;
   76                 i += 2;
   77             }
   78             break;
   79 
   80         case 24:
   81             buffer1 = buffer;
   82             buffer2 = buffer + 2;
   83             while(i < samples * channels * 3)
   84             {
   85                 byte1 = buffer2[i];
   86                 buffer2[i] = buffer1[i];
   87                 buffer1[i] = byte1;
   88                 i += 3;
   89             }
   90             break;
   91 
   92         default:
   93             break;
   94     }
   95     return 0;
   96 }
   97 
   98 
   99 static int decode(quicktime_t *file, 
  100                     int16_t *output_i, 
  101                     float *output_f, 
  102                     long samples, 
  103                     int track, 
  104                     int channel)
  105 {
  106     int result = 0;
  107     long i, j;
  108     quicktime_audio_map_t *track_map = &(file->atracks[track]);
  109     quicktime_twos_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
  110     int step = track_map->channels * quicktime_audio_bits(file, track) / 8;
  111 
  112     get_work_buffer(file, track, samples * step);
  113 /*
  114  * printf("decode 1 %d\n", quicktime_audio_bits(file, track));
  115  * sleep(1);
  116  */
  117     result = !quicktime_read_audio(file, codec->work_buffer, samples, track);
  118 
  119 
  120 /* Undo increment since this is done in codecs.c */
  121     track_map->current_position -= samples;
  122 
  123 /* Handle AVI byte order */
  124     if(file->use_avi)
  125         swap_bytes(codec->work_buffer, 
  126             samples, 
  127             track_map->channels, 
  128             quicktime_audio_bits(file, track));
  129 
  130     switch(quicktime_audio_bits(file, track))
  131     {
  132         case 8:
  133             if(output_i && !result)
  134             {
  135                 for(i = 0, j = channel; i < samples; i++)
  136                 {
  137                     if(file->use_avi)
  138                         output_i[i] = (int16_t)(((unsigned char)codec->work_buffer[j]) << 8) - 
  139                             0x7fff;
  140                     else
  141                         output_i[i] = ((int16_t)codec->work_buffer[j]) << 8;
  142                     j += step;
  143                 }
  144             }
  145             else
  146             if(output_f && !result)
  147             {
  148                 for(i = 0, j = channel; i < samples; i++)
  149                 {
  150                     if(file->use_avi)
  151                         output_f[i] = ((float)((unsigned char)codec->work_buffer[j]) - 0x7f) / 
  152                             0x7f;
  153                     else
  154                         output_f[i] = ((float)codec->work_buffer[j]) / 0x7f;
  155                     j += step;
  156                 }
  157             }
  158             break;
  159         
  160         case 16:
  161             if(output_i && !result)
  162             {
  163                 for(i = 0, j = channel * 2; i < samples; i++)
  164                 {
  165                     output_i[i] = ((int16_t)codec->work_buffer[j]) << 8 |
  166                                     ((unsigned char)codec->work_buffer[j + 1]);
  167                     j += step;
  168                 }
  169             }
  170             else
  171             if(output_f && !result)
  172             {
  173                 for(i = 0, j = channel * 2; i < samples; i++)
  174                 {
  175                     output_f[i] = (float)((((int16_t)codec->work_buffer[j]) << 8) |
  176                                     ((unsigned char)codec->work_buffer[j + 1])) / 0x7fff;
  177                     j += step;
  178                 }
  179             }
  180             break;
  181         
  182         case 24:
  183             if(output_i && !result)
  184             {
  185                 for(i = 0, j = channel * 3; i < samples; i++)
  186                 {
  187                     output_i[i] = (((int16_t)codec->work_buffer[j]) << 8) | 
  188                                     ((unsigned char)codec->work_buffer[j + 1]);
  189                     j += step;
  190                 }
  191             }
  192             else
  193             if(output_f && !result)
  194             {
  195                 for(i = 0, j = channel * 3; i < samples; i++)
  196                 {
  197                     output_f[i] = (float)((((int)codec->work_buffer[j]) << 16) | 
  198                                     (((unsigned char)codec->work_buffer[j + 1]) << 8) |
  199                                     ((unsigned char)codec->work_buffer[j + 2])) / 0x7fffff;
  200                     j += step;
  201                 }
  202             }
  203             break;
  204         
  205         default:
  206             break;
  207     }
  208 
  209 
  210     return result;
  211 }
  212 
  213 #define CLAMP(x, y, z) ((x) = ((x) <  (y) ? (y) : ((x) > (z) ? (z) : (x))))
  214 
  215 static int encode(quicktime_t *file, 
  216                             int16_t **input_i, 
  217                             float **input_f, 
  218                             int track, 
  219                             long samples)
  220 {
  221     int result = 0;
  222     long i, j, offset;
  223     quicktime_audio_map_t *track_map = &(file->atracks[track]);
  224     quicktime_twos_codec_t *codec = ((quicktime_codec_t*)track_map->codec)->priv;
  225     int step = track_map->channels * quicktime_audio_bits(file, track) / 8;
  226     int sample;
  227     float sample_f;
  228 
  229     get_work_buffer(file, track, samples * step);
  230 
  231     if(input_i)
  232     {
  233         for(i = 0; i < track_map->channels; i++)
  234         {
  235             switch(quicktime_audio_bits(file, track))
  236             {
  237                 case 8:
  238                     for(j = 0; j < samples; j++)
  239                     {
  240                         sample = input_i[i][j] >> 8;
  241                         codec->work_buffer[j * step + i] = sample;
  242                     }
  243                     break;
  244                 case 16:
  245                     for(j = 0; j < samples; j++)
  246                     {
  247                         sample = input_i[i][j];
  248                         codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8;
  249                         codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff;
  250                     }
  251                     break;
  252                 case 24:
  253                     for(j = 0; j < samples; j++)
  254                     {
  255                         sample = input_i[i][j];
  256                         codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff00) >> 8;
  257                         codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff);
  258                         codec->work_buffer[j * step + i * 3 + 2] = 0;
  259                     }
  260                     break;
  261             }
  262         }
  263     }
  264     else
  265     {
  266         for(i = 0; i < track_map->channels; i++)
  267         {
  268             switch(quicktime_audio_bits(file, track))
  269             {
  270                 case 8:
  271                     for(j = 0; j < samples; j++)
  272                     {
  273                         sample_f = input_f[i][j];
  274                         if(sample_f < 0)
  275                             sample = (int)(sample_f * 0x7f - 0.5);
  276                         else
  277                             sample = (int)(sample_f * 0x7f + 0.5);
  278                         CLAMP(sample, -0x7f, 0x7f);
  279                         codec->work_buffer[j * step + i] = sample;
  280                     }
  281                     break;
  282                 case 16:
  283                     for(j = 0; j < samples; j++)
  284                     {
  285                         sample_f = input_f[i][j];
  286                         if(sample_f < 0)
  287                             sample = (int)(sample_f * 0x7fff - 0.5);
  288                         else
  289                             sample = (int)(sample_f * 0x7fff + 0.5);
  290                         CLAMP(sample, -0x7fff, 0x7fff);
  291                         codec->work_buffer[j * step + i * 2] = ((unsigned int)sample & 0xff00) >> 8;
  292                         codec->work_buffer[j * step + i * 2 + 1] = ((unsigned int)sample) & 0xff;
  293                     }
  294                     break;
  295                 case 24:
  296                     for(j = 0; j < samples; j++)
  297                     {
  298                         sample_f = input_f[i][j];
  299                         if(sample_f < 0)
  300                             sample = (int)(sample_f * 0x7fffff - 0.5);
  301                         else
  302                             sample = (int)(sample_f * 0x7fffff + 0.5);
  303                         CLAMP(sample, -0x7fffff, 0x7fffff);
  304                         codec->work_buffer[j * step + i * 3] = ((unsigned int)sample & 0xff0000) >> 16;
  305                         codec->work_buffer[j * step + i * 3 + 1] = ((unsigned int)sample & 0xff00) >> 8;
  306                         codec->work_buffer[j * step + i * 3 + 2] = ((unsigned int)sample) & 0xff;
  307                     }
  308                     break;
  309             }
  310         }
  311     }
  312 
  313 /* Handle AVI byte order */
  314     if(file->use_avi)
  315         swap_bytes(codec->work_buffer, 
  316             samples, 
  317             track_map->channels, 
  318             quicktime_audio_bits(file, track));
  319 
  320     result = quicktime_write_audio(file, codec->work_buffer, samples, track);
  321 
  322     return result;
  323 }
  324 
  325 void quicktime_init_codec_twos(quicktime_audio_map_t *atrack)
  326 {
  327     quicktime_twos_codec_t *codec;
  328     quicktime_codec_t *codec_base = (quicktime_codec_t*)atrack->codec;
  329 
  330 /* Init public items */
  331     codec_base->delete_acodec = delete_codec;
  332     codec_base->decode_audio = decode;
  333     codec_base->encode_audio = encode;
  334     codec_base->fourcc = QUICKTIME_TWOS;
  335     codec_base->title = "Twos complement";
  336     codec_base->desc = "Twos complement";
  337     codec_base->wav_id = 0x01;
  338 
  339 /* Init private items */
  340     codec = codec_base->priv = calloc(1, sizeof(quicktime_twos_codec_t));
  341     codec->work_buffer = 0;
  342     codec->buffer_size = 0;
  343 }