blob: 06a0e165276a989f69dcb582d891c2a26c74683d [file] [log] [blame]
Dave Chapmancea6d0c2005-10-31 20:56:29 +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
20#include "codeclib.h"
21#include "libm4a/m4a.h"
22#include "libfaad/common.h"
23#include "libfaad/structs.h"
24#include "libfaad/decoder.h"
25
Jens Arnoldb8749fd2006-01-18 00:05:14 +000026CODEC_HEADER
27
Dave Chapmancea6d0c2005-10-31 20:56:29 +000028#ifndef SIMULATOR
29extern char iramcopy[];
30extern char iramstart[];
31extern char iramend[];
32#endif
33
34struct codec_api* rb;
35struct codec_api* ci;
36
37/* this is the codec entry point */
38enum codec_status codec_start(struct codec_api* api)
39{
Dave Chapmanb08a9422005-10-31 23:34:14 +000040 size_t n;
41 static demux_res_t demux_res;
42 stream_t input_stream;
43 uint32_t samplesdone;
44 uint32_t elapsedtime;
45 uint32_t sample_duration;
46 uint32_t sample_byte_size;
47 int samplesdecoded;
48 unsigned int i;
49 unsigned char* buffer;
50 static NeAACDecFrameInfo frameInfo;
51 NeAACDecHandle hDecoder;
52 int err;
53 int16_t* decodedbuffer;
Dave Chapmancea6d0c2005-10-31 20:56:29 +000054
Dave Chapmanb08a9422005-10-31 23:34:14 +000055 /* Generic codec initialisation */
Dave Chapmanb08a9422005-10-31 23:34:14 +000056 rb = api;
Jens Arnoldb8749fd2006-01-18 00:05:14 +000057 ci = api;
Dave Chapmancea6d0c2005-10-31 20:56:29 +000058
59#ifndef SIMULATOR
Dave Chapmanb08a9422005-10-31 23:34:14 +000060 rb->memcpy(iramstart, iramcopy, iramend-iramstart);
Dave Chapmancea6d0c2005-10-31 20:56:29 +000061#endif
62
Dave Chapmanb08a9422005-10-31 23:34:14 +000063 ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*16));
64 ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512));
Dave Chapmancea6d0c2005-10-31 20:56:29 +000065
Dave Chapmanb08a9422005-10-31 23:34:14 +000066 ci->configure(CODEC_DSP_ENABLE, (bool *)true);
67 ci->configure(DSP_DITHER, (bool *)false);
Thom Johansen0263ece2005-11-02 19:43:52 +000068 ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_NONINTERLEAVED);
69 ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(29));
Dave Chapmancea6d0c2005-10-31 20:56:29 +000070
Dave Chapmanb08a9422005-10-31 23:34:14 +000071 next_track:
Dave Chapmancea6d0c2005-10-31 20:56:29 +000072
Dave Chapmanb08a9422005-10-31 23:34:14 +000073 if (codec_init(api)) {
74 LOGF("FAAD: Error initialising codec\n");
Brandon Low1060e442006-01-18 20:22:03 +000075 err = CODEC_ERROR;
76 goto exit;
Dave Chapmancea6d0c2005-10-31 20:56:29 +000077 }
78
Dave Chapmanb08a9422005-10-31 23:34:14 +000079 while (!rb->taginfo_ready)
80 rb->yield();
81
82 ci->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency));
83
84 stream_create(&input_stream,ci);
85
86 /* if qtmovie_read returns successfully, the stream is up to
87 * the movie data, which can be used directly by the decoder */
88 if (!qtmovie_read(&input_stream, &demux_res)) {
89 LOGF("FAAD: Error initialising file\n");
Brandon Low1060e442006-01-18 20:22:03 +000090 err = CODEC_ERROR;
91 goto exit;
Dave Chapmanb08a9422005-10-31 23:34:14 +000092 }
93
94 /* initialise the sound converter */
95 hDecoder = NULL;
96 hDecoder = NeAACDecOpen();
97
98 if (!hDecoder) {
99 LOGF("FAAD: Error opening decoder\n");
Brandon Low1060e442006-01-18 20:22:03 +0000100 err = CODEC_ERROR;
101 goto exit;
Dave Chapmanb08a9422005-10-31 23:34:14 +0000102 }
103
104 NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(hDecoder);
Thom Johansen0263ece2005-11-02 19:43:52 +0000105 conf->outputFormat = FAAD_FMT_24BIT; /* irrelevant, we don't convert */
Dave Chapmanb08a9422005-10-31 23:34:14 +0000106 NeAACDecSetConfiguration(hDecoder, conf);
107
108 unsigned long s=0;
109 unsigned char c=0;
110
111 err = NeAACDecInit2(hDecoder, demux_res.codecdata,demux_res.codecdata_len, &s, &c);
112 if (err) {
113 LOGF("FAAD: Error initialising decoder: %d, type=%d\n", err,hDecoder->object_type);
Brandon Low1060e442006-01-18 20:22:03 +0000114 err = CODEC_ERROR;
115 goto exit;
Dave Chapmanb08a9422005-10-31 23:34:14 +0000116 }
117
118 ci->id3->frequency=s;
119
120 i=0;
121 samplesdone=0;
122 /* The main decoding loop */
123 while (i < demux_res.num_sample_byte_sizes) {
124 rb->yield();
125 if (ci->stop_codec || ci->reload_codec) {
126 break;
127 }
128
129 /* Deal with any pending seek requests */
130 if (ci->seek_time) {
Daniel Stenberg76667e22005-12-02 08:42:48 +0000131 if (alac_seek(&demux_res, &input_stream,
Thom Johansenc8193b82005-11-06 19:18:04 +0000132 ((ci->seek_time-1)/10) * (ci->id3->frequency/100),
Daniel Stenberg76667e22005-12-02 08:42:48 +0000133 &samplesdone, (int *)&i)) {
Dave Chapmanb08a9422005-10-31 23:34:14 +0000134 elapsedtime=(samplesdone*10)/(ci->id3->frequency/100);
135 ci->set_elapsed(elapsedtime);
136 }
Dave Chapman5006d152005-11-02 00:09:42 +0000137 ci->seek_complete();
Dave Chapmanb08a9422005-10-31 23:34:14 +0000138 }
139
140 /* Lookup the length (in samples and bytes) of block i */
141 if (!get_sample_info(&demux_res, i, &sample_duration,
142 &sample_byte_size)) {
143 LOGF("AAC: Error in get_sample_info\n");
Brandon Low1060e442006-01-18 20:22:03 +0000144 err = CODEC_ERROR;
145 goto exit;
Dave Chapmanb08a9422005-10-31 23:34:14 +0000146 }
147
148 /* Request the required number of bytes from the input buffer */
149 buffer=ci->request_buffer((long*)&n,sample_byte_size);
150
151 /* Decode one block - returned samples will be host-endian */
152 rb->yield();
153 decodedbuffer = NeAACDecDecode(hDecoder, &frameInfo, buffer, n);
Thom Johansen0263ece2005-11-02 19:43:52 +0000154 /* ignore decodedbuffer return value, we access samples in the
155 decoder struct directly */
Dave Chapmanb08a9422005-10-31 23:34:14 +0000156 if (frameInfo.error > 0) {
157 LOGF("FAAD: decoding error \"%s\"\n", NeAACDecGetErrorMessage(frameInfo.error));
Brandon Low1060e442006-01-18 20:22:03 +0000158 err = CODEC_ERROR;
159 goto exit;
Dave Chapmanb08a9422005-10-31 23:34:14 +0000160 }
161
162 /* Get the number of decoded samples */
163 samplesdecoded=frameInfo.samples;
164
165 /* Advance codec buffer */
166 ci->advance_buffer(n);
167
168 /* Output the audio */
169 rb->yield();
Thom Johansen0263ece2005-11-02 19:43:52 +0000170 while (!rb->pcmbuf_insert_split(hDecoder->time_out[0],
171 hDecoder->time_out[1],
172 frameInfo.samples*2))
Dave Chapmanb08a9422005-10-31 23:34:14 +0000173 rb->yield();
174
175 /* Update the elapsed-time indicator */
176 samplesdone+=sample_duration;
Dave Chapmancea6d0c2005-10-31 20:56:29 +0000177 elapsedtime=(samplesdone*10)/(ci->id3->frequency/100);
178 ci->set_elapsed(elapsedtime);
Dave Chapmanb08a9422005-10-31 23:34:14 +0000179
180 /* Keep track of current position - for resuming */
181 ci->set_offset(elapsedtime);
182
183 i++;
Dave Chapmancea6d0c2005-10-31 20:56:29 +0000184 }
185
Dave Chapmanb08a9422005-10-31 23:34:14 +0000186 LOGF("AAC: Decoded %d samples\n",samplesdone);
Dave Chapmancea6d0c2005-10-31 20:56:29 +0000187
Dave Chapmanb08a9422005-10-31 23:34:14 +0000188 if (ci->request_next_track())
189 goto next_track;
Dave Chapmancea6d0c2005-10-31 20:56:29 +0000190
Brandon Low1060e442006-01-18 20:22:03 +0000191 err = CODEC_OK;
192exit:
193 return err;
Dave Chapmancea6d0c2005-10-31 20:56:29 +0000194}