]> git.sesse.net Git - ffmpeg/blob - libavcodec/adx.c
CAVS decoder by (Stefan Gehrer stefan.gehrer gmx.de)
[ffmpeg] / libavcodec / adx.c
1 /*
2  * ADX ADPCM codecs
3  * Copyright (c) 2001,2003 BERO
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 #include "avcodec.h"
20
21 /**
22  * @file adx.c
23  * SEGA CRI adx codecs.
24  *
25  * Reference documents:
26  * http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html
27  * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/
28  */
29
30 typedef struct {
31     int s1,s2;
32 } PREV;
33
34 typedef struct {
35     PREV prev[2];
36     int header_parsed;
37     unsigned char dec_temp[18*2];
38     unsigned short enc_temp[32*2];
39     int in_temp;
40 } ADXContext;
41
42 //#define    BASEVOL    0x11e0
43 #define    BASEVOL   0x4000
44 #define    SCALE1    0x7298
45 #define    SCALE2    0x3350
46
47 #define    CLIP(s)    if (s>32767) s=32767; else if (s<-32768) s=-32768
48
49 /* 18 bytes <-> 32 samples */
50
51 #ifdef CONFIG_ENCODERS
52 static void adx_encode(unsigned char *adx,const short *wav,PREV *prev)
53 {
54     int scale;
55     int i;
56     int s0,s1,s2,d;
57     int max=0;
58     int min=0;
59     int data[32];
60
61     s1 = prev->s1;
62     s2 = prev->s2;
63     for(i=0;i<32;i++) {
64         s0 = wav[i];
65         d = ((s0<<14) - SCALE1*s1 + SCALE2*s2)/BASEVOL;
66         data[i]=d;
67         if (max<d) max=d;
68         if (min>d) min=d;
69         s2 = s1;
70         s1 = s0;
71     }
72     prev->s1 = s1;
73     prev->s2 = s2;
74
75     /* -8..+7 */
76
77     if (max==0 && min==0) {
78         memset(adx,0,18);
79         return;
80     }
81
82     if (max/7>-min/8) scale = max/7;
83     else scale = -min/8;
84
85     if (scale==0) scale=1;
86
87     adx[0] = scale>>8;
88     adx[1] = scale;
89
90     for(i=0;i<16;i++) {
91         adx[i+2] = ((data[i*2]/scale)<<4) | ((data[i*2+1]/scale)&0xf);
92     }
93 }
94 #endif //CONFIG_ENCODERS
95
96 static void adx_decode(short *out,const unsigned char *in,PREV *prev)
97 {
98     int scale = ((in[0]<<8)|(in[1]));
99     int i;
100     int s0,s1,s2,d;
101
102 //    printf("%x ",scale);
103
104     in+=2;
105     s1 = prev->s1;
106     s2 = prev->s2;
107     for(i=0;i<16;i++) {
108         d = in[i];
109         // d>>=4; if (d&8) d-=16;
110         d = ((signed char)d >> 4);
111         s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14;
112         CLIP(s0);
113         *out++=s0;
114         s2 = s1;
115         s1 = s0;
116
117         d = in[i];
118         //d&=15; if (d&8) d-=16;
119         d = ((signed char)(d<<4) >> 4);
120         s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14;
121         CLIP(s0);
122         *out++=s0;
123         s2 = s1;
124         s1 = s0;
125     }
126     prev->s1 = s1;
127     prev->s2 = s2;
128
129 }
130
131 static void adx_decode_stereo(short *out,const unsigned char *in,PREV *prev)
132 {
133     short tmp[32*2];
134     int i;
135
136     adx_decode(tmp   ,in   ,prev);
137     adx_decode(tmp+32,in+18,prev+1);
138     for(i=0;i<32;i++) {
139         out[i*2]   = tmp[i];
140         out[i*2+1] = tmp[i+32];
141     }
142 }
143
144 #ifdef CONFIG_ENCODERS
145
146 static void write_long(unsigned char *p,uint32_t v)
147 {
148     p[0] = v>>24;
149     p[1] = v>>16;
150     p[2] = v>>8;
151     p[3] = v;
152 }
153
154 static int adx_encode_header(AVCodecContext *avctx,unsigned char *buf,size_t bufsize)
155 {
156 #if 0
157     struct {
158         uint32_t offset; /* 0x80000000 + sample start - 4 */
159         unsigned char unknown1[3]; /* 03 12 04 */
160         unsigned char channel; /* 1 or 2 */
161         uint32_t freq;
162         uint32_t size;
163         uint32_t unknown2; /* 01 f4 03 00 */
164         uint32_t unknown3; /* 00 00 00 00 */
165         uint32_t unknown4; /* 00 00 00 00 */
166
167     /* if loop
168         unknown3 00 15 00 01
169         unknown4 00 00 00 01
170         long loop_start_sample;
171         long loop_start_byte;
172         long loop_end_sample;
173         long loop_end_byte;
174         long
175     */
176     } adxhdr; /* big endian */
177     /* offset-6 "(c)CRI" */
178 #endif
179     write_long(buf+0x00,0x80000000|0x20);
180     write_long(buf+0x04,0x03120400|avctx->channels);
181     write_long(buf+0x08,avctx->sample_rate);
182     write_long(buf+0x0c,0); /* FIXME: set after */
183     write_long(buf+0x10,0x01040300);
184     write_long(buf+0x14,0x00000000);
185     write_long(buf+0x18,0x00000000);
186     memcpy(buf+0x1c,"\0\0(c)CRI",8);
187     return 0x20+4;
188 }
189
190 static int adx_decode_init(AVCodecContext *avctx);
191 static int adx_encode_init(AVCodecContext *avctx)
192 {
193     if (avctx->channels > 2)
194         return -1; /* only stereo or mono =) */
195     avctx->frame_size = 32;
196
197     avctx->coded_frame= avcodec_alloc_frame();
198     avctx->coded_frame->key_frame= 1;
199
200 //    avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32;
201
202     av_log(avctx, AV_LOG_DEBUG, "adx encode init\n");
203     adx_decode_init(avctx);
204
205     return 0;
206 }
207
208 static int adx_encode_close(AVCodecContext *avctx)
209 {
210     av_freep(&avctx->coded_frame);
211
212     return 0;
213 }
214
215 static int adx_encode_frame(AVCodecContext *avctx,
216                 uint8_t *frame, int buf_size, void *data)
217 {
218     ADXContext *c = avctx->priv_data;
219     const short *samples = data;
220     unsigned char *dst = frame;
221     int rest = avctx->frame_size;
222
223 /*
224     input data size =
225     ffmpeg.c: do_audio_out()
226     frame_bytes = enc->frame_size * 2 * enc->channels;
227 */
228
229 //    printf("sz=%d ",buf_size); fflush(stdout);
230     if (!c->header_parsed) {
231         int hdrsize = adx_encode_header(avctx,dst,buf_size);
232         dst+=hdrsize;
233         c->header_parsed = 1;
234     }
235
236     if (avctx->channels==1) {
237         while(rest>=32) {
238             adx_encode(dst,samples,c->prev);
239             dst+=18;
240             samples+=32;
241             rest-=32;
242         }
243     } else {
244         while(rest>=32*2) {
245             short tmpbuf[32*2];
246             int i;
247
248             for(i=0;i<32;i++) {
249                 tmpbuf[i] = samples[i*2];
250                 tmpbuf[i+32] = samples[i*2+1];
251             }
252
253             adx_encode(dst,tmpbuf,c->prev);
254             adx_encode(dst+18,tmpbuf+32,c->prev+1);
255             dst+=18*2;
256             samples+=32*2;
257             rest-=32*2;
258         }
259     }
260     return dst-frame;
261 }
262
263 #endif //CONFIG_ENCODERS
264
265 static uint32_t read_long(const unsigned char *p)
266 {
267     return (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3];
268 }
269
270 static int is_adx(const unsigned char *buf,size_t bufsize)
271 {
272     int    offset;
273
274     if (buf[0]!=0x80) return 0;
275     offset = (read_long(buf)^0x80000000)+4;
276     if (bufsize<offset || memcmp(buf+offset-6,"(c)CRI",6)) return 0;
277     return offset;
278 }
279
280 /* return data offset or 6 */
281 static int adx_decode_header(AVCodecContext *avctx,const unsigned char *buf,size_t bufsize)
282 {
283     int offset;
284     int channels,freq,size;
285
286     offset = is_adx(buf,bufsize);
287     if (offset==0) return 0;
288
289     channels = buf[7];
290     freq = read_long(buf+8);
291     size = read_long(buf+12);
292
293 //    printf("freq=%d ch=%d\n",freq,channels);
294
295     avctx->sample_rate = freq;
296     avctx->channels = channels;
297     avctx->bit_rate = freq*channels*18*8/32;
298 //    avctx->frame_size = 18*channels;
299
300     return offset;
301 }
302
303 static int adx_decode_init(AVCodecContext * avctx)
304 {
305     ADXContext *c = avctx->priv_data;
306
307 //    printf("adx_decode_init\n"); fflush(stdout);
308     c->prev[0].s1 = 0;
309     c->prev[0].s2 = 0;
310     c->prev[1].s1 = 0;
311     c->prev[1].s2 = 0;
312     c->header_parsed = 0;
313     c->in_temp = 0;
314     return 0;
315 }
316
317 #if 0
318 static void dump(unsigned char *buf,size_t len)
319 {
320     int i;
321     for(i=0;i<len;i++) {
322         if ((i&15)==0) av_log(NULL, AV_LOG_DEBUG, "%04x  ",i);
323         av_log(NULL, AV_LOG_DEBUG, "%02x ",buf[i]);
324         if ((i&15)==15) av_log(NULL, AV_LOG_DEBUG, "\n");
325     }
326     av_log(NULL, AV_LOG_ERROR, "\n");
327 }
328 #endif
329
330 static int adx_decode_frame(AVCodecContext *avctx,
331                 void *data, int *data_size,
332                 uint8_t *buf0, int buf_size)
333 {
334     ADXContext *c = avctx->priv_data;
335     short *samples = data;
336     const uint8_t *buf = buf0;
337     int rest = buf_size;
338
339     if (!c->header_parsed) {
340         int hdrsize = adx_decode_header(avctx,buf,rest);
341         if (hdrsize==0) return -1;
342         c->header_parsed = 1;
343         buf  += hdrsize;
344         rest -= hdrsize;
345     }
346
347     if (c->in_temp) {
348         int copysize = 18*avctx->channels - c->in_temp;
349         memcpy(c->dec_temp+c->in_temp,buf,copysize);
350         rest -= copysize;
351         buf  += copysize;
352         if (avctx->channels==1) {
353             adx_decode(samples,c->dec_temp,c->prev);
354             samples += 32;
355         } else {
356             adx_decode_stereo(samples,c->dec_temp,c->prev);
357             samples += 32*2;
358         }
359     }
360     //
361     if (avctx->channels==1) {
362         while(rest>=18) {
363             adx_decode(samples,buf,c->prev);
364             rest-=18;
365             buf+=18;
366             samples+=32;
367         }
368     } else {
369         while(rest>=18*2) {
370             adx_decode_stereo(samples,buf,c->prev);
371             rest-=18*2;
372             buf+=18*2;
373             samples+=32*2;
374         }
375     }
376     //
377     c->in_temp = rest;
378     if (rest) {
379         memcpy(c->dec_temp,buf,rest);
380         buf+=rest;
381     }
382     *data_size = (uint8_t*)samples - (uint8_t*)data;
383 //    printf("%d:%d ",buf-buf0,*data_size); fflush(stdout);
384     return buf-buf0;
385 }
386
387 #ifdef CONFIG_ENCODERS
388 AVCodec adx_adpcm_encoder = {
389     "adx_adpcm",
390     CODEC_TYPE_AUDIO,
391     CODEC_ID_ADPCM_ADX,
392     sizeof(ADXContext),
393     adx_encode_init,
394     adx_encode_frame,
395     adx_encode_close,
396     NULL,
397 };
398 #endif //CONFIG_ENCODERS
399
400 AVCodec adx_adpcm_decoder = {
401     "adx_adpcm",
402     CODEC_TYPE_AUDIO,
403     CODEC_ID_ADPCM_ADX,
404     sizeof(ADXContext),
405     adx_decode_init,
406     NULL,
407     NULL,
408     adx_decode_frame,
409 };
410