Mercurial > libavcodec.hg
comparison adxdec.c @ 5867:67e62f3367e0 libavcodec
move adx.c to adxdec.c
author | aurel |
---|---|
date | Thu, 01 Nov 2007 18:40:42 +0000 |
parents | adx.c@b1b3dd3324ae |
children | a0797336b964 |
comparison
equal
deleted
inserted
replaced
5866:b1b3dd3324ae | 5867:67e62f3367e0 |
---|---|
1 /* | |
2 * ADX ADPCM codecs | |
3 * Copyright (c) 2001,2003 BERO | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 #include "avcodec.h" | |
22 #include "adx.h" | |
23 | |
24 /** | |
25 * @file adx.c | |
26 * SEGA CRI adx codecs. | |
27 * | |
28 * Reference documents: | |
29 * http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html | |
30 * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/ | |
31 */ | |
32 | |
33 /* 18 bytes <-> 32 samples */ | |
34 | |
35 static void adx_decode(short *out,const unsigned char *in,PREV *prev) | |
36 { | |
37 int scale = AV_RB16(in); | |
38 int i; | |
39 int s0,s1,s2,d; | |
40 | |
41 // printf("%x ",scale); | |
42 | |
43 in+=2; | |
44 s1 = prev->s1; | |
45 s2 = prev->s2; | |
46 for(i=0;i<16;i++) { | |
47 d = in[i]; | |
48 // d>>=4; if (d&8) d-=16; | |
49 d = ((signed char)d >> 4); | |
50 s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; | |
51 s2 = s1; | |
52 s1 = av_clip_int16(s0); | |
53 *out++=s1; | |
54 | |
55 d = in[i]; | |
56 //d&=15; if (d&8) d-=16; | |
57 d = ((signed char)(d<<4) >> 4); | |
58 s0 = (BASEVOL*d*scale + SCALE1*s1 - SCALE2*s2)>>14; | |
59 s2 = s1; | |
60 s1 = av_clip_int16(s0); | |
61 *out++=s1; | |
62 } | |
63 prev->s1 = s1; | |
64 prev->s2 = s2; | |
65 | |
66 } | |
67 | |
68 static void adx_decode_stereo(short *out,const unsigned char *in,PREV *prev) | |
69 { | |
70 short tmp[32*2]; | |
71 int i; | |
72 | |
73 adx_decode(tmp ,in ,prev); | |
74 adx_decode(tmp+32,in+18,prev+1); | |
75 for(i=0;i<32;i++) { | |
76 out[i*2] = tmp[i]; | |
77 out[i*2+1] = tmp[i+32]; | |
78 } | |
79 } | |
80 | |
81 /* return data offset or 0 */ | |
82 static int adx_decode_header(AVCodecContext *avctx,const unsigned char *buf,size_t bufsize) | |
83 { | |
84 int offset; | |
85 | |
86 if (buf[0]!=0x80) return 0; | |
87 offset = (AV_RB32(buf)^0x80000000)+4; | |
88 if (bufsize<offset || memcmp(buf+offset-6,"(c)CRI",6)) return 0; | |
89 | |
90 avctx->channels = buf[7]; | |
91 avctx->sample_rate = AV_RB32(buf+8); | |
92 avctx->bit_rate = avctx->sample_rate*avctx->channels*18*8/32; | |
93 | |
94 return offset; | |
95 } | |
96 | |
97 static int adx_decode_frame(AVCodecContext *avctx, | |
98 void *data, int *data_size, | |
99 uint8_t *buf0, int buf_size) | |
100 { | |
101 ADXContext *c = avctx->priv_data; | |
102 short *samples = data; | |
103 const uint8_t *buf = buf0; | |
104 int rest = buf_size; | |
105 | |
106 if (!c->header_parsed) { | |
107 int hdrsize = adx_decode_header(avctx,buf,rest); | |
108 if (hdrsize==0) return -1; | |
109 c->header_parsed = 1; | |
110 buf += hdrsize; | |
111 rest -= hdrsize; | |
112 } | |
113 | |
114 /* 18 bytes of data are expanded into 32*2 bytes of audio, | |
115 so guard against buffer overflows */ | |
116 if(rest/18 > *data_size/64) | |
117 rest = (*data_size/64) * 18; | |
118 | |
119 if (c->in_temp) { | |
120 int copysize = 18*avctx->channels - c->in_temp; | |
121 memcpy(c->dec_temp+c->in_temp,buf,copysize); | |
122 rest -= copysize; | |
123 buf += copysize; | |
124 if (avctx->channels==1) { | |
125 adx_decode(samples,c->dec_temp,c->prev); | |
126 samples += 32; | |
127 } else { | |
128 adx_decode_stereo(samples,c->dec_temp,c->prev); | |
129 samples += 32*2; | |
130 } | |
131 } | |
132 // | |
133 if (avctx->channels==1) { | |
134 while(rest>=18) { | |
135 adx_decode(samples,buf,c->prev); | |
136 rest-=18; | |
137 buf+=18; | |
138 samples+=32; | |
139 } | |
140 } else { | |
141 while(rest>=18*2) { | |
142 adx_decode_stereo(samples,buf,c->prev); | |
143 rest-=18*2; | |
144 buf+=18*2; | |
145 samples+=32*2; | |
146 } | |
147 } | |
148 // | |
149 c->in_temp = rest; | |
150 if (rest) { | |
151 memcpy(c->dec_temp,buf,rest); | |
152 buf+=rest; | |
153 } | |
154 *data_size = (uint8_t*)samples - (uint8_t*)data; | |
155 // printf("%d:%d ",buf-buf0,*data_size); fflush(stdout); | |
156 return buf-buf0; | |
157 } | |
158 | |
159 AVCodec adpcm_adx_decoder = { | |
160 "adpcm_adx", | |
161 CODEC_TYPE_AUDIO, | |
162 CODEC_ID_ADPCM_ADX, | |
163 sizeof(ADXContext), | |
164 NULL, | |
165 NULL, | |
166 NULL, | |
167 adx_decode_frame, | |
168 }; | |
169 |