Mercurial > mplayer.hg
annotate libmpcodecs/ad_dk3adpcm.c @ 7964:143d730908ae
here is a somewhat generic equalizer implementation for the X11 vo drivers
using the window's colormap (DirectColor).
this method is using the video card's hardware gamma ramp so it involves
no performance penalties at all.
patch by lucho <lucho@haemimont.bg>
author | arpi |
---|---|
date | Tue, 29 Oct 2002 20:27:47 +0000 |
parents | 1eadce15446c |
children | 9d0b052c4f74 |
rev | line source |
---|---|
5408 | 1 /* |
2 DK3 ADPCM Decoder for MPlayer | |
3 by Mike Melanson | |
4 | |
7191
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
5 "This format number was used by Duck Corp. but not officially |
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
6 registered with Microsoft" |
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
7 |
5408 | 8 This file is responsible for decoding audio data encoded with |
9 Duck Corp's DK3 ADPCM algorithm. Details about the data format | |
10 can be found here: | |
11 http://www.pcisys.net/~melanson/codecs/ | |
12 */ | |
13 | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
14 #include <stdio.h> |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
15 #include <stdlib.h> |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
16 #include <unistd.h> |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
17 |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
18 #include "config.h" |
5408 | 19 #include "bswap.h" |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
20 #include "ad_internal.h" |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
21 |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
22 static ad_info_t info = |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
23 { |
7191
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
24 "Duck Corp. DK3 ADPCM decoder", |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
25 "dk3adpcm", |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
26 "Nick Kurshev", |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
27 "Mike Melanson", |
7191
1eadce15446c
-afm/-vfm help implemenetd, some cosmetics of ad/vd codec names/comments
arpi
parents:
7180
diff
changeset
|
28 "" |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
29 }; |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
30 |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
31 LIBAD_EXTERN(dk3adpcm) |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
32 |
5408 | 33 #define DK3_ADPCM_PREAMBLE_SIZE 16 |
34 | |
35 #define LE_16(x) (le2me_16(*(unsigned short *)(x))) | |
36 #define LE_32(x) (le2me_32(*(unsigned int *)(x))) | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
37 |
5408 | 38 // useful macros |
39 // clamp a number between 0 and 88 | |
40 #define CLAMP_0_TO_88(x) if (x < 0) x = 0; else if (x > 88) x = 88; | |
41 // clamp a number within a signed 16-bit range | |
42 #define CLAMP_S16(x) if (x < -32768) x = -32768; \ | |
43 else if (x > 32767) x = 32767; | |
44 // clamp a number above 16 | |
45 #define CLAMP_ABOVE_16(x) if (x < 16) x = 16; | |
46 // sign extend a 16-bit value | |
47 #define SE_16BIT(x) if (x & 0x8000) x -= 0x10000; | |
48 // sign extend a 4-bit value | |
49 #define SE_4BIT(x) if (x & 0x8) x -= 0x10; | |
50 | |
51 // pertinent tables | |
52 static int adpcm_step[89] = | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
53 { |
5408 | 54 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, |
55 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, | |
56 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, | |
57 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, | |
58 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, | |
59 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, | |
60 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, | |
61 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, | |
62 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 | |
63 }; | |
64 | |
65 static int adpcm_index[16] = | |
66 { | |
67 -1, -1, -1, -1, 2, 4, 6, 8, | |
68 -1, -1, -1, -1, 2, 4, 6, 8 | |
69 }; | |
70 | |
71 static int preinit(sh_audio_t *sh_audio) | |
72 { | |
73 sh_audio->audio_out_minsize = sh_audio->wf->nBlockAlign * 6; | |
74 sh_audio->ds->ss_div = | |
75 (sh_audio->wf->nBlockAlign - DK3_ADPCM_PREAMBLE_SIZE) * 8 / 3; | |
5458 | 76 sh_audio->audio_in_minsize= |
5408 | 77 sh_audio->ds->ss_mul = sh_audio->wf->nBlockAlign; |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
78 return 1; |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
79 } |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
80 |
5408 | 81 static int init(sh_audio_t *sh_audio) |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
82 { |
5408 | 83 sh_audio->channels = sh_audio->wf->nChannels; |
84 sh_audio->samplerate = sh_audio->wf->nSamplesPerSec; | |
85 sh_audio->i_bps = | |
86 (sh_audio->ds->ss_mul * sh_audio->samplerate) / sh_audio->ds->ss_div; | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
87 return 1; |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
88 } |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
89 |
5408 | 90 static void uninit(sh_audio_t *sh_audio) |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
91 { |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
92 } |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
93 |
5481 | 94 static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...) |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
95 { |
5481 | 96 if(cmd==ADCTRL_SKIP_FRAME){ |
97 demux_read_data(sh_audio->ds, sh_audio->a_in_buffer,sh_audio->ds->ss_mul); | |
98 return CONTROL_TRUE; | |
99 } | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
100 return CONTROL_UNKNOWN; |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
101 } |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
102 |
5408 | 103 #define DK3_GET_NEXT_NIBBLE() \ |
104 if (decode_top_nibble_next) \ | |
105 { \ | |
106 nibble = (last_byte >> 4) & 0x0F; \ | |
107 decode_top_nibble_next = 0; \ | |
108 } \ | |
109 else \ | |
110 { \ | |
111 last_byte = input[in_ptr++]; \ | |
112 nibble = last_byte & 0x0F; \ | |
113 decode_top_nibble_next = 1; \ | |
114 } | |
115 | |
116 // note: This decoder assumes the format 0x62 data always comes in | |
117 // stereo flavor | |
118 static int dk3_adpcm_decode_block(unsigned short *output, unsigned char *input, | |
119 int block_size) | |
120 { | |
121 int sum_pred; | |
122 int diff_pred; | |
123 int sum_index; | |
124 int diff_index; | |
125 int diff_channel; | |
126 int in_ptr = 0x10; | |
127 int out_ptr = 0; | |
128 | |
129 unsigned char last_byte = 0; | |
130 unsigned char nibble; | |
131 int decode_top_nibble_next = 0; | |
132 | |
133 // ADPCM work variables | |
134 int sign; | |
135 int delta; | |
136 int step; | |
137 int diff; | |
138 | |
139 sum_pred = LE_16(&input[10]); | |
140 diff_pred = LE_16(&input[12]); | |
141 SE_16BIT(sum_pred); | |
142 SE_16BIT(diff_pred); | |
143 diff_channel = diff_pred; | |
144 sum_index = input[14]; | |
145 diff_index = input[15]; | |
146 | |
147 while (in_ptr < block_size) | |
148 // while (in_ptr < 2048) | |
149 { | |
150 // process the first predictor of the sum channel | |
151 DK3_GET_NEXT_NIBBLE(); | |
152 | |
153 step = adpcm_step[sum_index]; | |
154 | |
155 sign = nibble & 8; | |
156 delta = nibble & 7; | |
157 | |
158 diff = step >> 3; | |
159 if (delta & 4) diff += step; | |
160 if (delta & 2) diff += step >> 1; | |
161 if (delta & 1) diff += step >> 2; | |
162 | |
163 if (sign) | |
164 sum_pred -= diff; | |
165 else | |
166 sum_pred += diff; | |
167 | |
168 CLAMP_S16(sum_pred); | |
169 | |
170 sum_index += adpcm_index[nibble]; | |
171 CLAMP_0_TO_88(sum_index); | |
172 | |
173 // process the diff channel predictor | |
174 DK3_GET_NEXT_NIBBLE(); | |
175 | |
176 step = adpcm_step[diff_index]; | |
177 | |
178 sign = nibble & 8; | |
179 delta = nibble & 7; | |
180 | |
181 diff = step >> 3; | |
182 if (delta & 4) diff += step; | |
183 if (delta & 2) diff += step >> 1; | |
184 if (delta & 1) diff += step >> 2; | |
185 | |
186 if (sign) | |
187 diff_pred -= diff; | |
188 else | |
189 diff_pred += diff; | |
190 | |
191 CLAMP_S16(diff_pred); | |
192 | |
193 diff_index += adpcm_index[nibble]; | |
194 CLAMP_0_TO_88(diff_index); | |
195 | |
196 // output the first pair of stereo PCM samples | |
197 diff_channel = (diff_channel + diff_pred) / 2; | |
198 output[out_ptr++] = sum_pred + diff_channel; | |
199 output[out_ptr++] = sum_pred - diff_channel; | |
200 | |
201 // process the second predictor of the sum channel | |
202 DK3_GET_NEXT_NIBBLE(); | |
203 | |
204 step = adpcm_step[sum_index]; | |
205 | |
206 sign = nibble & 8; | |
207 delta = nibble & 7; | |
208 | |
209 diff = step >> 3; | |
210 if (delta & 4) diff += step; | |
211 if (delta & 2) diff += step >> 1; | |
212 if (delta & 1) diff += step >> 2; | |
213 | |
214 if (sign) | |
215 sum_pred -= diff; | |
216 else | |
217 sum_pred += diff; | |
218 | |
219 CLAMP_S16(sum_pred); | |
220 | |
221 sum_index += adpcm_index[nibble]; | |
222 CLAMP_0_TO_88(sum_index); | |
223 | |
224 // output the second pair of stereo PCM samples | |
225 output[out_ptr++] = sum_pred + diff_channel; | |
226 output[out_ptr++] = sum_pred - diff_channel; | |
227 } | |
228 | |
229 return out_ptr; | |
230 } | |
231 | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
232 static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) |
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
233 { |
5408 | 234 if (demux_read_data(sh_audio->ds, sh_audio->a_in_buffer, |
235 sh_audio->ds->ss_mul) != | |
236 sh_audio->ds->ss_mul) | |
237 return -1; /* EOF */ | |
238 | |
239 return 2 * dk3_adpcm_decode_block( | |
240 (unsigned short*)buf, sh_audio->a_in_buffer, | |
241 sh_audio->wf->nBlockAlign); | |
5340
0f12fb7c1c5d
imported from MPlayerXP, dlopen() hack removed, some bugs fixed, interface functions changed to static, info->author field added
arpi
parents:
diff
changeset
|
242 } |