summaryrefslogtreecommitdiff
path: root/apps/codecs/a52.c
diff options
context:
space:
mode:
authorThom Johansen <thomj@rockbox.org>2005-10-10 23:37:30 +0000
committerThom Johansen <thomj@rockbox.org>2005-10-10 23:37:30 +0000
commit6762810ba601ea8c2c97c95c631828fa854b712b (patch)
treed8d372a8318b936707344c5508a628e7a6db120f /apps/codecs/a52.c
parentb91e9fdfa94fa4e3cf7b85c830ccf67071ca0fe6 (diff)
downloadrockbox-6762810ba601ea8c2c97c95c631828fa854b712b.zip
rockbox-6762810ba601ea8c2c97c95c631828fa854b712b.tar.gz
rockbox-6762810ba601ea8c2c97c95c631828fa854b712b.tar.bz2
rockbox-6762810ba601ea8c2c97c95c631828fa854b712b.tar.xz
Cleaned up code. Now passes full precision samples to the playback engine, and DSP is enabled.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7620 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/a52.c')
-rw-r--r--apps/codecs/a52.c293
1 files changed, 122 insertions, 171 deletions
diff --git a/apps/codecs/a52.c b/apps/codecs/a52.c
index 3dacc52..81d8e35 100644
--- a/apps/codecs/a52.c
+++ b/apps/codecs/a52.c
@@ -18,208 +18,159 @@
****************************************************************************/
#include "codec.h"
-
+#include "lib/codeclib.h"
#include <inttypes.h> /* Needed by a52.h */
#include <codecs/liba52/config-a52.h>
#include <codecs/liba52/a52.h>
-#include "playback.h"
-#include "dsp.h"
-#include "lib/codeclib.h"
-
#define BUFFER_SIZE 4096
-struct codec_api* rb;
-struct codec_api* ci;
+struct codec_api *ci;
-static float gain = 1;
-static a52_state_t * state;
+static a52_state_t *state;
unsigned long samplesdone;
unsigned long frequency;
-/* Two buffers used outside liba52 */
+/* used outside liba52 */
static uint8_t buf[3840] IDATA_ATTR;
-static int16_t int16_samples[256*2] IDATA_ATTR;
-static inline int16_t convert (int32_t i)
+void output_audio(sample_t *samples, int flags)
{
- i >>= 15;
- return (i > 32767) ? 32767 : ((i < -32768) ? -32768 : i);
-}
-
-void output_audio(sample_t* samples,int flags) {
- int i;
-
- flags &= A52_CHANNEL_MASK | A52_LFE;
+ flags &= A52_CHANNEL_MASK | A52_LFE;
- /* We may need to check the output format in flags - I'm not sure... */
- for (i = 0; i < 256; i++) {
- int16_samples[2*i] = convert (samples[i]);
- int16_samples[2*i+1] = convert (samples[i+256]);
- }
-
- rb->yield();
- while(!ci->pcmbuf_insert((unsigned char*)int16_samples,256*2*2))
- rb->yield();
+ do {
+ ci->yield();
+ } while (!ci->pcmbuf_insert_split(&samples[0], &samples[256],
+ 256*sizeof(sample_t)));
}
-
-void a52_decode_data (uint8_t * start, uint8_t * end)
+void a52_decode_data(uint8_t *start, uint8_t *end)
{
- static uint8_t * bufptr = buf;
- static uint8_t * bufpos = buf + 7;
-
- /*
- * sample_rate and flags are static because this routine could
- * exit between the a52_syncinfo() and the ao_setup(), and we want
- * to have the same values when we get back !
- */
-
- static int sample_rate;
- static int flags;
- int bit_rate;
- int len;
-
- while (1) {
- len = end - start;
- if (!len)
- break;
- if (len > bufpos - bufptr)
- len = bufpos - bufptr;
- memcpy (bufptr, start, len);
- bufptr += len;
- start += len;
- if (bufptr == bufpos) {
- if (bufpos == buf + 7) {
- int length;
-
- length = a52_syncinfo (buf, &flags, &sample_rate, &bit_rate);
- if (!length) {
- DEBUGF("skip\n");
- for (bufptr = buf; bufptr < buf + 6; bufptr++)
- bufptr[0] = bufptr[1];
- continue;
- }
- bufpos = buf + length;
- } else {
- // The following two defaults are taken from audio_out_oss.c:
- level_t level;
- sample_t bias;
- int i;
-
- /* This is the configuration for the downmixing: */
- flags=A52_STEREO|A52_ADJUST_LEVEL|A52_LFE;
- level=(1 << 26);
- bias=0;
-
- level = (level_t) (level * gain);
-
- if (a52_frame (state, buf, &flags, &level, bias)) {
- goto error;
- }
-
-// file_info->frames_decoded++;
-
-// /* We assume this never changes */
-// file_info->samplerate=sample_rate;
- frequency=sample_rate;
-
- // An A52 frame consists of 6 blocks of 256 samples
- // So we decode and output them one block at a time
- for (i = 0; i < 6; i++) {
- if (a52_block (state)) {
- goto error;
- }
-
- output_audio(a52_samples (state),flags);
- samplesdone+=256;
- }
- ci->set_elapsed(samplesdone/(frequency/1000));
- bufptr = buf;
- bufpos = buf + 7;
- continue;
-
- error:
-
- //logf("Error decoding A52 stream\n");
- bufptr = buf;
- bufpos = buf + 7;
- }
+ static uint8_t *bufptr = buf;
+ static uint8_t *bufpos = buf + 7;
+ /*
+ * sample_rate and flags are static because this routine could
+ * exit between the a52_syncinfo() and the ao_setup(), and we want
+ * to have the same values when we get back !
+ */
+ static int sample_rate;
+ static int flags;
+ int bit_rate;
+ int len;
+
+ while (1) {
+ len = end - start;
+ if (!len)
+ break;
+ if (len > bufpos - bufptr)
+ len = bufpos - bufptr;
+ memcpy(bufptr, start, len);
+ bufptr += len;
+ start += len;
+ if (bufptr == bufpos) {
+ if (bufpos == buf + 7) {
+ int length;
+
+ length = a52_syncinfo(buf, &flags, &sample_rate, &bit_rate);
+ if (!length) {
+ //DEBUGF("skip\n");
+ for (bufptr = buf; bufptr < buf + 6; bufptr++)
+ bufptr[0] = bufptr[1];
+ continue;
+ }
+ bufpos = buf + length;
+ } else {
+ /* The following two defaults are taken from audio_out_oss.c: */
+ level_t level = 1 << 26;
+ sample_t bias = 0;
+ int i;
+
+ /* This is the configuration for the downmixing: */
+ flags = A52_STEREO | A52_ADJUST_LEVEL | A52_LFE;
+
+ if (a52_frame(state, buf, &flags, &level, bias))
+ goto error;
+
+ frequency = sample_rate;
+
+ /* An A52 frame consists of 6 blocks of 256 samples
+ So we decode and output them one block at a time */
+ for (i = 0; i < 6; i++) {
+ if (a52_block(state))
+ goto error;
+ output_audio(a52_samples(state), flags);
+ samplesdone += 256;
+ }
+ ci->set_elapsed(samplesdone/(frequency/1000));
+ bufptr = buf;
+ bufpos = buf + 7;
+ continue;
+ error:
+ //logf("Error decoding A52 stream\n");
+ bufptr = buf;
+ bufpos = buf + 7;
+ }
+ }
}
- }
}
-#ifndef SIMULATOR
+#ifdef USE_IRAM
extern char iramcopy[];
extern char iramstart[];
extern char iramend[];
#endif
/* this is the codec entry point */
-enum codec_status codec_start(struct codec_api* api)
+enum codec_status codec_start(struct codec_api *api)
{
- size_t n;
- unsigned char* filebuf;
-
- /* Generic codec initialisation */
- TEST_CODEC_API(api);
-
- rb = api;
- ci = (struct codec_api*)api;
-
-#ifndef SIMULATOR
- rb->memcpy(iramstart, iramcopy, iramend-iramstart);
-#endif
-
- ci->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2));
- ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*128));
-
- ci->configure(DSP_DITHER, (bool *)false);
- ci->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED);
- ci->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16));
-
- next_track:
-
- if (codec_init(api)) {
- return CODEC_ERROR;
- }
-
- while (!rb->taginfo_ready)
- rb->yield();
+ size_t n;
+ unsigned char *filebuf;
+
+ /* Generic codec initialisation */
+ TEST_CODEC_API(api);
+ ci = api;
+
+ #ifdef USE_IRAM
+ ci->memcpy(iramstart, iramcopy, iramend - iramstart);
+ #endif
+
+ ci->configure(CODEC_DSP_ENABLE, (bool *)true);
+ ci->configure(DSP_DITHER, (bool *)false);
+ ci->configure(DSP_SET_STEREO_MODE, (long *)STEREO_NONINTERLEAVED);
+ ci->configure(DSP_SET_SAMPLE_DEPTH, (long *)30);
+ ci->configure(DSP_SET_CLIP_MAX, (long *)((1 << 30) - 1));
+ ci->configure(DSP_SET_CLIP_MIN, (long *)-(1 << 30));
+ ci->configure(CODEC_SET_FILEBUF_LIMIT, (long *)(1024*1024*2));
+ ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (long *)(1024*128));
+
+next_track:
+ if (codec_init(api))
+ return CODEC_ERROR;
+
+ while (!ci->taginfo_ready)
+ ci->yield();
- if (rb->id3->frequency != NATIVE_FREQUENCY) {
- rb->configure(DSP_SET_FREQUENCY, (long *)(rb->id3->frequency));
- rb->configure(CODEC_DSP_ENABLE, (bool *)true);
- } else {
- rb->configure(CODEC_DSP_ENABLE, (bool *)false);
- }
+ ci->configure(DSP_SET_FREQUENCY, (long *)(ci->id3->frequency));
- /* Intialise the A52 decoder and check for success */
- state = a52_init (0); // Parameter is "accel"
-
- /* The main decoding loop */
+ /* Intialise the A52 decoder and check for success */
+ state = a52_init(0);
- samplesdone=0;
- while (1) {
- if (ci->stop_codec || ci->reload_codec) {
- break;
- }
+ /* The main decoding loop */
+ samplesdone = 0;
+ while (1) {
+ if (ci->stop_codec || ci->reload_codec)
+ break;
- filebuf=ci->request_buffer(&n,BUFFER_SIZE);
+ filebuf = ci->request_buffer(&n, BUFFER_SIZE);
- if (n==0) { /* End of Stream */
- break;
- }
+ if (n == 0) /* End of Stream */
+ break;
- a52_decode_data(filebuf,filebuf+n);
-
- ci->advance_buffer(n);
- }
-
- if (ci->request_next_track())
- goto next_track;
-
-//NOT NEEDED??: a52_free (state);
-
- return CODEC_OK;
+ a52_decode_data(filebuf, filebuf + n);
+ ci->advance_buffer(n);
+ }
+ if (ci->request_next_track())
+ goto next_track;
+ a52_free(state);
+ return CODEC_OK;
}