diff options
Diffstat (limited to 'apps/codecs')
-rw-r--r-- | apps/codecs/a52.c | 15 | ||||
-rw-r--r-- | apps/codecs/flac.c | 15 | ||||
-rw-r--r-- | apps/codecs/mpa.c | 303 | ||||
-rw-r--r-- | apps/codecs/vorbis.c | 30 | ||||
-rw-r--r-- | apps/codecs/wav.c | 17 | ||||
-rw-r--r-- | apps/codecs/wavpack.c | 16 |
6 files changed, 101 insertions, 295 deletions
diff --git a/apps/codecs/a52.c b/apps/codecs/a52.c index bc711965ec..663e7941ec 100644 --- a/apps/codecs/a52.c +++ b/apps/codecs/a52.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <codecs/liba52/a52.h> | 24 | #include <codecs/liba52/a52.h> |
25 | 25 | ||
26 | #include "playback.h" | 26 | #include "playback.h" |
27 | #include "dsp.h" | ||
27 | #include "lib/codeclib.h" | 28 | #include "lib/codeclib.h" |
28 | 29 | ||
29 | #define BUFFER_SIZE 4096 | 30 | #define BUFFER_SIZE 4096 |
@@ -173,12 +174,26 @@ enum codec_status codec_start(struct codec_api* api) | |||
173 | ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2)); | 174 | ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2)); |
174 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*128)); | 175 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*128)); |
175 | 176 | ||
177 | ci->configure(DSP_DITHER, (bool *)false); | ||
178 | ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED); | ||
179 | ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16)); | ||
180 | |||
176 | next_track: | 181 | next_track: |
177 | 182 | ||
178 | if (codec_init(api)) { | 183 | if (codec_init(api)) { |
179 | return CODEC_ERROR; | 184 | return CODEC_ERROR; |
180 | } | 185 | } |
181 | 186 | ||
187 | while (!rb->taginfo_ready) | ||
188 | rb->yield(); | ||
189 | |||
190 | if (rb->id3->frequency != NATIVE_FREQUENCY) { | ||
191 | rb->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency)); | ||
192 | rb->configure(CODEC_DSP_ENABLE, (bool *)true); | ||
193 | } else { | ||
194 | rb->configure(CODEC_DSP_ENABLE, (bool *)false); | ||
195 | } | ||
196 | |||
182 | /* Intialise the A52 decoder and check for success */ | 197 | /* Intialise the A52 decoder and check for success */ |
183 | state = a52_init (0); // Parameter is "accel" | 198 | state = a52_init (0); // Parameter is "accel" |
184 | 199 | ||
diff --git a/apps/codecs/flac.c b/apps/codecs/flac.c index 07e5b8f566..d7ae037d26 100644 --- a/apps/codecs/flac.c +++ b/apps/codecs/flac.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <codecs/libFLAC/include/FLAC/seekable_stream_decoder.h> | 22 | #include <codecs/libFLAC/include/FLAC/seekable_stream_decoder.h> |
23 | #include "playback.h" | 23 | #include "playback.h" |
24 | #include "lib/codeclib.h" | 24 | #include "lib/codeclib.h" |
25 | #include "dsp.h" | ||
25 | 26 | ||
26 | #define FLAC_MAX_SUPPORTED_BLOCKSIZE 4608 | 27 | #define FLAC_MAX_SUPPORTED_BLOCKSIZE 4608 |
27 | #define FLAC_MAX_SUPPORTED_CHANNELS 2 | 28 | #define FLAC_MAX_SUPPORTED_CHANNELS 2 |
@@ -180,12 +181,26 @@ enum codec_status codec_start(struct codec_api* api) | |||
180 | ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512)); | 181 | ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512)); |
181 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*128)); | 182 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*128)); |
182 | 183 | ||
184 | ci->configure(DSP_DITHER, (bool *)false); | ||
185 | ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED); | ||
186 | ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16)); | ||
187 | |||
183 | next_track: | 188 | next_track: |
184 | 189 | ||
185 | if (codec_init(api)) { | 190 | if (codec_init(api)) { |
186 | return CODEC_ERROR; | 191 | return CODEC_ERROR; |
187 | } | 192 | } |
188 | 193 | ||
194 | while (!rb->taginfo_ready) | ||
195 | rb->yield(); | ||
196 | |||
197 | if (rb->id3->frequency != NATIVE_FREQUENCY) { | ||
198 | rb->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency)); | ||
199 | rb->configure(CODEC_DSP_ENABLE, (bool *)true); | ||
200 | } else { | ||
201 | rb->configure(CODEC_DSP_ENABLE, (bool *)false); | ||
202 | } | ||
203 | |||
189 | /* Create a decoder instance */ | 204 | /* Create a decoder instance */ |
190 | 205 | ||
191 | flacDecoder=FLAC__seekable_stream_decoder_new(); | 206 | flacDecoder=FLAC__seekable_stream_decoder_new(); |
diff --git a/apps/codecs/mpa.c b/apps/codecs/mpa.c index 736eef1ffe..f052b9df88 100644 --- a/apps/codecs/mpa.c +++ b/apps/codecs/mpa.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <codecs/libmad/mad.h> | 22 | #include <codecs/libmad/mad.h> |
23 | 23 | ||
24 | #include "playback.h" | 24 | #include "playback.h" |
25 | #include "dsp.h" | ||
25 | #include "mp3data.h" | 26 | #include "mp3data.h" |
26 | #include "lib/codeclib.h" | 27 | #include "lib/codeclib.h" |
27 | 28 | ||
@@ -29,7 +30,6 @@ struct mad_stream Stream IDATA_ATTR; | |||
29 | struct mad_frame Frame IDATA_ATTR; | 30 | struct mad_frame Frame IDATA_ATTR; |
30 | struct mad_synth Synth IDATA_ATTR; | 31 | struct mad_synth Synth IDATA_ATTR; |
31 | mad_timer_t Timer; | 32 | mad_timer_t Timer; |
32 | struct dither d0, d1; | ||
33 | 33 | ||
34 | /* The following function is used inside libmad - let's hope it's never | 34 | /* The following function is used inside libmad - let's hope it's never |
35 | called. | 35 | called. |
@@ -38,122 +38,6 @@ struct dither d0, d1; | |||
38 | void abort(void) { | 38 | void abort(void) { |
39 | } | 39 | } |
40 | 40 | ||
41 | /* The "dither" code to convert the 24-bit samples produced by libmad was | ||
42 | taken from the coolplayer project - coolplayer.sourceforge.net */ | ||
43 | |||
44 | struct dither { | ||
45 | mad_fixed_t error[3]; | ||
46 | mad_fixed_t random; | ||
47 | }; | ||
48 | |||
49 | # define SAMPLE_DEPTH 16 | ||
50 | # define scale(x, y) dither((x), (y)) | ||
51 | |||
52 | /* | ||
53 | * NAME: prng() | ||
54 | * DESCRIPTION: 32-bit pseudo-random number generator | ||
55 | */ | ||
56 | static __inline | ||
57 | unsigned long prng(unsigned long state) | ||
58 | { | ||
59 | return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL; | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * NAME: dither() | ||
64 | * DESCRIPTION: dither and scale sample | ||
65 | */ | ||
66 | inline int dither(mad_fixed_t sample, struct dither *dither) | ||
67 | { | ||
68 | unsigned int scalebits; | ||
69 | mad_fixed_t output, mask, random; | ||
70 | |||
71 | enum { | ||
72 | MIN = -MAD_F_ONE, | ||
73 | MAX = MAD_F_ONE - 1 | ||
74 | }; | ||
75 | |||
76 | /* noise shape */ | ||
77 | sample += dither->error[0] - dither->error[1] + dither->error[2]; | ||
78 | |||
79 | dither->error[2] = dither->error[1]; | ||
80 | dither->error[1] = dither->error[0]/2; | ||
81 | |||
82 | /* bias */ | ||
83 | output = sample + (1L << (MAD_F_FRACBITS + 1 - SAMPLE_DEPTH - 1)); | ||
84 | |||
85 | scalebits = MAD_F_FRACBITS + 1 - SAMPLE_DEPTH; | ||
86 | mask = (1L << scalebits) - 1; | ||
87 | |||
88 | /* dither */ | ||
89 | random = prng(dither->random); | ||
90 | output += (random & mask) - (dither->random & mask); | ||
91 | |||
92 | //dither->random = random; | ||
93 | |||
94 | /* clip */ | ||
95 | if (output > MAX) { | ||
96 | output = MAX; | ||
97 | |||
98 | if (sample > MAX) | ||
99 | sample = MAX; | ||
100 | } else if (output < MIN) { | ||
101 | output = MIN; | ||
102 | |||
103 | if (sample < MIN) | ||
104 | sample = MIN; | ||
105 | } | ||
106 | |||
107 | /* quantize */ | ||
108 | output &= ~mask; | ||
109 | |||
110 | /* error feedback */ | ||
111 | dither->error[0] = sample - output; | ||
112 | |||
113 | /* scale */ | ||
114 | return output >> scalebits; | ||
115 | } | ||
116 | |||
117 | inline int detect_silence(mad_fixed_t sample) | ||
118 | { | ||
119 | unsigned int scalebits; | ||
120 | mad_fixed_t output, mask; | ||
121 | |||
122 | enum { | ||
123 | MIN = -MAD_F_ONE, | ||
124 | MAX = MAD_F_ONE - 1 | ||
125 | }; | ||
126 | |||
127 | /* bias */ | ||
128 | output = sample + (1L << (MAD_F_FRACBITS + 1 - SAMPLE_DEPTH - 1)); | ||
129 | |||
130 | scalebits = MAD_F_FRACBITS + 1 - SAMPLE_DEPTH; | ||
131 | mask = (1L << scalebits) - 1; | ||
132 | |||
133 | /* clip */ | ||
134 | if (output > MAX) { | ||
135 | output = MAX; | ||
136 | |||
137 | if (sample > MAX) | ||
138 | sample = MAX; | ||
139 | } else if (output < MIN) { | ||
140 | output = MIN; | ||
141 | |||
142 | if (sample < MIN) | ||
143 | sample = MIN; | ||
144 | } | ||
145 | |||
146 | /* quantize */ | ||
147 | output &= ~mask; | ||
148 | |||
149 | /* scale */ | ||
150 | output >>= scalebits + 4; | ||
151 | |||
152 | if (output == 0x00 || output == 0xff) | ||
153 | return 1; | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | 41 | ||
158 | #define INPUT_CHUNK_SIZE 8192 | 42 | #define INPUT_CHUNK_SIZE 8192 |
159 | #define OUTPUT_BUFFER_SIZE 65536 /* Must be an integer multiple of 4. */ | 43 | #define OUTPUT_BUFFER_SIZE 65536 /* Must be an integer multiple of 4. */ |
@@ -162,7 +46,6 @@ unsigned char OutputBuffer[OUTPUT_BUFFER_SIZE]; | |||
162 | unsigned char *OutputPtr; | 46 | unsigned char *OutputPtr; |
163 | unsigned char *GuardPtr = NULL; | 47 | unsigned char *GuardPtr = NULL; |
164 | const unsigned char *OutputBufferEnd = OutputBuffer + OUTPUT_BUFFER_SIZE; | 48 | const unsigned char *OutputBufferEnd = OutputBuffer + OUTPUT_BUFFER_SIZE; |
165 | long resampled_data[2][5000]; /* enough to cope with 11khz upsampling */ | ||
166 | 49 | ||
167 | mad_fixed_t mad_frame_overlap[2][32][18] IDATA_ATTR; | 50 | mad_fixed_t mad_frame_overlap[2][32][18] IDATA_ATTR; |
168 | unsigned char mad_main_data[MAD_BUFFER_MDLEN] IDATA_ATTR; | 51 | unsigned char mad_main_data[MAD_BUFFER_MDLEN] IDATA_ATTR; |
@@ -174,73 +57,7 @@ extern char iramstart[]; | |||
174 | extern char iramend[]; | 57 | extern char iramend[]; |
175 | #endif | 58 | #endif |
176 | 59 | ||
177 | #undef DEBUG_GAPLESS | 60 | /* |
178 | |||
179 | struct resampler { | ||
180 | long last_sample, phase, delta; | ||
181 | }; | ||
182 | |||
183 | #if CONFIG_CPU==MCF5249 && !defined(SIMULATOR) | ||
184 | |||
185 | #define INIT() asm volatile ("move.l #0xb0, %macsr") /* frac, round, clip */ | ||
186 | #define FRACMUL(x, y) \ | ||
187 | ({ \ | ||
188 | long t; \ | ||
189 | asm volatile ("mac.l %[a], %[b], %%acc0\n\t" \ | ||
190 | "movclr.l %%acc0, %[t]\n\t" \ | ||
191 | : [t] "=r" (t) : [a] "r" (x), [b] "r" (y)); \ | ||
192 | t; \ | ||
193 | }) | ||
194 | |||
195 | #else | ||
196 | |||
197 | #define INIT() | ||
198 | #define FRACMUL(x, y) (long)(((long long)(x)*(long long)(y)) << 1) | ||
199 | #endif | ||
200 | |||
201 | /* linear resampling, introduces one sample delay, because of our inability to | ||
202 | look into the future at the end of a frame */ | ||
203 | long downsample(long *in, long *out, int num, struct resampler *s) | ||
204 | { | ||
205 | long i = 1, pos; | ||
206 | long last = s->last_sample; | ||
207 | |||
208 | INIT(); | ||
209 | pos = s->phase >> 16; | ||
210 | /* check if we need last sample of previous frame for interpolation */ | ||
211 | if (pos > 0) | ||
212 | last = in[pos - 1]; | ||
213 | out[0] = last + FRACMUL((s->phase & 0xffff) << 15, in[pos] - last); | ||
214 | s->phase += s->delta; | ||
215 | while ((pos = s->phase >> 16) < num) { | ||
216 | out[i++] = in[pos - 1] + FRACMUL((s->phase & 0xffff) << 15, in[pos] - in[pos - 1]); | ||
217 | s->phase += s->delta; | ||
218 | } | ||
219 | /* wrap phase accumulator back to start of next frame */ | ||
220 | s->phase -= num << 16; | ||
221 | s->last_sample = in[num - 1]; | ||
222 | return i; | ||
223 | } | ||
224 | |||
225 | long upsample(long *in, long *out, int num, struct resampler *s) | ||
226 | { | ||
227 | long i = 0, pos; | ||
228 | |||
229 | INIT(); | ||
230 | while ((pos = s->phase >> 16) == 0) { | ||
231 | out[i++] = s->last_sample + FRACMUL((s->phase & 0xffff) << 15, in[pos] - s->last_sample); | ||
232 | s->phase += s->delta; | ||
233 | } | ||
234 | while ((pos = s->phase >> 16) < num) { | ||
235 | out[i++] = in[pos - 1] + FRACMUL((s->phase & 0xffff) << 15, in[pos] - in[pos - 1]); | ||
236 | s->phase += s->delta; | ||
237 | } | ||
238 | /* wrap phase accumulator back to start of next frame */ | ||
239 | s->phase -= num << 16; | ||
240 | s->last_sample = in[num - 1]; | ||
241 | return i; | ||
242 | } | ||
243 | |||
244 | long resample(long *in, long *out, int num, struct resampler *s) | 61 | long resample(long *in, long *out, int num, struct resampler *s) |
245 | { | 62 | { |
246 | if (s->delta >= (1 << 16)) | 63 | if (s->delta >= (1 << 16)) |
@@ -248,7 +65,7 @@ long resample(long *in, long *out, int num, struct resampler *s) | |||
248 | else | 65 | else |
249 | return upsample(in, out, num, s); | 66 | return upsample(in, out, num, s); |
250 | } | 67 | } |
251 | 68 | */ | |
252 | /* this is the codec entry point */ | 69 | /* this is the codec entry point */ |
253 | enum codec_status codec_start(struct codec_api* api) | 70 | enum codec_status codec_start(struct codec_api* api) |
254 | { | 71 | { |
@@ -257,20 +74,12 @@ enum codec_status codec_start(struct codec_api* api) | |||
257 | int Status = 0; | 74 | int Status = 0; |
258 | size_t size; | 75 | size_t size; |
259 | int file_end; | 76 | int file_end; |
260 | unsigned short Sample; | ||
261 | char *InputBuffer; | 77 | char *InputBuffer; |
262 | unsigned int samplecount; | 78 | unsigned int samplecount; |
263 | unsigned int samplesdone; | 79 | unsigned int samplesdone; |
264 | bool first_frame; | 80 | bool first_frame; |
265 | #ifdef DEBUG_GAPLESS | ||
266 | bool first = true; | ||
267 | int fd; | ||
268 | #endif | ||
269 | int i; | ||
270 | int yieldcounter = 0; | ||
271 | int stop_skip, start_skip; | 81 | int stop_skip, start_skip; |
272 | struct resampler lr = { 0, 0, 0 }, rr = { 0, 0, 0 }; | 82 | // struct resampler lr = { 0, 0, 0 }, rr = { 0, 0, 0 }; |
273 | long length; | ||
274 | /* Generic codec inititialisation */ | 83 | /* Generic codec inititialisation */ |
275 | 84 | ||
276 | TEST_CODEC_API(api); | 85 | TEST_CODEC_API(api); |
@@ -289,7 +98,13 @@ enum codec_status codec_start(struct codec_api* api) | |||
289 | 98 | ||
290 | ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2)); | 99 | ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2)); |
291 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*16)); | 100 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*16)); |
292 | 101 | ci->configure(DSP_SET_CLIP_MIN, (int *)-MAD_F_ONE); | |
102 | ci->configure(DSP_SET_CLIP_MAX, (int *)(MAD_F_ONE - 1)); | ||
103 | ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(MAD_F_FRACBITS)); | ||
104 | ci->configure(DSP_DITHER, (bool *)true); | ||
105 | ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_NONINTERLEAVED); | ||
106 | ci->configure(CODEC_DSP_ENABLE, (bool *)true); | ||
107 | |||
293 | ci->memset(&Stream, 0, sizeof(struct mad_stream)); | 108 | ci->memset(&Stream, 0, sizeof(struct mad_stream)); |
294 | ci->memset(&Frame, 0, sizeof(struct mad_frame)); | 109 | ci->memset(&Frame, 0, sizeof(struct mad_frame)); |
295 | ci->memset(&Synth, 0, sizeof(struct mad_synth)); | 110 | ci->memset(&Synth, 0, sizeof(struct mad_synth)); |
@@ -309,14 +124,6 @@ enum codec_status codec_start(struct codec_api* api) | |||
309 | for gapless playback */ | 124 | for gapless playback */ |
310 | next_track: | 125 | next_track: |
311 | 126 | ||
312 | #ifdef DEBUG_GAPLESS | ||
313 | if (first) | ||
314 | fd = ci->open("/first.pcm", O_WRONLY | O_CREAT); | ||
315 | else | ||
316 | fd = ci->open("/second.pcm", O_WRONLY | O_CREAT); | ||
317 | first = false; | ||
318 | #endif | ||
319 | |||
320 | info = ci->mp3data; | 127 | info = ci->mp3data; |
321 | first_frame = false; | 128 | first_frame = false; |
322 | file_end = 0; | 129 | file_end = 0; |
@@ -325,6 +132,8 @@ enum codec_status codec_start(struct codec_api* api) | |||
325 | while (!*ci->taginfo_ready) | 132 | while (!*ci->taginfo_ready) |
326 | ci->yield(); | 133 | ci->yield(); |
327 | 134 | ||
135 | ci->configure(DSP_SET_FREQUENCY, (int *)ci->id3->frequency); | ||
136 | |||
328 | ci->request_buffer(&size, ci->id3->first_frame_offset); | 137 | ci->request_buffer(&size, ci->id3->first_frame_offset); |
329 | ci->advance_buffer(size); | 138 | ci->advance_buffer(size); |
330 | 139 | ||
@@ -350,13 +159,7 @@ enum codec_status codec_start(struct codec_api* api) | |||
350 | samplecount = ci->id3->length * (ci->id3->frequency / 100) / 10; | 159 | samplecount = ci->id3->length * (ci->id3->frequency / 100) / 10; |
351 | samplesdone = ci->id3->elapsed * (ci->id3->frequency / 100) / 10; | 160 | samplesdone = ci->id3->elapsed * (ci->id3->frequency / 100) / 10; |
352 | } | 161 | } |
353 | /* rb->snprintf(buf2, sizeof(buf2), "sc: %d", samplecount); | 162 | |
354 | rb->splash(0, true, buf2); | ||
355 | rb->snprintf(buf2, sizeof(buf2), "length: %d", ci->id3->length); | ||
356 | rb->splash(HZ*5, true, buf2); | ||
357 | rb->snprintf(buf2, sizeof(buf2), "frequency: %d", ci->id3->frequency); | ||
358 | rb->splash(HZ*5, true, buf2); */ | ||
359 | lr.delta = rr.delta = ci->id3->frequency*65536/44100; | ||
360 | /* This is the decoding loop. */ | 163 | /* This is the decoding loop. */ |
361 | while (1) { | 164 | while (1) { |
362 | ci->yield(); | 165 | ci->yield(); |
@@ -387,9 +190,6 @@ enum codec_status codec_start(struct codec_api* api) | |||
387 | mad_stream_buffer(&Stream, InputBuffer, size); | 190 | mad_stream_buffer(&Stream, InputBuffer, size); |
388 | } | 191 | } |
389 | 192 | ||
390 | //if ((int)ci->curpos >= ci->id3->first_frame_offset) | ||
391 | //first_frame = true; | ||
392 | |||
393 | if(mad_frame_decode(&Frame,&Stream)) | 193 | if(mad_frame_decode(&Frame,&Stream)) |
394 | { | 194 | { |
395 | if (Stream.error == MAD_FLAG_INCOMPLETE || Stream.error == MAD_ERROR_BUFLEN) { | 195 | if (Stream.error == MAD_FLAG_INCOMPLETE || Stream.error == MAD_ERROR_BUFLEN) { |
@@ -428,78 +228,23 @@ enum codec_status codec_start(struct codec_api* api) | |||
428 | 228 | ||
429 | mad_synth_frame(&Synth,&Frame); | 229 | mad_synth_frame(&Synth,&Frame); |
430 | 230 | ||
431 | //if (!first_frame) { | ||
432 | //samplecount -= Synth.pcm.length; | ||
433 | //continue ; | ||
434 | //} | ||
435 | |||
436 | /* Convert MAD's numbers to an array of 16-bit LE signed integers */ | 231 | /* Convert MAD's numbers to an array of 16-bit LE signed integers */ |
437 | /* We skip start_skip number of samples here, this should only happen for | 232 | /* We skip start_skip number of samples here, this should only happen for |
438 | very first frame in the stream. */ | 233 | very first frame in the stream. */ |
439 | /* TODO: possible for start_skip to exceed one frames worth of samples? */ | 234 | /* TODO: possible for start_skip to exceed one frames worth of samples? */ |
440 | length = resample((long *)&Synth.pcm.samples[0][start_skip], resampled_data[0], Synth.pcm.length, &lr); | 235 | //length = resample((long *)&Synth.pcm.samples[0][start_skip], resampled_data[0], Synth.pcm.length, &lr); |
441 | if (MAD_NCHANNELS(&Frame.header) == 2) | 236 | //if (MAD_NCHANNELS(&Frame.header) == 2) |
442 | resample((long *)&Synth.pcm.samples[1][start_skip], resampled_data[1], Synth.pcm.length, &rr); | 237 | // resample((long *)&Synth.pcm.samples[1][start_skip], resampled_data[1], Synth.pcm.length, &rr); |
443 | for (i = 0; i < length; i++) | 238 | ci->audiobuffer_insert_split(&Synth.pcm.samples[0][start_skip], |
444 | { | 239 | &Synth.pcm.samples[1][start_skip], |
445 | start_skip = 0; /* not very elegant, and might want to keep this value */ | 240 | (Synth.pcm.length - start_skip) * 4); |
446 | samplesdone++; | 241 | start_skip = 0; /* not very elegant, and might want to keep this value */ |
447 | //if (ci->mp3data->padding > 0) { | 242 | |
448 | // ci->mp3data->padding--; | 243 | samplesdone += Synth.pcm.length; |
449 | // continue ; | 244 | samplecount -= Synth.pcm.length; |
450 | //} | ||
451 | /*if (!first_frame) { | ||
452 | if (detect_silence(Synth.pcm.samples[0][i])) | ||
453 | continue ; | ||
454 | first_frame = true; | ||
455 | }*/ | ||
456 | |||
457 | /* Left channel */ | ||
458 | Sample = scale(resampled_data[0][i], &d0); | ||
459 | *(OutputPtr++) = Sample >> 8; | ||
460 | *(OutputPtr++) = Sample & 0xff; | ||
461 | |||
462 | /* Right channel. If the decoded stream is monophonic then | ||
463 | * the right output channel is the same as the left one. | ||
464 | */ | ||
465 | if (MAD_NCHANNELS(&Frame.header) == 2) | ||
466 | Sample = scale(resampled_data[1][i], &d1); | ||
467 | *(OutputPtr++) = Sample >> 8; | ||
468 | *(OutputPtr++) = Sample & 0xff; | ||
469 | |||
470 | samplecount--; | ||
471 | if (samplecount == 0) { | ||
472 | #ifdef DEBUG_GAPLESS | ||
473 | ci->write(fd, OutputBuffer, (int)OutputPtr - (int)OutputBuffer); | ||
474 | #endif | ||
475 | while (!ci->audiobuffer_insert(OutputBuffer, (int)OutputPtr - (int)OutputBuffer)) | ||
476 | ci->yield(); | ||
477 | goto song_end; | ||
478 | } | ||
479 | |||
480 | if (yieldcounter++ == 200) { | ||
481 | ci->yield(); | ||
482 | yieldcounter = 0; | ||
483 | } | ||
484 | |||
485 | /* Flush the buffer if it is full. */ | ||
486 | if (OutputPtr == OutputBufferEnd) | ||
487 | { | ||
488 | #ifdef DEBUG_GAPLESS | ||
489 | ci->write(fd, OutputBuffer, OUTPUT_BUFFER_SIZE); | ||
490 | #endif | ||
491 | while (!ci->audiobuffer_insert(OutputBuffer, OUTPUT_BUFFER_SIZE)) | ||
492 | ci->yield(); | ||
493 | OutputPtr = OutputBuffer; | ||
494 | } | ||
495 | } | ||
496 | ci->set_elapsed(samplesdone / (ci->id3->frequency/1000)); | 245 | ci->set_elapsed(samplesdone / (ci->id3->frequency/1000)); |
497 | } | 246 | } |
498 | 247 | ||
499 | song_end: | ||
500 | #ifdef DEBUG_GAPLESS | ||
501 | ci->close(fd); | ||
502 | #endif | ||
503 | Stream.error = 0; | 248 | Stream.error = 0; |
504 | 249 | ||
505 | if (ci->request_next_track()) | 250 | if (ci->request_next_track()) |
diff --git a/apps/codecs/vorbis.c b/apps/codecs/vorbis.c index f2939aa68d..9afeb053e1 100644 --- a/apps/codecs/vorbis.c +++ b/apps/codecs/vorbis.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include "Tremor/ivorbisfile.h" | 22 | #include "Tremor/ivorbisfile.h" |
23 | #include "playback.h" | 23 | #include "playback.h" |
24 | #include "dsp.h" | ||
24 | #include "lib/codeclib.h" | 25 | #include "lib/codeclib.h" |
25 | 26 | ||
26 | static struct codec_api* rb; | 27 | static struct codec_api* rb; |
@@ -92,10 +93,6 @@ enum codec_status codec_start(struct codec_api* api) | |||
92 | long n; | 93 | long n; |
93 | int current_section; | 94 | int current_section; |
94 | int eof; | 95 | int eof; |
95 | #if BYTE_ORDER == BIG_ENDIAN | ||
96 | int i; | ||
97 | char x; | ||
98 | #endif | ||
99 | 96 | ||
100 | TEST_CODEC_API(api); | 97 | TEST_CODEC_API(api); |
101 | 98 | ||
@@ -110,15 +107,27 @@ enum codec_status codec_start(struct codec_api* api) | |||
110 | rb->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2)); | 107 | rb->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2)); |
111 | rb->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*64)); | 108 | rb->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*64)); |
112 | 109 | ||
113 | /* We need to flush reserver memory every track load. */ | 110 | rb->configure(DSP_DITHER, (bool *)false); |
111 | rb->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED); | ||
112 | rb->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16)); | ||
113 | |||
114 | /* We need to flush reserver memory every track load. */ | ||
114 | next_track: | 115 | next_track: |
115 | if (codec_init(rb)) { | 116 | if (codec_init(rb)) { |
116 | return CODEC_ERROR; | 117 | return CODEC_ERROR; |
117 | } | 118 | } |
118 | 119 | ||
119 | 120 | while (!rb->taginfo_ready) | |
121 | rb->yield(); | ||
122 | |||
123 | if (rb->id3->frequency != NATIVE_FREQUENCY) { | ||
124 | rb->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency)); | ||
125 | rb->configure(CODEC_DSP_ENABLE, (bool *)true); | ||
126 | } else { | ||
127 | rb->configure(CODEC_DSP_ENABLE, (bool *)false); | ||
128 | } | ||
129 | |||
120 | /* Create a decoder instance */ | 130 | /* Create a decoder instance */ |
121 | |||
122 | callbacks.read_func=read_handler; | 131 | callbacks.read_func=read_handler; |
123 | callbacks.seek_func=seek_handler; | 132 | callbacks.seek_func=seek_handler; |
124 | callbacks.tell_func=tell_handler; | 133 | callbacks.tell_func=tell_handler; |
@@ -148,17 +157,10 @@ enum codec_status codec_start(struct codec_api* api) | |||
148 | if (rb->stop_codec || rb->reload_codec) | 157 | if (rb->stop_codec || rb->reload_codec) |
149 | break ; | 158 | break ; |
150 | 159 | ||
151 | rb->yield(); | ||
152 | while (!rb->audiobuffer_insert(pcmbuf, n)) | 160 | while (!rb->audiobuffer_insert(pcmbuf, n)) |
153 | rb->yield(); | 161 | rb->yield(); |
154 | 162 | ||
155 | rb->set_elapsed(ov_time_tell(&vf)); | 163 | rb->set_elapsed(ov_time_tell(&vf)); |
156 | |||
157 | #if BYTE_ORDER == BIG_ENDIAN | ||
158 | for (i=0;i<n;i+=2) { | ||
159 | x=pcmbuf[i]; pcmbuf[i]=pcmbuf[i+1]; pcmbuf[i+1]=x; | ||
160 | } | ||
161 | #endif | ||
162 | } | 164 | } |
163 | } | 165 | } |
164 | 166 | ||
diff --git a/apps/codecs/wav.c b/apps/codecs/wav.c index dfed97d64c..49bd12da1f 100644 --- a/apps/codecs/wav.c +++ b/apps/codecs/wav.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include "codec.h" | 20 | #include "codec.h" |
21 | #include "playback.h" | 21 | #include "playback.h" |
22 | #include "lib/codeclib.h" | 22 | #include "lib/codeclib.h" |
23 | #include "dsp.h" | ||
23 | 24 | ||
24 | #define BYTESWAP(x) (((x>>8) & 0xff) | ((x<<8) & 0xff00)) | 25 | #define BYTESWAP(x) (((x>>8) & 0xff) | ((x<<8) & 0xff00)) |
25 | 26 | ||
@@ -60,12 +61,26 @@ enum codec_status codec_start(struct codec_api* api) | |||
60 | ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512)); | 61 | ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512)); |
61 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*256)); | 62 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*256)); |
62 | 63 | ||
64 | ci->configure(DSP_DITHER, (bool *)false); | ||
65 | ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED); | ||
66 | ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16)); | ||
67 | |||
63 | next_track: | 68 | next_track: |
64 | 69 | ||
65 | if (codec_init(api)) { | 70 | if (codec_init(api)) { |
66 | return CODEC_ERROR; | 71 | return CODEC_ERROR; |
67 | } | 72 | } |
68 | 73 | ||
74 | while (!rb->taginfo_ready) | ||
75 | rb->yield(); | ||
76 | |||
77 | if (rb->id3->frequency != NATIVE_FREQUENCY) { | ||
78 | rb->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency)); | ||
79 | rb->configure(CODEC_DSP_ENABLE, (bool *)true); | ||
80 | } else { | ||
81 | rb->configure(CODEC_DSP_ENABLE, (bool *)false); | ||
82 | } | ||
83 | |||
69 | /* FIX: Correctly parse WAV header - we assume canonical 44-byte header */ | 84 | /* FIX: Correctly parse WAV header - we assume canonical 44-byte header */ |
70 | 85 | ||
71 | header=ci->request_buffer(&n,44); | 86 | header=ci->request_buffer(&n,44); |
@@ -116,7 +131,7 @@ enum codec_status codec_start(struct codec_api* api) | |||
116 | 131 | ||
117 | /* Byte-swap data */ | 132 | /* Byte-swap data */ |
118 | for (i=0;i<n/2;i++) { | 133 | for (i=0;i<n/2;i++) { |
119 | wavbuf[i]=BYTESWAP(wavbuf[i]); | 134 | wavbuf[i]=SWAB16(wavbuf[i]); |
120 | } | 135 | } |
121 | 136 | ||
122 | samplesdone+=nsamples; | 137 | samplesdone+=nsamples; |
diff --git a/apps/codecs/wavpack.c b/apps/codecs/wavpack.c index 2ea8f052df..275f5f11e4 100644 --- a/apps/codecs/wavpack.c +++ b/apps/codecs/wavpack.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <codecs/libwavpack/wavpack.h> | 22 | #include <codecs/libwavpack/wavpack.h> |
23 | #include "playback.h" | 23 | #include "playback.h" |
24 | #include "lib/codeclib.h" | 24 | #include "lib/codeclib.h" |
25 | #include "dsp.h" | ||
25 | 26 | ||
26 | static struct codec_api *rb; | 27 | static struct codec_api *rb; |
27 | static struct codec_api *ci; | 28 | static struct codec_api *ci; |
@@ -61,14 +62,27 @@ enum codec_status codec_start(struct codec_api* api) | |||
61 | ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*10)); | 62 | ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*10)); |
62 | ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512)); | 63 | ci->configure(CODEC_SET_FILEBUF_WATERMARK, (int *)(1024*512)); |
63 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*128)); | 64 | ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*128)); |
65 | |||
66 | ci->configure(DSP_DITHER, (bool *)false); | ||
67 | ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED); | ||
68 | ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16)); | ||
64 | 69 | ||
65 | next_track: | 70 | next_track: |
66 | 71 | ||
67 | if (codec_init(api)) | 72 | if (codec_init(api)) |
68 | return CODEC_ERROR; | 73 | return CODEC_ERROR; |
69 | 74 | ||
75 | while (!rb->taginfo_ready) | ||
76 | ci->yield(); | ||
77 | |||
78 | if (ci->id3->frequency != NATIVE_FREQUENCY) { | ||
79 | ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency)); | ||
80 | ci->configure(CODEC_DSP_ENABLE, (bool *)true); | ||
81 | } else { | ||
82 | ci->configure(CODEC_DSP_ENABLE, (bool *)false); | ||
83 | } | ||
84 | |||
70 | /* Create a decoder instance */ | 85 | /* Create a decoder instance */ |
71 | |||
72 | wpc = WavpackOpenFileInput (read_callback, error); | 86 | wpc = WavpackOpenFileInput (read_callback, error); |
73 | 87 | ||
74 | if (!wpc) | 88 | if (!wpc) |