00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "avcodec.h"
00020
00030 typedef struct {
00031 } WSSNDContext;
00032
00033 static const char ws_adpcm_2bit[] = { -2, -1, 0, 1};
00034 static const char ws_adpcm_4bit[] = {
00035 -9, -8, -6, -5, -4, -3, -2, -1,
00036 0, 1, 2, 3, 4, 5, 6, 8 };
00037
00038 #define CLIP8(a) if(a>127)a=127;if(a<-128)a=-128;
00039
00040 static int ws_snd_decode_init(AVCodecContext * avctx)
00041 {
00042
00043
00044 return 0;
00045 }
00046
00047 static int ws_snd_decode_frame(AVCodecContext *avctx,
00048 void *data, int *data_size,
00049 uint8_t *buf, int buf_size)
00050 {
00051
00052
00053 int in_size, out_size;
00054 int sample = 0;
00055 int i;
00056 short *samples = data;
00057
00058 if (!buf_size)
00059 return 0;
00060
00061 out_size = LE_16(&buf[0]);
00062 *data_size = out_size * 2;
00063 in_size = LE_16(&buf[2]);
00064 buf += 4;
00065
00066 if (in_size == out_size) {
00067 for (i = 0; i < out_size; i++)
00068 *samples++ = (*buf++ - 0x80) << 8;
00069 return buf_size;
00070 }
00071
00072 while (out_size > 0) {
00073 int code;
00074 uint8_t count;
00075 code = (*buf) >> 6;
00076 count = (*buf) & 0x3F;
00077 buf++;
00078 switch(code) {
00079 case 0:
00080 for (count++; count > 0; count--) {
00081 code = *buf++;
00082 sample += ws_adpcm_2bit[code & 0x3];
00083 CLIP8(sample);
00084 *samples++ = sample << 8;
00085 sample += ws_adpcm_2bit[(code >> 2) & 0x3];
00086 CLIP8(sample);
00087 *samples++ = sample << 8;
00088 sample += ws_adpcm_2bit[(code >> 4) & 0x3];
00089 CLIP8(sample);
00090 *samples++ = sample << 8;
00091 sample += ws_adpcm_2bit[(code >> 6) & 0x3];
00092 CLIP8(sample);
00093 *samples++ = sample << 8;
00094 out_size -= 4;
00095 }
00096 break;
00097 case 1:
00098 for (count++; count > 0; count--) {
00099 code = *buf++;
00100 sample += ws_adpcm_4bit[code & 0xF];
00101 CLIP8(sample);
00102 *samples++ = sample << 8;
00103 sample += ws_adpcm_4bit[code >> 4];
00104 CLIP8(sample);
00105 *samples++ = sample << 8;
00106 out_size -= 2;
00107 }
00108 break;
00109 case 2:
00110 if (count & 0x20) {
00111 char t;
00112 t = count;
00113 t <<= 3;
00114 sample += t >> 3;
00115 *samples++ = sample << 8;
00116 out_size--;
00117 } else {
00118 for (count++; count > 0; count--) {
00119 *samples++ = (*buf++ - 0x80) << 8;
00120 out_size--;
00121 }
00122 sample = buf[-1] - 0x80;
00123 }
00124 break;
00125 default:
00126 for(count++; count > 0; count--) {
00127 *samples++ = sample << 8;
00128 out_size--;
00129 }
00130 }
00131 }
00132
00133 return buf_size;
00134 }
00135
00136 AVCodec ws_snd1_decoder = {
00137 "ws_snd1",
00138 CODEC_TYPE_AUDIO,
00139 CODEC_ID_WESTWOOD_SND1,
00140 sizeof(WSSNDContext),
00141 ws_snd_decode_init,
00142 NULL,
00143 NULL,
00144 ws_snd_decode_frame,
00145 };