summaryrefslogtreecommitdiff
path: root/apps/codecs/a52_rm.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-04-27 03:08:23 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-04-27 03:08:23 +0000
commitc537d5958e8b421ac4f9bef6c8b9e7425a6cf167 (patch)
tree7ed36518fb6524da7bbd913ba7619b85b5d15d23 /apps/codecs/a52_rm.c
parentdcf0f8de4a37ff1d2ea510aef75fa67977a8bdcc (diff)
downloadrockbox-c537d5958e8b421ac4f9bef6c8b9e7425a6cf167.tar.gz
rockbox-c537d5958e8b421ac4f9bef6c8b9e7425a6cf167.zip
Commit FS#12069 - Playback rework - first stages. Gives as thorough as possible a treatment of codec management, track change and metadata logic as possible while maintaining fairly narrow focus and not rewriting everything all at once. Please see the rockbox-dev mail archive on 2011-04-25 (Playback engine rework) for a more thorough manifest of what was addressed. Plugins and codecs become incompatible.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29785 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/a52_rm.c')
-rw-r--r--apps/codecs/a52_rm.c77
1 files changed, 43 insertions, 34 deletions
diff --git a/apps/codecs/a52_rm.c b/apps/codecs/a52_rm.c
index f5e4923292..c1930aa7b4 100644
--- a/apps/codecs/a52_rm.c
+++ b/apps/codecs/a52_rm.c
@@ -124,36 +124,44 @@ static void a52_decode_data(uint8_t *start, uint8_t *end)
124 } 124 }
125} 125}
126 126
127
128/* this is the codec entry point */ 127/* this is the codec entry point */
129enum codec_status codec_main(void) 128enum codec_status codec_main(enum codec_entry_call_reason reason)
129{
130 if (reason == CODEC_LOAD) {
131 /* Generic codec initialisation */
132 ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
133 ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
134 }
135 else if (reason == CODEC_UNLOAD) {
136 if (state)
137 a52_free(state);
138 }
139
140 return CODEC_OK;
141}
142
143/* this is called for each file to process */
144enum codec_status codec_run(void)
130{ 145{
131 size_t n; 146 size_t n;
132 uint8_t *filebuf; 147 uint8_t *filebuf;
133 int retval, consumed, packet_offset; 148 int consumed, packet_offset;
134 int playback_on = -1; 149 int playback_on = -1;
135 size_t resume_offset; 150 size_t resume_offset;
136 151 intptr_t param;
137 /* Generic codec initialisation */ 152 enum codec_command_action action = CODEC_ACTION_NULL;
138 ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED);
139 ci->configure(DSP_SET_SAMPLE_DEPTH, 28);
140
141next_track:
142 retval = CODEC_OK;
143 153
144 if (codec_init()) { 154 if (codec_init()) {
145 retval = CODEC_ERROR; 155 return CODEC_ERROR;
146 goto exit;
147 } 156 }
148 157
149 if (codec_wait_taginfo() != 0)
150 goto request_next_track;
151
152 resume_offset = ci->id3->offset; 158 resume_offset = ci->id3->offset;
153 159
154 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); 160 ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency);
155 codec_set_replaygain(ci->id3); 161 codec_set_replaygain(ci->id3);
156 162
163 ci->seek_buffer(ci->id3->first_frame_offset);
164
157 /* Intializations */ 165 /* Intializations */
158 state = a52_init(0); 166 state = a52_init(0);
159 ci->memset(&rmctx,0,sizeof(RMContext)); 167 ci->memset(&rmctx,0,sizeof(RMContext));
@@ -165,26 +173,34 @@ next_track:
165 resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; 173 resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE;
166 /* put number of subpackets to skip in resume_offset */ 174 /* put number of subpackets to skip in resume_offset */
167 resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE); 175 resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE);
168 ci->seek_time = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate); 176 param = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate);
177 action = CODEC_ACTION_SEEK_TIME;
178 }
179 else {
180 /* Seek to the first packet */
181 ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE );
169 } 182 }
170
171 /* Seek to the first packet */
172 ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE );
173 183
174 /* The main decoding loop */ 184 /* The main decoding loop */
175 while((unsigned)rmctx.audio_pkt_cnt < rmctx.nb_packets) { 185 while((unsigned)rmctx.audio_pkt_cnt < rmctx.nb_packets) {
176 ci->yield(); 186 if (action == CODEC_ACTION_NULL)
177 if (ci->stop_codec || ci->new_track) 187 action = ci->get_command(&param);
188
189 if (action == CODEC_ACTION_HALT)
178 break; 190 break;
179 191
180 if (ci->seek_time) { 192 if (action == CODEC_ACTION_SEEK_TIME) {
181 packet_offset = ci->seek_time / ((rmctx.block_align*8*1000)/rmctx.bit_rate); 193 packet_offset = param / ((rmctx.block_align*8*1000)/rmctx.bit_rate);
182 ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + packet_offset*(rmctx.block_align + PACKET_HEADER_SIZE)); 194 ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE +
195 packet_offset*(rmctx.block_align + PACKET_HEADER_SIZE));
183 rmctx.audio_pkt_cnt = packet_offset; 196 rmctx.audio_pkt_cnt = packet_offset;
184 samplesdone = (rmctx.sample_rate/1000 * ci->seek_time); 197 samplesdone = (rmctx.sample_rate/1000 * param);
198 ci->set_elapsed(samplesdone/(frequency/1000));
185 ci->seek_complete(); 199 ci->seek_complete();
186 } 200 }
187 201
202 action = CODEC_ACTION_NULL;
203
188 filebuf = ci->request_buffer(&n, rmctx.block_align + PACKET_HEADER_SIZE); 204 filebuf = ci->request_buffer(&n, rmctx.block_align + PACKET_HEADER_SIZE);
189 consumed = rm_get_packet(&filebuf, &rmctx, &pkt); 205 consumed = rm_get_packet(&filebuf, &rmctx, &pkt);
190 206
@@ -195,8 +211,7 @@ next_track:
195 return CODEC_ERROR; 211 return CODEC_ERROR;
196 } 212 }
197 else { 213 else {
198 retval = CODEC_OK; 214 break;
199 goto exit;
200 } 215 }
201 } 216 }
202 217
@@ -205,11 +220,5 @@ next_track:
205 ci->advance_buffer(pkt.length); 220 ci->advance_buffer(pkt.length);
206 } 221 }
207 222
208request_next_track: 223 return CODEC_OK;
209 if (ci->request_next_track())
210 goto next_track;
211
212exit:
213 a52_free(state);
214 return retval;
215} 224}