/*************************************************************************** * __________ __ ___. * 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 "librm/rm.h" #include "libfaad/common.h" #include "libfaad/structs.h" #include "libfaad/decoder.h" /* rockbox: not used #include "libfaad/output.h" */ CODEC_HEADER static void init_rm(RMContext *rmctx) { memcpy(rmctx, (void*)(( (intptr_t)ci->id3->id3v2buf + 3 ) &~ 3), sizeof(RMContext)); } static RMContext rmctx; static RMPacket pkt; /* 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, 29); } return CODEC_OK; } /* this is called for each file to process */ enum codec_status codec_run(void) { static NeAACDecFrameInfo frame_info; NeAACDecHandle decoder; size_t n; unsigned int i; unsigned char* buffer; int err, consumed, pkt_offset, skipped = 0; uint32_t s = 0; /* sample rate */ unsigned char c = 0; /* channels */ int playback_on = -1; size_t resume_offset; intptr_t param; enum codec_command_action action = CODEC_ACTION_NULL; if (codec_init()) { DEBUGF("FAAD: Codec init error\n"); return CODEC_ERROR; } resume_offset = ci->id3->offset; ci->memset(&rmctx,0,sizeof(RMContext)); ci->memset(&pkt,0,sizeof(RMPacket)); ci->seek_buffer(0); init_rm(&rmctx); ci->configure(DSP_SWITCH_FREQUENCY, ci->id3->frequency); codec_set_replaygain(ci->id3); /* initialise the sound converter */ decoder = NeAACDecOpen(); if (!decoder) { DEBUGF("FAAD: Decode open error\n"); return CODEC_ERROR; } NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(decoder); conf->outputFormat = FAAD_FMT_16BIT; /* irrelevant, we don't convert */ NeAACDecSetConfiguration(decoder, conf); decoder->config.defObjectType = rmctx.codec_extradata[0]; decoder->config.defSampleRate = rmctx.sample_rate; err = NeAACDecInit(decoder, NULL, 0, &s, &c); if (err) { DEBUGF("FAAD: DecInit: %d, %d\n", err, decoder->object_type); return CODEC_ERROR; } /* 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; } ci->set_elapsed(0); ci->advance_buffer(rmctx.data_offset + DATA_HEADER_SIZE); /* The main decoding loop */ while (1) { if (action == CODEC_ACTION_NULL) action = ci->get_command(¶m); if (action == CODEC_ACTION_HALT) break; if (action == CODEC_ACTION_SEEK_TIME) { /* Do not allow seeking beyond the file's length */ if ((unsigned) param > ci->id3->length) { ci->set_elapsed(ci->id3->length); ci->seek_complete(); break; } ci->seek_buffer(rmctx.data_offset + DATA_HEADER_SIZE); /* Seek to the start of the track */ if (param == 0) { ci->set_elapsed(0); ci->seek_complete(); action = CODEC_ACTION_NULL; continue; } skipped = 0; /* ** $Id$ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ #ifndef lmem_h #define lmem_h #include <stddef.h> #include "llimits.h" #include "lua.h" #define MEMERRMSG "not enough memory" #define luaM_reallocv(L,b,on,n,e) \ ((cast(size_t, (n)+1) <= MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \ luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \ luaM_toobig(L)) #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) #define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t)) #define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t)) #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) #define luaM_newvector(L,n,t) \ cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) #define luaM_growvector(L,v,nelems,size,t,limit,e) \ if ((nelems)+1 > (size)) \ ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) #define luaM_reallocvector(L, v,oldn,n,t) \ ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, size_t size); LUAI_FUNC void *luaM_toobig (lua_State *L); LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elem, int limit, const char *errormsg); #endif