summaryrefslogtreecommitdiff
path: root/apps/codecs/raac.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/raac.c')
-rw-r--r--apps/codecs/raac.c98
1 files changed, 55 insertions, 43 deletions
diff --git a/apps/codecs/raac.c b/apps/codecs/raac.c
index b322ae7df3..4b73f41462 100644
--- a/apps/codecs/raac.c
+++ b/apps/codecs/raac.c
@@ -35,8 +35,21 @@ static void init_rm(RMContext *rmctx)
35 35
36static RMContext rmctx; 36static RMContext rmctx;
37static RMPacket pkt; 37static RMPacket pkt;
38
38/* this is the codec entry point */ 39/* this is the codec entry point */
39enum codec_status codec_main(void) 40enum codec_status codec_main(enum codec_entry_call_reason reason)
41{
42 if (reason == CODEC_LOAD) {
43 /* Generic codec initialisation */
44 ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
45 ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
46 }
47
48 return CODEC_OK;
49}
50
51/* this is called for each file to process */
52enum codec_status codec_run(void)
40{ 53{
41 static NeAACDecFrameInfo frame_info; 54 static NeAACDecFrameInfo frame_info;
42 NeAACDecHandle decoder; 55 NeAACDecHandle decoder;
@@ -49,26 +62,21 @@ enum codec_status codec_main(void)
49 unsigned char c = 0; /* channels */ 62 unsigned char c = 0; /* channels */
50 int playback_on = -1; 63 int playback_on = -1;
51 size_t resume_offset; 64 size_t resume_offset;
52 65 intptr_t param;
53 /* Generic codec initialisation */ 66 enum codec_command_action action = CODEC_ACTION_NULL;
54 ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
55 ci->configure(DSP_SET_SAMPLE_DEPTH, 29);
56
57next_track:
58 err = CODEC_OK;
59 67
60 if (codec_init()) { 68 if (codec_init()) {
61 DEBUGF("FAAD: Codec init error\n"); 69 DEBUGF("FAAD: Codec init error\n");
62 return CODEC_ERROR; 70 return CODEC_ERROR;
63 } 71 }
64 72
65 if (codec_wait_taginfo() != 0)
66 goto done;
67
68 resume_offset = ci->id3->offset; 73 resume_offset = ci->id3->offset;
69 74
70 ci->memset(&rmctx,0,sizeof(RMContext)); 75 ci->memset(&rmctx,0,sizeof(RMContext));
71 ci->memset(&pkt,0,sizeof(RMPacket)); 76 ci->memset(&pkt,0,sizeof(RMPacket));
77
78 ci->seek_buffer(0);
79
72 init_rm(&rmctx); 80 init_rm(&rmctx);
73 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); 81 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
74 codec_set_replaygain(ci->id3); 82 codec_set_replaygain(ci->id3);
@@ -78,9 +86,9 @@ next_track:
78 86
79 if (!decoder) { 87 if (!decoder) {
80 DEBUGF("FAAD: Decode open error\n"); 88 DEBUGF("FAAD: Decode open error\n");
81 err = CODEC_ERROR; 89 return CODEC_ERROR;
82 goto done; 90 }
83 } 91
84 NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(decoder); 92 NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(decoder);
85 conf->outputFormat = FAAD_FMT_16BIT; /* irrelevant, we don't convert */ 93 conf->outputFormat = FAAD_FMT_16BIT; /* irrelevant, we don't convert */
86 NeAACDecSetConfiguration(decoder, conf); 94 NeAACDecSetConfiguration(decoder, conf);
@@ -91,8 +99,7 @@ next_track:
91 99
92 if (err) { 100 if (err) {
93 DEBUGF("FAAD: DecInit: %d, %d\n", err, decoder->object_type); 101 DEBUGF("FAAD: DecInit: %d, %d\n", err, decoder->object_type);
94 err = CODEC_ERROR; 102 return CODEC_ERROR;
95 goto done;
96 } 103 }
97 104
98 /* check for a mid-track resume and force a seek time accordingly */ 105 /* check for a mid-track resume and force a seek time accordingly */
@@ -100,36 +107,38 @@ next_track:
100 resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; 107 resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE;
101 /* put number of subpackets to skip in resume_offset */ 108 /* put number of subpackets to skip in resume_offset */
102 resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE); 109 resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE);
103 ci->seek_time = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate); 110 param = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate);
111 action = CODEC_ACTION_SEEK_TIME;
104 } 112 }
105 113
106 ci->id3->frequency = s; 114 ci->id3->frequency = s; /* FIXME: Won't get it to the UI */
107 ci->set_elapsed(0); 115 ci->set_elapsed(0);
108 ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE); 116 ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE);
109 117
110 /* The main decoding loop */ 118 /* The main decoding loop */
111seek_start:
112 while (1) { 119 while (1) {
113 ci->yield(); 120 if (action == CODEC_ACTION_NULL)
114 if (ci->stop_codec || ci->new_track) { 121 action = ci->get_command(&param);
122
123 if (action == CODEC_ACTION_HALT)
115 break; 124 break;
116 }
117 125
118 if (ci->seek_time) { 126 if (action == CODEC_ACTION_SEEK_TIME) {
119
120 /* Do not allow seeking beyond the file's length */ 127 /* Do not allow seeking beyond the file's length */
121 if ((unsigned) ci->seek_time > ci->id3->length) { 128 if ((unsigned) param > ci->id3->length) {
129 ci->set_elapsed(ci->id3->length);
122 ci->seek_complete(); 130 ci->seek_complete();
123 goto done; 131 break;
124 } 132 }
125 133
126 ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE); 134 ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE);
127 135
128 /* Seek to the start of the track */ 136 /* Seek to the start of the track */
129 if (ci->seek_time == 1) { 137 if (param == 0) {
130 ci->set_elapsed(0); 138 ci->set_elapsed(0);
131 ci->seek_complete(); 139 ci->seek_complete();
132 goto seek_start; 140 action = CODEC_ACTION_NULL;
141 continue;
133 } 142 }
134 143
135 skipped = 0; 144 skipped = 0;
@@ -141,21 +150,30 @@ seek_start:
141 if(playback_on == -1) { 150 if(playback_on == -1) {
142 /* Error only if packet-parsing failed and playback hadn't started */ 151 /* Error only if packet-parsing failed and playback hadn't started */
143 DEBUGF("rm_get_packet failed\n"); 152 DEBUGF("rm_get_packet failed\n");
153 ci->seek_complete();
144 return CODEC_ERROR; 154 return CODEC_ERROR;
145 } 155 }
146 else 156 else {
147 goto done; 157 ci->seek_complete();
158 return CODEC_OK;
159 }
148 } 160 }
149 skipped += pkt.length; 161 skipped += pkt.length;
150 if(pkt.timestamp > (unsigned)ci->seek_time) break; 162
163 if(pkt.timestamp > (unsigned)param)
164 break;
165
151 ci->advance_buffer(pkt.length); 166 ci->advance_buffer(pkt.length);
152 } 167 }
153 ci->seek_buffer(pkt_offset + rmctx.data_offset + DATA_HEADER_SIZE); 168 ci->seek_buffer(pkt_offset + rmctx.data_offset + DATA_HEADER_SIZE);
154 buffer = ci->request_buffer(&n,rmctx.audio_framesize + 1000); 169 buffer = ci->request_buffer(&n,rmctx.audio_framesize + 1000);
155 NeAACDecPostSeekReset(decoder, decoder->frame); 170 NeAACDecPostSeekReset(decoder, decoder->frame);
171 ci->set_elapsed(pkt.timestamp);
156 ci->seek_complete(); 172 ci->seek_complete();
157 } 173 }
158 174
175 action = CODEC_ACTION_NULL;
176
159 /* Request the required number of bytes from the input buffer */ 177 /* Request the required number of bytes from the input buffer */
160 buffer=ci->request_buffer(&n,rmctx.audio_framesize + 1000); 178 buffer=ci->request_buffer(&n,rmctx.audio_framesize + 1000);
161 consumed = rm_get_packet(&buffer, &rmctx, &pkt); 179 consumed = rm_get_packet(&buffer, &rmctx, &pkt);
@@ -167,20 +185,20 @@ seek_start:
167 return CODEC_ERROR; 185 return CODEC_ERROR;
168 } 186 }
169 else 187 else
170 goto done; 188 break;
171 } 189 }
172 190
173 playback_on = 1; 191 playback_on = 1;
174 if (pkt.timestamp >= ci->id3->length) 192 if (pkt.timestamp >= ci->id3->length)
175 goto done; 193 break;
194
176 /* Decode one block - returned samples will be host-endian */ 195 /* Decode one block - returned samples will be host-endian */
177 for(i = 0; i < rmctx.sub_packet_cnt; i++) { 196 for(i = 0; i < rmctx.sub_packet_cnt; i++) {
178 ret = NeAACDecDecode(decoder, &frame_info, buffer, rmctx.sub_packet_lengths[i]); 197 ret = NeAACDecDecode(decoder, &frame_info, buffer, rmctx.sub_packet_lengths[i]);
179 buffer += rmctx.sub_packet_lengths[i]; 198 buffer += rmctx.sub_packet_lengths[i];
180 if (frame_info.error > 0) { 199 if (frame_info.error > 0) {
181 DEBUGF("FAAD: decode error '%s'\n", NeAACDecGetErrorMessage(frame_info.error)); 200 DEBUGF("FAAD: decode error '%s'\n", NeAACDecGetErrorMessage(frame_info.error));
182 err = CODEC_ERROR; 201 return CODEC_ERROR;
183 goto exit;
184 } 202 }
185 ci->pcmbuf_insert(decoder->time_out[0], 203 ci->pcmbuf_insert(decoder->time_out[0],
186 decoder->time_out[1], 204 decoder->time_out[1],
@@ -191,11 +209,5 @@ seek_start:
191 ci->advance_buffer(pkt.length); 209 ci->advance_buffer(pkt.length);
192 } 210 }
193 211
194done: 212 return CODEC_OK;
195 if (ci->request_next_track())
196 goto next_track;
197
198exit:
199 return err;
200} 213}
201