blob: bedd2dd5819e1c744635da1e564fc3163d7fa99d [file] [log] [blame]
Dave Chapman139c1cb2005-09-22 21:55:37 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
Thom Johansenc91e0bb2005-10-13 11:32:52 +000020#include "codeclib.h"
Dave Chapman45f9e5d2005-10-29 17:12:52 +000021#include "libm4a/m4a.h"
22#include "libalac/decomp.h"
Dave Chapman139c1cb2005-09-22 21:55:37 +000023
Jens Arnoldb8749fd2006-01-18 00:05:14 +000024CODEC_HEADER
25
Dave Chapmanf1844c42005-10-28 00:11:28 +000026int32_t outputbuffer[ALAC_MAX_CHANNELS][ALAC_BLOCKSIZE] IBSS_ATTR;
Dave Chapman45f9e5d2005-10-29 17:12:52 +000027
Dave Chapman139c1cb2005-09-22 21:55:37 +000028/* this is the codec entry point */
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000029enum codec_status codec_main(void)
Dave Chapman139c1cb2005-09-22 21:55:37 +000030{
31 size_t n;
32 demux_res_t demux_res;
Dave Chapman45f9e5d2005-10-29 17:12:52 +000033 stream_t input_stream;
Dave Chapman139c1cb2005-09-22 21:55:37 +000034 uint32_t samplesdone;
35 uint32_t elapsedtime;
36 uint32_t sample_duration;
37 uint32_t sample_byte_size;
Dave Chapmanf1844c42005-10-28 00:11:28 +000038 int samplesdecoded;
Dave Chapman139c1cb2005-09-22 21:55:37 +000039 unsigned int i;
40 unsigned char* buffer;
41 alac_file alac;
Brandon Low1060e442006-01-18 20:22:03 +000042 int retval;
Dave Chapman139c1cb2005-09-22 21:55:37 +000043
44 /* Generic codec initialisation */
Michael Sevakis97f369a2007-02-10 16:34:16 +000045 ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512);
46 ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, 1024*128);
Dave Chapman139c1cb2005-09-22 21:55:37 +000047
Michael Sevakis97f369a2007-02-10 16:34:16 +000048 ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
49 ci->configure(DSP_SET_SAMPLE_DEPTH, ALAC_OUTPUT_DEPTH-1);
Dave Chapmanfca6b632005-10-30 22:06:42 +000050
Dave Chapman139c1cb2005-09-22 21:55:37 +000051 next_track:
52
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000053 if (codec_init()) {
Dave Chapman139c1cb2005-09-22 21:55:37 +000054 LOGF("ALAC: Error initialising codec\n");
Brandon Low1060e442006-01-18 20:22:03 +000055 retval = CODEC_ERROR;
56 goto exit;
Dave Chapman139c1cb2005-09-22 21:55:37 +000057 }
58
Magnus Holmgrenaf052962006-11-23 20:05:14 +000059 while (!*ci->taginfo_ready && !ci->stop_codec)
60 ci->sleep(1);
Dave Chapman139c1cb2005-09-22 21:55:37 +000061
Michael Sevakis97f369a2007-02-10 16:34:16 +000062 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000063 codec_set_replaygain(ci->id3);
Dave Chapman139c1cb2005-09-22 21:55:37 +000064
Dave Chapman45f9e5d2005-10-29 17:12:52 +000065 stream_create(&input_stream,ci);
Dave Chapman139c1cb2005-09-22 21:55:37 +000066
67 /* if qtmovie_read returns successfully, the stream is up to
68 * the movie data, which can be used directly by the decoder */
69 if (!qtmovie_read(&input_stream, &demux_res)) {
70 LOGF("ALAC: Error initialising file\n");
Brandon Low1060e442006-01-18 20:22:03 +000071 retval = CODEC_ERROR;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +000072 goto done;
Dave Chapman139c1cb2005-09-22 21:55:37 +000073 }
74
Dave Chapman139c1cb2005-09-22 21:55:37 +000075 /* initialise the sound converter */
Magnus Holmgrend63d8fe2006-10-11 17:12:29 +000076 create_alac(demux_res.sound_sample_size, demux_res.num_channels,&alac);
Dave Chapman139c1cb2005-09-22 21:55:37 +000077 alac_set_info(&alac, demux_res.codecdata);
78
79 i=0;
80 samplesdone=0;
81 /* The main decoding loop */
82 while (i < demux_res.num_sample_byte_sizes) {
Tomasz Malesinski80da8b12006-11-26 18:31:41 +000083 ci->yield();
Brandon Lowebadcc62006-04-15 02:03:11 +000084 if (ci->stop_codec || ci->new_track) {
Dave Chapman139c1cb2005-09-22 21:55:37 +000085 break;
86 }
87
88 /* Deal with any pending seek requests */
89 if (ci->seek_time) {
Daniel Stenberg76667e22005-12-02 08:42:48 +000090 if (alac_seek(&demux_res, &input_stream,
Thom Johansenc8193b82005-11-06 19:18:04 +000091 ((ci->seek_time-1)/10) * (ci->id3->frequency/100),
Daniel Stenberg76667e22005-12-02 08:42:48 +000092 &samplesdone, (int *)&i)) {
Dave Chapman139c1cb2005-09-22 21:55:37 +000093 elapsedtime=(samplesdone*10)/(ci->id3->frequency/100);
94 ci->set_elapsed(elapsedtime);
95 }
Dave Chapman5006d152005-11-02 00:09:42 +000096 ci->seek_complete();
Dave Chapman139c1cb2005-09-22 21:55:37 +000097 }
98
99 /* Lookup the length (in samples and bytes) of block i */
100 if (!get_sample_info(&demux_res, i, &sample_duration,
101 &sample_byte_size)) {
102 LOGF("ALAC: Error in get_sample_info\n");
Brandon Low1060e442006-01-18 20:22:03 +0000103 retval = CODEC_ERROR;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000104 goto done;
Dave Chapman139c1cb2005-09-22 21:55:37 +0000105 }
106
107 /* Request the required number of bytes from the input buffer */
108
Brandon Lowc76904b2006-03-24 14:02:27 +0000109 buffer=ci->request_buffer(&n,sample_byte_size);
Dave Chapman139c1cb2005-09-22 21:55:37 +0000110 if (n!=sample_byte_size) {
Brandon Low1060e442006-01-18 20:22:03 +0000111 retval = CODEC_ERROR;
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000112 goto done;
Dave Chapman139c1cb2005-09-22 21:55:37 +0000113 }
114
115 /* Decode one block - returned samples will be host-endian */
Tomasz Malesinski80da8b12006-11-26 18:31:41 +0000116 ci->yield();
117 samplesdecoded=alac_decode_frame(&alac, buffer, outputbuffer, ci->yield);
Dave Chapman139c1cb2005-09-22 21:55:37 +0000118
Dave Chapman0c915512006-04-13 17:04:53 +0000119 /* Advance codec buffer n bytes */
Dave Chapman29c7da92005-10-30 21:04:32 +0000120 ci->advance_buffer(n);
Dave Chapman139c1cb2005-09-22 21:55:37 +0000121
122 /* Output the audio */
Tomasz Malesinski80da8b12006-11-26 18:31:41 +0000123 ci->yield();
Michael Sevakisaba6ca02007-02-07 00:51:50 +0000124 ci->pcmbuf_insert(outputbuffer[0], outputbuffer[1], samplesdecoded);
Dave Chapman139c1cb2005-09-22 21:55:37 +0000125
126 /* Update the elapsed-time indicator */
127 samplesdone+=sample_duration;
128 elapsedtime=(samplesdone*10)/(ci->id3->frequency/100);
129 ci->set_elapsed(elapsedtime);
130
131 /* Keep track of current position - for resuming */
132 ci->set_offset(elapsedtime);
133
134 i++;
135 }
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000136 retval = CODEC_OK;
Dave Chapman139c1cb2005-09-22 21:55:37 +0000137
Brandon Lowf3bc1ef2006-04-22 14:40:13 +0000138done:
Magnus Holmgren01a010f2007-03-18 09:50:53 +0000139 LOGF("ALAC: Decoded %ld samples\n",samplesdone);
Dave Chapman139c1cb2005-09-22 21:55:37 +0000140
141 if (ci->request_next_track())
142 goto next_track;
143
Brandon Low1060e442006-01-18 20:22:03 +0000144exit:
145 return retval;
Dave Chapman139c1cb2005-09-22 21:55:37 +0000146}