~ubuntu-dev/mplayer/upstream-ubuntu

« back to all changes in this revision

Viewing changes to libavcodec/adx.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:45:33 UTC
  • Revision ID: siretart@tauware.de-20060708084533-dbc155bde7122e78
imported mplayer_0.99+1.0pre7try2+cvs20060117

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
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