summaryrefslogtreecommitdiff
path: root/apps/codecs/aac.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/aac.c')
-rw-r--r--apps/codecs/aac.c129
1 files changed, 75 insertions, 54 deletions
diff --git a/apps/codecs/aac.c b/apps/codecs/aac.c
index 6c86f38372..0c48422a53 100644
--- a/apps/codecs/aac.c
+++ b/apps/codecs/aac.c
@@ -29,6 +29,8 @@ CODEC_HEADER
29extern char iramcopy[]; 29extern char iramcopy[];
30extern char iramstart[]; 30extern char iramstart[];
31extern char iramend[]; 31extern char iramend[];
32extern char iedata[];
33extern char iend[];
32#endif 34#endif
33 35
34struct codec_api* rb; 36struct codec_api* rb;
@@ -37,27 +39,35 @@ struct codec_api* ci;
37/* this is the codec entry point */ 39/* this is the codec entry point */
38enum codec_status codec_start(struct codec_api* api) 40enum codec_status codec_start(struct codec_api* api)
39{ 41{
42 /* Note that when dealing with QuickTime/MPEG4 files, terminology is
43 * a bit confusing. Files with sound are split up in chunks, where
44 * each chunk contains one or more samples. Each sample in turn
45 * contains a number of "sound samples" (the kind you refer to with
46 * the sampling frequency).
47 */
40 size_t n; 48 size_t n;
41 static demux_res_t demux_res; 49 static demux_res_t demux_res;
42 stream_t input_stream; 50 stream_t input_stream;
43 uint32_t samplesdone; 51 uint32_t sound_samples_done;
44 uint32_t elapsedtime; 52 uint32_t elapsed_time;
45 uint32_t sample_duration; 53 uint32_t sample_duration;
46 uint32_t sample_byte_size; 54 uint32_t sample_byte_size;
47 int samplesdecoded; 55 int file_offset;
48 unsigned int i; 56 unsigned int i;
49 unsigned char* buffer; 57 unsigned char* buffer;
50 static NeAACDecFrameInfo frameInfo; 58 static NeAACDecFrameInfo frame_info;
51 NeAACDecHandle hDecoder; 59 NeAACDecHandle decoder;
52 int err; 60 int err;
53 int16_t* decodedbuffer; 61 uint32_t s = 0;
62 unsigned char c = 0;
54 63
55 /* Generic codec initialisation */ 64 /* Generic codec initialisation */
56 rb = api; 65 rb = api;
57 ci = api; 66 ci = api;
58 67
59#ifndef SIMULATOR 68#ifndef SIMULATOR
60 rb->memcpy(iramstart, iramcopy, iramend-iramstart); 69 ci->memcpy(iramstart, iramcopy, iramend-iramstart);
70 ci->memset(iedata, 0, iend - iedata);
61#endif 71#endif
62 72
63 ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*16)); 73 ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*16));
@@ -68,9 +78,10 @@ enum codec_status codec_start(struct codec_api* api)
68 ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(29)); 78 ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(29));
69 79
70next_track: 80next_track:
81 err = CODEC_OK;
71 82
72 if (codec_init(api)) { 83 if (codec_init(api)) {
73 LOGF("FAAD: Error initialising codec\n"); 84 LOGF("FAAD: Codec init error\n");
74 err = CODEC_ERROR; 85 err = CODEC_ERROR;
75 goto exit; 86 goto exit;
76 } 87 }
@@ -78,7 +89,7 @@ next_track:
78 while (!*ci->taginfo_ready && !ci->stop_codec) 89 while (!*ci->taginfo_ready && !ci->stop_codec)
79 ci->sleep(1); 90 ci->sleep(1);
80 91
81 samplesdone = ci->id3->offset; 92 sound_samples_done = ci->id3->offset;
82 93
83 ci->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency)); 94 ci->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency));
84 95
@@ -87,52 +98,49 @@ next_track:
87 /* if qtmovie_read returns successfully, the stream is up to 98 /* if qtmovie_read returns successfully, the stream is up to
88 * the movie data, which can be used directly by the decoder */ 99 * the movie data, which can be used directly by the decoder */
89 if (!qtmovie_read(&input_stream, &demux_res)) { 100 if (!qtmovie_read(&input_stream, &demux_res)) {
90 LOGF("FAAD: Error initialising file\n"); 101 LOGF("FAAD: File init error\n");
91 err = CODEC_ERROR; 102 err = CODEC_ERROR;
92 goto done; 103 goto done;
93 } 104 }
94 105
95 /* initialise the sound converter */ 106 /* initialise the sound converter */
96 hDecoder = NULL; 107 decoder = NeAACDecOpen();
97 hDecoder = NeAACDecOpen();
98 108
99 if (!hDecoder) { 109 if (!decoder) {
100 LOGF("FAAD: Error opening decoder\n"); 110 LOGF("FAAD: Decode open error\n");
101 err = CODEC_ERROR; 111 err = CODEC_ERROR;
102 goto done; 112 goto done;
103 } 113 }
104 114
105 NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(hDecoder); 115 NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(decoder);
106 conf->outputFormat = FAAD_FMT_24BIT; /* irrelevant, we don't convert */ 116 conf->outputFormat = FAAD_FMT_24BIT; /* irrelevant, we don't convert */
107 NeAACDecSetConfiguration(hDecoder, conf); 117 NeAACDecSetConfiguration(decoder, conf);
108
109 uint32_t s=0;
110 unsigned char c=0;
111 118
112 err = NeAACDecInit2(hDecoder, demux_res.codecdata,demux_res.codecdata_len, &s, &c); 119 err = NeAACDecInit2(decoder, demux_res.codecdata, demux_res.codecdata_len, &s, &c);
113 if (err) { 120 if (err) {
114 LOGF("FAAD: Error initialising decoder: %d, type=%d\n", err,hDecoder->object_type); 121 LOGF("FAAD: DecInit: %d, %d\n", err, decoder->object_type);
115 err = CODEC_ERROR; 122 err = CODEC_ERROR;
116 goto done; 123 goto done;
117 } 124 }
118 125
119 ci->id3->frequency=s; 126 ci->id3->frequency = s;
120 127
121 i=0; 128 i = 0;
122 129
123 if (samplesdone > 0) { 130 if (sound_samples_done > 0) {
124 if (alac_seek_raw(&demux_res, &input_stream, samplesdone, 131 if (alac_seek_raw(&demux_res, &input_stream, sound_samples_done,
125 &samplesdone, (int *)&i)) { 132 &sound_samples_done, (int*) &i)) {
126 elapsedtime=(samplesdone*10)/(ci->id3->frequency/100); 133 elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100);
127 ci->set_elapsed(elapsedtime); 134 ci->set_elapsed(elapsed_time);
128 } else { 135 } else {
129 samplesdone=0; 136 sound_samples_done = 0;
130 } 137 }
131 } 138 }
132 139
133 /* The main decoding loop */ 140 /* The main decoding loop */
134 while (i < demux_res.num_sample_byte_sizes) { 141 while (i < demux_res.num_sample_byte_sizes) {
135 rb->yield(); 142 rb->yield();
143
136 if (ci->stop_codec || ci->new_track) { 144 if (ci->stop_codec || ci->new_track) {
137 break; 145 break;
138 } 146 }
@@ -140,10 +148,10 @@ next_track:
140 /* Deal with any pending seek requests */ 148 /* Deal with any pending seek requests */
141 if (ci->seek_time) { 149 if (ci->seek_time) {
142 if (alac_seek(&demux_res, &input_stream, 150 if (alac_seek(&demux_res, &input_stream,
143 ((ci->seek_time-1)/10) * (ci->id3->frequency/100), 151 ((ci->seek_time-1)/10)*(ci->id3->frequency/100),
144 &samplesdone, (int *)&i)) { 152 &sound_samples_done, (int*) &i)) {
145 elapsedtime=(samplesdone*10)/(ci->id3->frequency/100); 153 elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100);
146 ci->set_elapsed(elapsedtime); 154 ci->set_elapsed(elapsed_time);
147 } 155 }
148 ci->seek_complete(); 156 ci->seek_complete();
149 } 157 }
@@ -151,52 +159,65 @@ next_track:
151 /* Lookup the length (in samples and bytes) of block i */ 159 /* Lookup the length (in samples and bytes) of block i */
152 if (!get_sample_info(&demux_res, i, &sample_duration, 160 if (!get_sample_info(&demux_res, i, &sample_duration,
153 &sample_byte_size)) { 161 &sample_byte_size)) {
154 LOGF("AAC: Error in get_sample_info\n"); 162 LOGF("AAC: get_sample_info error\n");
155 err = CODEC_ERROR; 163 err = CODEC_ERROR;
156 goto done; 164 goto done;
157 } 165 }
158 166
167 /* There can be gaps between chunks, so skip ahead if needed. It
168 * doesn't seem to happen much, but it probably means that a
169 * "proper" file can have chunks out of order. Why one would want
170 * that an good question (but files with gaps do exist, so who
171 * knows?), so we don't support that - for now, at least.
172 */
173 file_offset = get_sample_offset(&demux_res, i);
174
175 if (file_offset > ci->curpos)
176 {
177 ci->advance_buffer(file_offset - ci->curpos);
178 }
179
159 /* Request the required number of bytes from the input buffer */ 180 /* Request the required number of bytes from the input buffer */
160 buffer=ci->request_buffer(&n,sample_byte_size); 181 buffer=ci->request_buffer(&n,sample_byte_size);
161 182
162 /* Decode one block - returned samples will be host-endian */ 183 /* Decode one block - returned samples will be host-endian */
163 rb->yield(); 184 NeAACDecDecode(decoder, &frame_info, buffer, n);
164 decodedbuffer = NeAACDecDecode(hDecoder, &frameInfo, buffer, n); 185 /* Ignore return value, we access samples in the decoder struct
165 /* ignore decodedbuffer return value, we access samples in the 186 * directly.
166 decoder struct directly */ 187 */
167 if (frameInfo.error > 0) { 188 if (frame_info.error > 0) {
168 LOGF("FAAD: decoding error \"%s\"\n", NeAACDecGetErrorMessage(frameInfo.error)); 189 LOGF("FAAD: decode error '%s'\n", NeAACDecGetErrorMessage(frame_info.error));
169 err = CODEC_ERROR; 190 err = CODEC_ERROR;
170 goto done; 191 goto done;
171 } 192 }
172 193
173 /* Get the number of decoded samples */
174 samplesdecoded=frameInfo.samples;
175
176 /* Advance codec buffer */ 194 /* Advance codec buffer */
177 ci->advance_buffer(n); 195 ci->advance_buffer(n);
178 196
179 /* Output the audio */ 197 /* Output the audio */
180 rb->yield(); 198 rb->yield();
181 while (!rb->pcmbuf_insert_split(hDecoder->time_out[0], 199 while (!rb->pcmbuf_insert_split(decoder->time_out[0],
182 hDecoder->time_out[1], 200 decoder->time_out[1],
183 frameInfo.samples*2)) 201 frame_info.samples * 2))
184 rb->yield(); 202 {
203 rb->sleep(1);
204 }
185 205
186 /* Update the elapsed-time indicator */ 206 /* Update the elapsed-time indicator */
187 samplesdone+=sample_duration; 207 sound_samples_done += sample_duration;
188 elapsedtime=(samplesdone*10)/(ci->id3->frequency/100); 208 elapsed_time = (sound_samples_done * 10) / (ci->id3->frequency / 100);
189 ci->set_elapsed(elapsedtime); 209 ci->set_elapsed(elapsed_time);
190 210
191 /* Keep track of current position - for resuming */ 211 /* Keep track of current position - for resuming */
192 ci->set_offset(elapsedtime); 212 ci->set_offset(elapsed_time);
193 213
194 i++; 214 i++;
195 } 215 }
216
196 err = CODEC_OK; 217 err = CODEC_OK;
197 218
198done: 219done:
199 LOGF("AAC: Decoded %d samples\n",samplesdone); 220 LOGF("AAC: Decoded %d samples, %d frames\n", sound_samples_done);
200 221
201 if (ci->request_next_track()) 222 if (ci->request_next_track())
202 goto next_track; 223 goto next_track;