diff options
author | Daniel Stenberg <daniel@haxx.se> | 2005-06-22 19:41:30 +0000 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2005-06-22 19:41:30 +0000 |
commit | 1dd672fe3226fa77113f35e4d72f50b863484c63 (patch) | |
tree | 67b424ab990f160dbc8fb238b9fa3390ceba10ed /apps/codecs/vorbis.c | |
parent | b7aaa641b864628d76103b8c9d57c15747560ca7 (diff) |
moved and renamed the codecs, gave the codecs a new extension (.codec),
unified to a single codec-only API, made a new codeclib, disabled the building
of the *2wav plugins
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6812 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/vorbis.c')
-rw-r--r-- | apps/codecs/vorbis.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/apps/codecs/vorbis.c b/apps/codecs/vorbis.c new file mode 100644 index 0000000000..969fdf365b --- /dev/null +++ b/apps/codecs/vorbis.c @@ -0,0 +1,168 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Björn Stenberg + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "kernel.h" +#include "codecs.h" + +#include "Tremor/ivorbisfile.h" +#include "playback.h" +#include "lib/codeclib.h" + +static struct codec_api* rb; + +/* Some standard functions and variables needed by Tremor */ + +int errno; + +size_t strlen(const char *s) +{ + return(rb->strlen(s)); +} + +char *strcpy(char *dest, const char *src) +{ + return(rb->strcpy(dest,src)); +} + +char *strcat(char *dest, const char *src) +{ + return(rb->strcat(dest,src)); +} + +size_t read_handler(void *ptr, size_t size, size_t nmemb, void *datasource) +{ + return rb->read_filebuf(ptr, nmemb*size); +} + +int seek_handler(void *datasource, ogg_int64_t offset, int whence) +{ + /* We are not seekable at the moment */ + (void)datasource; + (void)offset; + (void)whence; + return -1; +} + +int close_handler(void *datasource) +{ + (void)datasource; + return 0; +} + +long tell_handler(void *datasource) +{ + return rb->curpos; +} + +#ifdef USE_IRAM +extern char iramcopy[]; +extern char iramstart[]; +extern char iramend[]; +#endif + + +/* reserve the PCM buffer in the IRAM area */ +static char pcmbuf[4096] IDATA_ATTR; + +/* this is the codec entry point */ +enum codec_status codec_start(struct codec_api* api, void* parm) +{ + ov_callbacks callbacks; + OggVorbis_File vf; + vorbis_info* vi; + + int error; + long n; + int current_section; + int eof; +#if BYTE_ORDER == BIG_ENDIAN + int i; + char x; +#endif + + TEST_CODEC_API(api); + + /* if you are using a global api pointer, don't forget to copy it! + otherwise you will get lovely "I04: IllInstr" errors... :-) */ + rb = api; + +#ifdef USE_IRAM + rb->memcpy(iramstart, iramcopy, iramend-iramstart); +#endif + + rb->configure(CODEC_SET_FILEBUF_LIMIT, (int *)(1024*1024*2)); + rb->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (int *)(1024*64)); + + /* We need to flush reserver memory every track load. */ + next_track: + if (codec_init(rb)) { + return CODEC_ERROR; + } + + + /* Create a decoder instance */ + + callbacks.read_func=read_handler; + callbacks.seek_func=seek_handler; + callbacks.tell_func=tell_handler; + callbacks.close_func=close_handler; + + error=ov_open_callbacks(rb,&vf,NULL,0,callbacks); + + vi=ov_info(&vf,-1); + + if (vi==NULL) { + // rb->splash(HZ*2, true, "Vorbis Error"); + return CODEC_ERROR; + } + + eof=0; + while (!eof) { + /* Read host-endian signed 16 bit PCM samples */ + n=ov_read(&vf,pcmbuf,sizeof(pcmbuf),¤t_section); + + if (n==0) { + eof=1; + } + else if (n < 0) { + DEBUGF("Error decoding frame\n"); + } else { + rb->yield(); + if (rb->stop_codec || rb->reload_codec) + break ; + + rb->yield(); + while (!rb->audiobuffer_insert(pcmbuf, n)) + rb->yield(); + + rb->set_elapsed(ov_time_tell(&vf)); + +#if BYTE_ORDER == BIG_ENDIAN + for (i=0;i<n;i+=2) { + x=pcmbuf[i]; pcmbuf[i]=pcmbuf[i+1]; pcmbuf[i+1]=x; + } +#endif + } + } + + if (rb->request_next_track()) + goto next_track; + + return CODEC_OK; +} + |