diff options
Diffstat (limited to 'apps/codecs/raac.c')
-rw-r--r-- | apps/codecs/raac.c | 98 |
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 | ||
36 | static RMContext rmctx; | 36 | static RMContext rmctx; |
37 | static RMPacket pkt; | 37 | static RMPacket pkt; |
38 | |||
38 | /* this is the codec entry point */ | 39 | /* this is the codec entry point */ |
39 | enum codec_status codec_main(void) | 40 | enum 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 */ | ||
52 | enum 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 | |||
57 | next_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 */ |
111 | seek_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(¶m); |
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 | ||
194 | done: | 212 | return CODEC_OK; |
195 | if (ci->request_next_track()) | ||
196 | goto next_track; | ||
197 | |||
198 | exit: | ||
199 | return err; | ||
200 | } | 213 | } |
201 | |||