ws-snd1.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:4k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*
  2.  * Westwood SNDx codecs
  3.  * Copyright (c) 2005 Konstantin Shishkov
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19. #include "avcodec.h"
  20. /**
  21.  * @file ws-snd.c
  22.  * Westwood SNDx codecs.
  23.  *
  24.  * Reference documents about VQA format and its audio codecs
  25.  * can be found here:
  26.  * http://www.multimedia.cx
  27.  */
  28. typedef struct {
  29. } WSSNDContext;
  30. static const char ws_adpcm_2bit[] = { -2, -1, 0, 1};
  31. static const char ws_adpcm_4bit[] = {
  32.     -9, -8, -6, -5, -4, -3, -2, -1,
  33.      0,  1,  2,  3,  4,  5,  6,  8 };
  34. #define CLIP8(a) if(a>127)a=127;if(a<-128)a=-128;
  35. static int ws_snd_decode_init(AVCodecContext * avctx)
  36. {
  37. //    WSSNDContext *c = avctx->priv_data;
  38.     
  39.     return 0;
  40. }
  41. static int ws_snd_decode_frame(AVCodecContext *avctx,
  42.                 void *data, int *data_size,
  43.                 uint8_t *buf, int buf_size)
  44. {
  45. //    WSSNDContext *c = avctx->priv_data;
  46.     
  47.     int in_size, out_size;
  48.     int sample = 0;
  49.     int i;
  50.     short *samples = data;
  51.     
  52.     if (!buf_size)
  53.         return 0;
  54.     out_size = LE_16(&buf[0]);
  55.     *data_size = out_size * 2;
  56.     in_size = LE_16(&buf[2]);
  57.     buf += 4;
  58.     
  59.     if (in_size == out_size) {
  60.         for (i = 0; i < out_size; i++)
  61.             *samples++ = (*buf++ - 0x80) << 8;
  62.         return buf_size;
  63.     }
  64.     
  65.     while (out_size > 0) {
  66.         int code;
  67.         uint8_t count;
  68.         code = (*buf) >> 6;
  69.         count = (*buf) & 0x3F;
  70.         buf++;
  71.         switch(code) {
  72.         case 0: /* ADPCM 2-bit */
  73.             for (count++; count > 0; count--) {
  74.                 code = *buf++;
  75.                 sample += ws_adpcm_2bit[code & 0x3];
  76.                 CLIP8(sample);
  77.                 *samples++ = sample << 8;
  78.                 sample += ws_adpcm_2bit[(code >> 2) & 0x3];
  79.                 CLIP8(sample);
  80.                 *samples++ = sample << 8;
  81.                 sample += ws_adpcm_2bit[(code >> 4) & 0x3];
  82.                 CLIP8(sample);
  83.                 *samples++ = sample << 8;
  84.                 sample += ws_adpcm_2bit[(code >> 6) & 0x3];
  85.                 CLIP8(sample);
  86.                 *samples++ = sample << 8;
  87.                 out_size -= 4;
  88.             }
  89.             break;
  90.         case 1: /* ADPCM 4-bit */
  91.             for (count++; count > 0; count--) {
  92.                 code = *buf++;
  93.                 sample += ws_adpcm_4bit[code & 0xF];
  94.                 CLIP8(sample);
  95.                 *samples++ = sample << 8;
  96.                 sample += ws_adpcm_4bit[code >> 4];
  97.                 CLIP8(sample);
  98.                 *samples++ = sample << 8;
  99.                 out_size -= 2;
  100.             }
  101.             break;
  102.         case 2: /* no compression */
  103.             if (count & 0x20) { /* big delta */
  104.                 char t;
  105.                 t = count;
  106.                 t <<= 3;
  107.                 sample += t >> 3;
  108.                 *samples++ = sample << 8;
  109.                 out_size--;
  110.             } else { /* copy */
  111.                 for (count++; count > 0; count--) {
  112.                     *samples++ = (*buf++ - 0x80) << 8;
  113.                     out_size--;
  114.                 }
  115.                 sample = buf[-1] - 0x80;
  116.             }
  117.             break;
  118.         default: /* run */
  119.             for(count++; count > 0; count--) {
  120.                 *samples++ = sample << 8;
  121.                 out_size--;
  122.             }
  123.         }
  124.     }
  125.     
  126.     return buf_size;
  127. }
  128. AVCodec ws_snd1_decoder = {
  129.     "ws_snd1",
  130.     CODEC_TYPE_AUDIO,
  131.     CODEC_ID_WESTWOOD_SND1,
  132.     sizeof(WSSNDContext),
  133.     ws_snd_decode_init,
  134.     NULL,
  135.     NULL,
  136.     ws_snd_decode_frame,
  137. };