1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 Dave Chapman
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
22 #include <codecs/demac/libdemac/demac.h>
26 #define BLOCKS_PER_LOOP 4608
27 #define MAX_CHANNELS 2
28 #define MAX_BYTESPERSAMPLE 3
30 #define INPUT_CHUNKSIZE (32*1024)
32 /* 4608*4 = 18432 bytes per channel */
33 static int32_t decoded0
[BLOCKS_PER_LOOP
] IBSS_ATTR
;
34 static int32_t decoded1
[BLOCKS_PER_LOOP
] IBSS_ATTR
;
36 #define MAX_SUPPORTED_SEEKTABLE_SIZE 5000
38 /* this is the codec entry point */
39 enum codec_status
codec_main(void)
41 struct ape_ctx_t ape_ctx
;
47 uint32_t currentframe
;
50 unsigned char* inbuffer
;
55 /* Generic codec initialisation */
56 ci
->configure(CODEC_SET_FILEBUF_WATERMARK
, 1024*512);
57 ci
->configure(CODEC_SET_FILEBUF_CHUNKSIZE
, 1024*128);
59 ci
->configure(DSP_SET_SAMPLE_DEPTH
, APE_OUTPUT_DEPTH
-1);
64 LOGF("APE: Error initialising codec\n");
69 inbuffer
= ci
->request_buffer(&bytesleft
, INPUT_CHUNKSIZE
);
71 /* Read the file headers to populate the ape_ctx struct */
72 if (ape_parseheaderbuf(inbuffer
,&ape_ctx
) < 0) {
73 LOGF("APE: Error reading header\n");
77 ci
->advance_buffer(ape_ctx
.firstframe
);
79 while (!*ci
->taginfo_ready
&& !ci
->stop_codec
)
82 ci
->configure(DSP_SWITCH_FREQUENCY
, ape_ctx
.samplerate
);
83 ci
->configure(DSP_SET_STEREO_MODE
, ape_ctx
.channels
== 1 ?
84 STEREO_MONO
: STEREO_NONINTERLEAVED
);
85 codec_set_replaygain(ci
->id3
);
87 /* The main decoding loop */
92 /* Initialise the buffer */
93 inbuffer
= ci
->request_buffer(&bytesleft
, INPUT_CHUNKSIZE
);
94 firstbyte
= 3; /* Take account of the little-endian 32-bit byte ordering */
96 /* The main decoding loop - we decode the frames a small chunk at a time */
97 while (currentframe
< ape_ctx
.totalframes
)
99 /* Calculate how many blocks there are in this frame */
100 if (currentframe
== (ape_ctx
.totalframes
- 1))
101 nblocks
= ape_ctx
.finalframeblocks
;
103 nblocks
= ape_ctx
.blocksperframe
;
105 ape_ctx
.currentframeblocks
= nblocks
;
107 /* Initialise the frame decoder */
108 init_frame_decoder(&ape_ctx
, inbuffer
, &firstbyte
, &bytesconsumed
);
110 ci
->advance_buffer(bytesconsumed
);
111 inbuffer
= ci
->request_buffer(&bytesleft
, INPUT_CHUNKSIZE
);
113 /* Decode the frame a chunk at a time */
117 if (ci
->stop_codec
|| ci
->new_track
) {
121 blockstodecode
= MIN(BLOCKS_PER_LOOP
, nblocks
);
123 if ((res
= decode_chunk(&ape_ctx
, inbuffer
, &firstbyte
,
126 blockstodecode
)) < 0)
128 /* Frame decoding error, abort */
129 LOGF("APE: Frame %d, error %d\n",currentframe
,res
);
130 retval
= CODEC_ERROR
;
135 ci
->pcmbuf_insert(decoded0
, decoded1
, blockstodecode
);
137 /* Update the elapsed-time indicator */
138 samplesdone
+= blockstodecode
;
139 elapsedtime
= (samplesdone
*10)/(ape_ctx
.samplerate
/100);
140 ci
->set_elapsed(elapsedtime
);
142 ci
->advance_buffer(bytesconsumed
);
143 inbuffer
= ci
->request_buffer(&bytesleft
, INPUT_CHUNKSIZE
);
145 /* Decrement the block count */
146 nblocks
-= blockstodecode
;
155 LOGF("APE: Decoded %ld samples\n",samplesdone
);
157 if (ci
->request_next_track())