diff options
| author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
|---|---|---|
| committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
| commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
| tree | 9b20069d5e62809ff434061ad730096836f916f2 /apps/codecs/a52_rm.c | |
| parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
| download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.bz2 rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.xz | |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'apps/codecs/a52_rm.c')
| -rw-r--r-- | apps/codecs/a52_rm.c | 227 |
1 files changed, 0 insertions, 227 deletions
diff --git a/apps/codecs/a52_rm.c b/apps/codecs/a52_rm.c deleted file mode 100644 index 207c282..0000000 --- a/apps/codecs/a52_rm.c +++ /dev/null @@ -1,227 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2009 Mohamed Tarek - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#include "codeclib.h" -#include <codecs/librm/rm.h> -#include <inttypes.h> /* Needed by a52.h */ -#include <codecs/liba52/config-a52.h> -#include <codecs/liba52/a52.h> - -CODEC_HEADER - -#define BUFFER_SIZE 4096 - -#define A52_SAMPLESPERFRAME (6*256) - -static a52_state_t *state; -static unsigned long samplesdone; -static unsigned long frequency; -static RMContext rmctx; -static RMPacket pkt; - -static void init_rm(RMContext *rmctx) -{ - memcpy(rmctx, (void*)(( (intptr_t)ci->id3->id3v2buf + 3 ) &~ 3), sizeof(RMContext)); -} - -/* used outside liba52 */ -static uint8_t buf[3840] IBSS_ATTR; - -/* The following two functions, a52_decode_data and output_audio are taken from apps/codecs/a52.c */ -static inline void output_audio(sample_t *samples) -{ - ci->yield(); - ci->pcmbuf_insert(&samples[0], &samples[256], 256); -} - -static 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 { - /* Unity gain is 1 << 26, and we want to end up on 28 bits - of precision instead of the default 30. - */ - level_t level = 1 << 24; - sample_t bias = 0; - int i; - - /* This is the configuration for the downmixing: */ - flags = A52_STEREO | A52_ADJUST_LEVEL; - - if (a52_frame(state, buf, &flags, &level, bias)) - goto error; - a52_dynrng(state, NULL, NULL); - 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)); - 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; - } - } - } -} - -/* this is the codec entry point */ -enum codec_status codec_main(enum codec_entry_call_reason reason) -{ - if (reason == CODEC_LOAD) { - /* Generic codec initialisation */ - ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED); - ci->configure(DSP_SET_SAMPLE_DEPTH, 28); - } - else if (reason == CODEC_UNLOAD) { - if (state) - a52_free(state); - } - - return CODEC_OK; -} - -/* this is called for each file to process */ -enum codec_status codec_run(void) -{ - size_t n; - uint8_t *filebuf; - int consumed, packet_offset; - int playback_on = -1; - size_t resume_offset; - intptr_t param; - enum codec_command_action action = CODEC_ACTION_NULL; - - if (codec_init()) { - return CODEC_ERROR; - } - - resume_offset = ci->id3->offset; - - ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); - codec_set_replaygain(ci->id3); - - ci->seek_buffer(ci->id3->first_frame_offset); - - /* Intializations */ - state = a52_init(0); - ci->memset(&rmctx,0,sizeof(RMContext)); - ci->memset(&pkt,0,sizeof(RMPacket)); - init_rm(&rmctx); - - samplesdone = 0; - - /* check for a mid-track resume and force a seek time accordingly */ - if(resume_offset > rmctx.data_offset + DATA_HEADER_SIZE) { - resume_offset -= rmctx.data_offset + DATA_HEADER_SIZE; - /* put number of subpackets to skip in resume_offset */ - resume_offset /= (rmctx.block_align + PACKET_HEADER_SIZE); - param = (int)resume_offset * ((rmctx.block_align * 8 * 1000)/rmctx.bit_rate); - action = CODEC_ACTION_SEEK_TIME; - } - else { - /* Seek to the first packet */ - ci->set_elapsed(0); - ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE ); - } - - /* The main decoding loop */ - while((unsigned)rmctx.audio_pkt_cnt < rmctx.nb_packets) { - if (action == CODEC_ACTION_NULL) - action = ci->get_command(¶m); - - if (action == CODEC_ACTION_HALT) - break; - - if (action == CODEC_ACTION_SEEK_TIME) { - packet_offset = param / ((rmctx.block_align*8*1000)/rmctx.bit_rate); - ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE + - packet_offset*(rmctx.block_align + PACKET_HEADER_SIZE)); - rmctx.audio_pkt_cnt = packet_offset; - samplesdone = (rmctx.sample_rate/1000 * param); - ci->set_elapsed(samplesdone/(frequency/1000)); - ci->seek_complete(); - } - - action = CODEC_ACTION_NULL; - - filebuf = ci->request_buffer(&n, rmctx.block_align + PACKET_HEADER_SIZE); - consumed = rm_get_packet(&filebuf, &rmctx, &pkt); - - if(consumed < 0 && playback_on != 0) { - if(playback_on == -1) { - /* Error only if packet-parsing failed and playback hadn't started */ - DEBUGF("rm_get_packet failed\n"); - return CODEC_ERROR; - } - else { - break; - } - } - - playback_on = 1; - a52_decode_data(filebuf, filebuf + rmctx.block_align); - ci->advance_buffer(pkt.length); - } - - return CODEC_OK; -} |