1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2006 Adam Gashlin (hcs)
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
17 ****************************************************************************/
24 /* Maximum number of bytes to process in one iteration */
25 #define WAV_CHUNK_SIZE (1024*2)
27 /* Volume for ADX decoder */
28 #define BASE_VOL 0x2000
30 /* Number of times to loop looped tracks when repeat is disabled */
33 /* Length of fade-out for looped tracks (milliseconds) */
34 #define FADE_LENGTH 10000L
36 static int16_t samples
[WAV_CHUNK_SIZE
] IBSS_ATTR
;
38 /* this is the codec entry point */
39 enum codec_status
codec_main(void)
42 int sampleswritten
, i
;
44 int32_t ch1_1
, ch1_2
, ch2_1
, ch2_2
; /* ADPCM history */
46 int endofstream
; /* end of stream flag */
47 uint32_t avgbytespersec
;
48 int looping
; /* looping flag */
49 int loop_count
; /* number of loops done so far */
50 int fade_count
; /* countdown for fadeout */
51 int fade_frames
; /* length of fade in frames */
52 off_t start_adr
, end_adr
; /* loop points */
53 off_t chanstart
, bufoff
;
55 /* Generic codec initialisation */
56 /* we only render 16 bits */
57 ci
->configure(DSP_SET_SAMPLE_DEPTH
, 16);
58 /*ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, 1024*256);*/
61 DEBUGF("ADX: next_track\n");
65 DEBUGF("ADX: after init\n");
68 ch1_1
=ch1_2
=ch2_1
=ch2_2
=0;
70 /* wait for track info to load */
71 while (!*ci
->taginfo_ready
&& !ci
->stop_codec
)
74 codec_set_replaygain(ci
->id3
);
76 /* Read the entire file (or as much as possible) */
77 DEBUGF("ADX: request initial buffer\n");
78 ci
->configure(CODEC_SET_FILEBUF_WATERMARK
, ci
->filesize
);
80 buf
= ci
->request_buffer(&n
, ci
->filesize
);
81 if (!buf
|| n
< 0x38) {
86 DEBUGF("ADX: read size = %lx\n",(unsigned long)bufsize
);
88 /* Get file header for starting offset, channel count */
90 chanstart
= ((buf
[2] << 8) | buf
[3]) + 4;
93 /* useful for seeking and reporting current playback position */
94 avgbytespersec
= ci
->id3
->frequency
* 18 * channels
/ 32;
95 DEBUGF("avgbytespersec=%ld\n",(unsigned long)avgbytespersec
);
99 looping
= 0; start_adr
= 0; end_adr
= 0;
100 if (!memcmp(buf
+0x10,"\x01\xF4\x03\x00",4)) {
101 /* Soul Calibur 2 style (type 03) */
102 DEBUGF("ADX: type 03 found\n");
103 /* check if header is too small for loop data */
104 if (chanstart
-6 < 0x2c) looping
=0;
106 looping
= (buf
[0x18]) ||
110 end_adr
= (buf
[0x28]<<24) |
120 )/32*channels
*18+chanstart
;
122 } else if (!memcmp(buf
+0x10,"\x01\xF4\x04\x00",4)) {
123 /* Standard (type 04) */
124 DEBUGF("ADX: type 04 found\n");
125 /* check if header is too small for loop data */
126 if (chanstart
-6 < 0x38) looping
=0;
128 looping
= (buf
[0x24]) ||
132 end_adr
= (buf
[0x34]<<24) |
141 )/32*channels
*18+chanstart
;
144 DEBUGF("ADX: error, couldn't determine ADX type\n");
149 DEBUGF("ADX: looped, start: %lx end: %lx\n",start_adr
,end_adr
);
151 DEBUGF("ADX: not looped\n");
154 /* advance to first frame */
155 /*ci->seek_buffer(chanstart);*/
156 DEBUGF("ADX: first frame at %lx\n",chanstart
);
159 /* setup pcm buffer format */
160 ci
->configure(DSP_SWITCH_FREQUENCY
, ci
->id3
->frequency
);
162 ci
->configure(DSP_SET_STEREO_MODE
, STEREO_INTERLEAVED
);
163 } else if (channels
== 1) {
164 ci
->configure(DSP_SET_STEREO_MODE
, STEREO_MONO
);
166 DEBUGF("ADX CODEC_ERROR: more than 2 channels\n");
172 fade_count
= -1; /* disable fade */
175 /* The main decoder loop */
177 while (!endofstream
) {
179 if (ci
->stop_codec
|| ci
->new_track
) {
183 /* do we need to loop? */
184 if (bufoff
>= end_adr
-18*channels
&& looping
) {
185 DEBUGF("ADX: loop!\n");
186 /* check for endless looping */
187 if (ci
->global_settings
->repeat_mode
==REPEAT_ONE
) {
189 fade_count
= -1; /* disable fade */
191 /* otherwise start fade after LOOP_TIMES loops */
193 if (loop_count
>= LOOP_TIMES
&& fade_count
< 0) {
194 /* frames to fade over */
195 fade_frames
= FADE_LENGTH
*ci
->id3
->frequency
/32/1000;
196 /* volume relative to fade_frames */
197 fade_count
= fade_frames
;
198 DEBUGF("ADX: fade_frames = %d\n",fade_frames
);
204 /* do we need to seek? */
208 DEBUGF("ADX: seek to %ldms\n",ci
->seek_time
);
212 fade_count
= -1; /* disable fade */
215 newpos
= (((uint64_t)avgbytespersec
*(ci
->seek_time
- 1))
216 / (1000LL*18*channels
))*(18*channels
);
217 bufoff
= chanstart
+ newpos
;
218 while (bufoff
> end_adr
-18*channels
) {
219 bufoff
-=end_adr
-start_adr
;
225 if (bufoff
>ci
->filesize
-channels
*18) break; /* End of stream */
227 /* dance with the devil in the pale moonlight */
228 if ((bufoff
> ci
->curpos
+ (off_t
)bufsize
- channels
*18) ||
229 bufoff
< ci
->curpos
) {
230 DEBUGF("ADX: requesting another buffer at %lx size %lx\n",
231 bufoff
,ci
->filesize
-bufoff
);
232 ci
->seek_buffer(bufoff
);
233 buf
= ci
->request_buffer(&n
, ci
->filesize
-bufoff
);
235 DEBUGF("ADX: read size = %lx\n",(unsigned long)bufsize
);
236 if ((off_t
)bufsize
< channels
*18) {
237 /* if we can't get a full frame, just request a single
238 frame (should be able to fit it in the guard buffer) */
239 DEBUGF("ADX: requesting single frame at %lx\n",bufoff
);
240 buf
= ci
->request_buffer(&n
, channels
*18);
242 DEBUGF("ADX: read size = %lx\n",(unsigned long)bufsize
);
245 DEBUGF("ADX: couldn't get buffer at %lx size %lx\n",
246 bufoff
,ci
->filesize
-bufoff
);
252 if (bufsize
== 0) break; /* End of stream */
257 /* Is there data in the file buffer? */
258 ((size_t)bufoff
<= ci
->curpos
+bufsize
-(18*channels
)) &&
259 /* Is there space in the output buffer? */
260 (sampleswritten
<= WAV_CHUNK_SIZE
-(32*channels
)) &&
261 /* Should we be looping? */
262 ((!looping
) || bufoff
< end_adr
-18*channels
)) {
263 /* decode 18 bytes to 32 samples (from bero) */
264 int32_t scale
= ((buf
[bufoff
] << 8) | (buf
[bufoff
+1])) * BASE_VOL
;
268 for (i
= 2; i
< 18; i
++)
270 d
= (buf
[bufoff
+i
] >> 4) & 15;
272 ch1_0
= (d
*scale
+ 0x7298L
*ch1_1
- 0x3350L
*ch1_2
) >> 14;
273 if (ch1_0
> 32767) ch1_0
= 32767;
274 else if (ch1_0
< -32768) ch1_0
= -32768;
275 samples
[sampleswritten
] = ch1_0
;
276 sampleswritten
+=channels
;
277 ch1_2
= ch1_1
; ch1_1
= ch1_0
;
278 d
= buf
[bufoff
+i
] & 15;
280 ch1_0
= (d
*scale
+ 0x7298L
*ch1_1
- 0x3350L
*ch1_2
) >> 14;
281 if (ch1_0
> 32767) ch1_0
= 32767;
282 else if (ch1_0
< -32768) ch1_0
= -32768;
283 samples
[sampleswritten
] = ch1_0
;
284 sampleswritten
+=channels
;
285 ch1_2
= ch1_1
; ch1_1
= ch1_0
;
290 int32_t scale
= ((buf
[bufoff
] << 8)|(buf
[bufoff
+1]))*BASE_VOL
;
295 for (i
= 2; i
< 18; i
++)
297 d
= (buf
[bufoff
+i
] >> 4) & 15;
299 ch2_0
= (d
*scale
+ 0x7298L
*ch2_1
- 0x3350L
*ch2_2
) >> 14;
300 if (ch2_0
> 32767) ch2_0
= 32767;
301 else if (ch2_0
< -32768) ch2_0
= -32768;
302 samples
[sampleswritten
] = ch2_0
;
304 ch2_2
= ch2_1
; ch2_1
= ch2_0
;
305 d
= buf
[bufoff
+i
] & 15;
307 ch2_0
= (d
*scale
+ 0x7298L
*ch2_1
- 0x3350L
*ch2_2
) >> 14;
308 if (ch2_0
> 32767) ch2_0
= 32767;
309 else if (ch2_0
< -32768) ch2_0
= -32768;
310 samples
[sampleswritten
] = ch2_0
;
312 ch2_2
= ch2_1
; ch2_1
= ch2_0
;
315 sampleswritten
--; /* go back to first channel's next sample */
319 for (i
=0;i
<(channels
==1?32:64);i
++) samples
[sampleswritten
-i
-1]=
320 ((int32_t)samples
[sampleswritten
-i
-1])*fade_count
/fade_frames
;
321 if (fade_count
==0) {endofstream
=1; break;}
326 sampleswritten
>>= 1; /* make samples/channel */
328 ci
->pcmbuf_insert(samples
, NULL
, sampleswritten
);
331 ((end_adr
-start_adr
)*loop_count
+ bufoff
-chanstart
)*
332 1000LL/avgbytespersec
);
335 if (ci
->request_next_track())