summaryrefslogtreecommitdiff
path: root/apps/codecs/mpa.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/codecs/mpa.c')
-rw-r--r--apps/codecs/mpa.c56
1 files changed, 30 insertions, 26 deletions
diff --git a/apps/codecs/mpa.c b/apps/codecs/mpa.c
index f2fd8a6e2b..a52dc12a40 100644
--- a/apps/codecs/mpa.c
+++ b/apps/codecs/mpa.c
@@ -57,15 +57,6 @@ extern char iramstart[];
57extern char iramend[]; 57extern char iramend[];
58#endif 58#endif
59 59
60/*
61long resample(long *in, long *out, int num, struct resampler *s)
62{
63 if (s->delta >= (1 << 16))
64 return downsample(in, out, num, s);
65 else
66 return upsample(in, out, num, s);
67}
68*/
69/* this is the codec entry point */ 60/* this is the codec entry point */
70enum codec_status codec_start(struct codec_api* api) 61enum codec_status codec_start(struct codec_api* api)
71{ 62{
@@ -79,9 +70,10 @@ enum codec_status codec_start(struct codec_api* api)
79 unsigned int samplesdone; 70 unsigned int samplesdone;
80 bool first_frame; 71 bool first_frame;
81 int stop_skip, start_skip; 72 int stop_skip, start_skip;
82 // struct resampler lr = { 0, 0, 0 }, rr = { 0, 0, 0 }; 73 int current_stereo_mode = -1;
74 int frequency_divider;
75
83 /* Generic codec inititialisation */ 76 /* Generic codec inititialisation */
84
85 TEST_CODEC_API(api); 77 TEST_CODEC_API(api);
86 78
87#ifdef USE_IRAM 79#ifdef USE_IRAM
@@ -102,7 +94,6 @@ enum codec_status codec_start(struct codec_api* api)
102 ci->configure(DSP_SET_CLIP_MAX, (int *)(MAD_F_ONE - 1)); 94 ci->configure(DSP_SET_CLIP_MAX, (int *)(MAD_F_ONE - 1));
103 ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(MAD_F_FRACBITS)); 95 ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(MAD_F_FRACBITS));
104 ci->configure(DSP_DITHER, (bool *)false); 96 ci->configure(DSP_DITHER, (bool *)false);
105 ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_NONINTERLEAVED);
106 ci->configure(CODEC_DSP_ENABLE, (bool *)true); 97 ci->configure(CODEC_DSP_ENABLE, (bool *)true);
107 98
108 ci->memset(&Stream, 0, sizeof(struct mad_stream)); 99 ci->memset(&Stream, 0, sizeof(struct mad_stream));
@@ -128,6 +119,7 @@ enum codec_status codec_start(struct codec_api* api)
128 first_frame = false; 119 first_frame = false;
129 file_end = 0; 120 file_end = 0;
130 OutputPtr = OutputBuffer; 121 OutputPtr = OutputBuffer;
122 frequency_divider = ci->id3->frequency / 100;
131 123
132 while (!*ci->taginfo_ready) 124 while (!*ci->taginfo_ready)
133 ci->yield(); 125 ci->yield();
@@ -154,16 +146,16 @@ enum codec_status codec_start(struct codec_api* api)
154 /* TODO: 1152 is the frame size in samples for MPEG1 layer 2 and layer 3, 146 /* TODO: 1152 is the frame size in samples for MPEG1 layer 2 and layer 3,
155 it's probably not correct at all for MPEG2 and layer 1 */ 147 it's probably not correct at all for MPEG2 and layer 1 */
156 samplecount = info->frame_count*1152 - (start_skip + stop_skip); 148 samplecount = info->frame_count*1152 - (start_skip + stop_skip);
157 samplesdone = ci->id3->elapsed * (ci->id3->frequency / 100) / 10; 149 samplesdone = ci->id3->elapsed * frequency_divider / 10;
158 } else { 150 } else {
159 samplecount = ci->id3->length * (ci->id3->frequency / 100) / 10; 151 samplecount = ci->id3->length * frequency_divider / 10;
160 samplesdone = ci->id3->elapsed * (ci->id3->frequency / 100) / 10; 152 samplesdone = ci->id3->elapsed * frequency_divider / 10;
161 } 153 }
162 154
163 /* This is the decoding loop. */ 155 /* This is the decoding loop. */
164 while (1) { 156 while (1) {
165 ci->yield(); 157 ci->yield();
166 if (ci->stop_codec || ci->reload_codec) { 158 if (ci->stop_codec || ci->reload_codec) {
167 break ; 159 break ;
168 } 160 }
169 161
@@ -171,11 +163,12 @@ enum codec_status codec_start(struct codec_api* api)
171 unsigned int sample_loc; 163 unsigned int sample_loc;
172 int newpos; 164 int newpos;
173 165
174 sample_loc = ci->seek_time/1000 * ci->id3->frequency; 166 sample_loc = ci->seek_time * frequency_divider / 10;
175 newpos = ci->mp3_get_filepos(ci->seek_time-1); 167 newpos = ci->mp3_get_filepos(ci->seek_time-1);
168 if (sample_loc >= samplecount + samplesdone)
169 break ;
170
176 if (ci->seek_buffer(newpos)) { 171 if (ci->seek_buffer(newpos)) {
177 if (sample_loc >= samplecount + samplesdone)
178 break ;
179 samplecount += samplesdone - sample_loc; 172 samplecount += samplesdone - sample_loc;
180 samplesdone = sample_loc; 173 samplesdone = sample_loc;
181 } 174 }
@@ -232,17 +225,28 @@ enum codec_status codec_start(struct codec_api* api)
232 /* We skip start_skip number of samples here, this should only happen for 225 /* We skip start_skip number of samples here, this should only happen for
233 very first frame in the stream. */ 226 very first frame in the stream. */
234 /* TODO: possible for start_skip to exceed one frames worth of samples? */ 227 /* TODO: possible for start_skip to exceed one frames worth of samples? */
235 //length = resample((long *)&Synth.pcm.samples[0][start_skip], resampled_data[0], Synth.pcm.length, &lr); 228
236 //if (MAD_NCHANNELS(&Frame.header) == 2) 229 if (MAD_NCHANNELS(&Frame.header) == 2) {
237 // resample((long *)&Synth.pcm.samples[1][start_skip], resampled_data[1], Synth.pcm.length, &rr); 230 if (current_stereo_mode != STEREO_NONINTERLEAVED) {
238 ci->audiobuffer_insert_split(&Synth.pcm.samples[0][start_skip], 231 ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_NONINTERLEAVED);
239 &Synth.pcm.samples[1][start_skip], 232 current_stereo_mode = STEREO_NONINTERLEAVED;
240 (Synth.pcm.length - start_skip) * 4); 233 }
234 ci->audiobuffer_insert_split(&Synth.pcm.samples[0][start_skip],
235 &Synth.pcm.samples[1][start_skip],
236 (Synth.pcm.length - start_skip) * 4);
237 } else {
238 if (current_stereo_mode != STEREO_MONO) {
239 ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_MONO);
240 current_stereo_mode = STEREO_MONO;
241 }
242 ci->audiobuffer_insert((char *)&Synth.pcm.samples[0][start_skip],
243 (Synth.pcm.length - start_skip) * 4);
244 }
241 start_skip = 0; /* not very elegant, and might want to keep this value */ 245 start_skip = 0; /* not very elegant, and might want to keep this value */
242 246
243 samplesdone += Synth.pcm.length; 247 samplesdone += Synth.pcm.length;
244 samplecount -= Synth.pcm.length; 248 samplecount -= Synth.pcm.length;
245 ci->set_elapsed(samplesdone / (ci->id3->frequency/1000)); 249 ci->set_elapsed(samplesdone / (frequency_divider / 10));
246 } 250 }
247 251
248 Stream.error = 0; 252 Stream.error = 0;