1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 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 ****************************************************************************/
21 #include <codecs/libalac/demux.h>
22 #include <codecs/libalac/decomp.h>
23 #include <codecs/libalac/stream.h>
26 extern char iramcopy
[];
27 extern char iramstart
[];
28 extern char iramend
[];
31 #define destBufferSize (1024*16)
33 char inputBuffer
[1024*32]; /* Input buffer */
34 int32_t outputbuffer
[ALAC_MAX_CHANNELS
][ALAC_BLOCKSIZE
] IBSS_ATTR
;
39 /* Implementation of the stream.h functions used by libalac */
41 #define _Swap32(v) do { \
42 v = (((v) & 0x000000FF) << 0x18) | \
43 (((v) & 0x0000FF00) << 0x08) | \
44 (((v) & 0x00FF0000) >> 0x08) | \
45 (((v) & 0xFF000000) >> 0x18); } while(0)
47 #define _Swap16(v) do { \
48 v = (((v) & 0x00FF) << 0x08) | \
49 (((v) & 0xFF00) >> 0x08); } while (0)
51 /* A normal read without any byte-swapping */
52 void stream_read(stream_t
*stream
, size_t size
, void *buf
)
54 ci
->read_filebuf(buf
,size
);
55 if (ci
->curpos
>= ci
->filesize
) { stream
->eof
=1; }
58 int32_t stream_read_int32(stream_t
*stream
)
61 stream_read(stream
, 4, &v
);
62 #ifdef ROCKBOX_LITTLE_ENDIAN
68 uint32_t stream_read_uint32(stream_t
*stream
)
71 stream_read(stream
, 4, &v
);
72 #ifdef ROCKBOX_LITTLE_ENDIAN
78 int16_t stream_read_int16(stream_t
*stream
)
81 stream_read(stream
, 2, &v
);
82 #ifdef ROCKBOX_LITTLE_ENDIAN
88 uint16_t stream_read_uint16(stream_t
*stream
)
91 stream_read(stream
, 2, &v
);
92 #ifdef ROCKBOX_LITTLE_ENDIAN
98 int8_t stream_read_int8(stream_t
*stream
)
101 stream_read(stream
, 1, &v
);
105 uint8_t stream_read_uint8(stream_t
*stream
)
108 stream_read(stream
, 1, &v
);
112 void stream_skip(stream_t
*stream
, size_t skip
)
115 ci
->advance_buffer(skip
);
118 int stream_eof(stream_t
*stream
)
123 void stream_create(stream_t
*stream
)
128 /* This function was part of the original alac decoder implementation */
130 static int get_sample_info(demux_res_t
*demux_res
, uint32_t samplenum
,
131 uint32_t *sample_duration
,
132 uint32_t *sample_byte_size
)
134 unsigned int duration_index_accum
= 0;
135 unsigned int duration_cur_index
= 0;
137 if (samplenum
>= demux_res
->num_sample_byte_sizes
) {
141 if (!demux_res
->num_time_to_samples
) {
145 while ((demux_res
->time_to_sample
[duration_cur_index
].sample_count
146 + duration_index_accum
) <= samplenum
) {
147 duration_index_accum
+=
148 demux_res
->time_to_sample
[duration_cur_index
].sample_count
;
150 duration_cur_index
++;
151 if (duration_cur_index
>= demux_res
->num_time_to_samples
) {
157 demux_res
->time_to_sample
[duration_cur_index
].sample_duration
;
158 *sample_byte_size
= demux_res
->sample_byte_size
[samplenum
];
163 /* Seek to sample_loc (or close to it). Return 1 on success (and
164 modify samplesdone and currentblock), 0 if failed
166 Seeking uses the following two arrays:
168 1) the sample_byte_size array contains the length in bytes of
169 each block ("sample" in Applespeak).
171 2) the time_to_sample array contains the duration (in samples) of
174 So we just find the block number we are going to seek to (using
175 time_to_sample) and then find the offset in the file (using
178 Each ALAC block seems to be independent of all the others.
181 static unsigned int alac_seek (demux_res_t
* demux_res
,
182 unsigned int sample_loc
,
183 uint32_t* samplesdone
, int* currentblock
)
187 unsigned int newblock
;
188 unsigned int newsample
;
191 /* First check we have the appropriate metadata - we should always
193 if ((demux_res
->num_time_to_samples
==0) ||
194 (demux_res
->num_sample_byte_sizes
==0)) { return 0; }
196 /* Find the destination block from time_to_sample array */
202 while ((i
<demux_res
->num_time_to_samples
) && (flag
==0) &&
203 (newsample
< sample_loc
)) {
204 j
=(sample_loc
-newsample
) /
205 demux_res
->time_to_sample
[i
].sample_duration
;
207 if (j
<= demux_res
->time_to_sample
[i
].sample_count
) {
209 newsample
+=j
*demux_res
->time_to_sample
[i
].sample_duration
;
212 newsample
+=(demux_res
->time_to_sample
[i
].sample_duration
213 * demux_res
->time_to_sample
[i
].sample_count
);
214 newblock
+=demux_res
->time_to_sample
[i
].sample_count
;
219 /* We know the new block, now calculate the file position */
221 for (i
=0;i
<newblock
;i
++) {
222 newpos
+=demux_res
->sample_byte_size
[i
];
225 /* We know the new file position, so let's try to seek to it */
226 if (ci
->seek_buffer(newpos
)) {
227 *samplesdone
=newsample
;
228 *currentblock
=newblock
;
235 /* this is the codec entry point */
236 enum codec_status
codec_start(struct codec_api
* api
)
239 demux_res_t demux_res
;
240 static stream_t input_stream
;
241 uint32_t samplesdone
;
242 uint32_t elapsedtime
;
243 uint32_t sample_duration
;
244 uint32_t sample_byte_size
;
247 unsigned char* buffer
;
250 /* Generic codec initialisation */
254 ci
= (struct codec_api
*)api
;
257 rb
->memcpy(iramstart
, iramcopy
, iramend
-iramstart
);
260 ci
->configure(CODEC_SET_FILEBUF_LIMIT
, (int *)(1024*1024*10));
261 ci
->configure(CODEC_SET_FILEBUF_WATERMARK
, (int *)(1024*512));
262 ci
->configure(CODEC_SET_FILEBUF_CHUNKSIZE
, (int *)(1024*128));
264 ci
->configure(CODEC_DSP_ENABLE
, (bool *)true);
265 ci
->configure(DSP_DITHER
, (bool *)false);
266 ci
->configure(DSP_SET_STEREO_MODE
, (int *)STEREO_NONINTERLEAVED
);
267 ci
->configure(DSP_SET_SAMPLE_DEPTH
, (int *)(28));
271 if (codec_init(api
)) {
272 LOGF("ALAC: Error initialising codec\n");
276 while (!rb
->taginfo_ready
)
279 ci
->configure(DSP_SET_FREQUENCY
, (long *)(rb
->id3
->frequency
));
281 stream_create(&input_stream
);
283 /* if qtmovie_read returns successfully, the stream is up to
284 * the movie data, which can be used directly by the decoder */
285 if (!qtmovie_read(&input_stream
, &demux_res
)) {
286 LOGF("ALAC: Error initialising file\n");
290 /* Keep track of start of stream in file - used for seeking */
291 mdat_offset
=ci
->curpos
;
293 /* initialise the sound converter */
294 create_alac(demux_res
.sample_size
, demux_res
.num_channels
,&alac
);
295 alac_set_info(&alac
, demux_res
.codecdata
);
299 /* The main decoding loop */
300 while (i
< demux_res
.num_sample_byte_sizes
) {
302 if (ci
->stop_codec
|| ci
->reload_codec
) {
306 /* Deal with any pending seek requests */
308 if (alac_seek(&demux_res
,
309 (ci
->seek_time
/10) * (ci
->id3
->frequency
/100),
311 elapsedtime
=(samplesdone
*10)/(ci
->id3
->frequency
/100);
312 ci
->set_elapsed(elapsedtime
);
317 /* Lookup the length (in samples and bytes) of block i */
318 if (!get_sample_info(&demux_res
, i
, &sample_duration
,
319 &sample_byte_size
)) {
320 LOGF("ALAC: Error in get_sample_info\n");
324 /* Request the required number of bytes from the input buffer */
326 buffer
=ci
->request_buffer((long*)&n
,sample_byte_size
);
327 if (n
!=sample_byte_size
) {
328 /* The decode_frame function requires the whole frame, so if we
329 can't get it contiguously from the buffer, then we need to
330 copy it via a read - i.e. we are at the buffer wraparound
333 /* Check we estimated the maximum buffer size correctly */
334 if (sample_byte_size
> sizeof(inputBuffer
)) {
335 LOGF("ALAC: Input buffer < %d bytes\n",sample_byte_size
);
339 n
=ci
->read_filebuf(inputBuffer
,sample_byte_size
);
340 if (n
!=sample_byte_size
) {
341 LOGF("ALAC: Error reading data\n");
347 /* Decode one block - returned samples will be host-endian */
349 samplesdecoded
=alac_decode_frame(&alac
, buffer
, outputbuffer
, rb
->yield
);
351 /* Advance codec buffer - unless we did a read */
352 if ((char*)buffer
!=(char*)inputBuffer
) {
353 ci
->advance_buffer(n
);
356 /* Output the audio */
358 while(!ci
->pcmbuf_insert_split(outputbuffer
[0],
360 samplesdecoded
*sizeof(int32_t)))
363 /* Update the elapsed-time indicator */
364 samplesdone
+=sample_duration
;
365 elapsedtime
=(samplesdone
*10)/(ci
->id3
->frequency
/100);
366 ci
->set_elapsed(elapsedtime
);
368 /* Keep track of current position - for resuming */
369 ci
->set_offset(elapsedtime
);
374 LOGF("ALAC: Decoded %d samples\n",samplesdone
);
376 if (ci
->request_next_track())