diff options
| author | Magnus Holmgren <magnushol@gmail.com> | 2005-07-24 15:32:28 +0000 |
|---|---|---|
| committer | Magnus Holmgren <magnushol@gmail.com> | 2005-07-24 15:32:28 +0000 |
| commit | 4a53787992b396d28c001f7567bc91644fae861c (patch) | |
| tree | 0ab4fee5b878e957fa781d6581efbe6f103c0fd2 /apps/codecs | |
| parent | 6bd8e5db08e42130d1a72377b3c0cec0b8d57a69 (diff) | |
| download | rockbox-4a53787992b396d28c001f7567bc91644fae861c.zip rockbox-4a53787992b396d28c001f7567bc91644fae861c.tar.gz rockbox-4a53787992b396d28c001f7567bc91644fae861c.tar.bz2 rockbox-4a53787992b396d28c001f7567bc91644fae861c.tar.xz | |
ReplayGain support for Ogg Vorbis files (also called VorbisGain) added.
Note that there is a small delay from leaving a setting until the change
can be heard (due to audio data buffering).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7234 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs')
| -rw-r--r-- | apps/codecs/Tremor/ivorbisfile.h | 2 | ||||
| -rw-r--r-- | apps/codecs/Tremor/vorbisfile.c | 44 | ||||
| -rw-r--r-- | apps/codecs/lib/codeclib.c | 9 | ||||
| -rw-r--r-- | apps/codecs/lib/codeclib.h | 2 | ||||
| -rw-r--r-- | apps/codecs/vorbis.c | 32 |
5 files changed, 70 insertions, 19 deletions
diff --git a/apps/codecs/Tremor/ivorbisfile.h b/apps/codecs/Tremor/ivorbisfile.h index 1ec0f74..9ff446a 100644 --- a/apps/codecs/Tremor/ivorbisfile.h +++ b/apps/codecs/Tremor/ivorbisfile.h @@ -121,6 +121,8 @@ extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); extern long ov_read(OggVorbis_File *vf,char *buffer,int length, int *bitstream); +extern long ov_read_fixed(OggVorbis_File *vf,ogg_int32_t ***pcm_channels, + int length,int *bitstream); #ifdef __cplusplus } diff --git a/apps/codecs/Tremor/vorbisfile.c b/apps/codecs/Tremor/vorbisfile.c index f6a208d..0d8c04a 100644 --- a/apps/codecs/Tremor/vorbisfile.c +++ b/apps/codecs/Tremor/vorbisfile.c @@ -1604,3 +1604,47 @@ long ov_read(OggVorbis_File *vf,char *buffer,int bytes_req,int *bitstream){ return(samples); } } + +/* input values: pcm_channels) a float vector per channel of output + length) the sample length being read by the app + + return values: <0) error/hole in data (OV_HOLE), partial open (OV_EINVAL) + 0) EOF + n) number of samples of PCM actually returned. The + below works on a packet-by-packet basis, so the + return length is not related to the 'length' passed + in, just guaranteed to fit. + + *section) set to the logical bitstream number */ + +long ov_read_fixed(OggVorbis_File *vf,ogg_int32_t ***pcm_channels,int length, + int *bitstream){ + if(vf->ready_state<OPENED)return(OV_EINVAL); + +#if CONFIG_CPU == MCF5249 + mcf5249_init_mac(); +#endif + + while(1){ + if(vf->ready_state==INITSET){ + ogg_int32_t **pcm; + long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm); + if(samples){ + if(pcm_channels)*pcm_channels=pcm; + if(samples>length)samples=length; + vorbis_synthesis_read(&vf->vd,samples); + vf->pcm_offset+=samples; + if(bitstream)*bitstream=vf->current_link; + return samples; + + } + } + + /* suck in another packet */ + { + int ret=_fetch_and_process_packet(vf,1,1); + if(ret==OV_EOF)return(0); + if(ret<=0)return(ret); + } + } +} diff --git a/apps/codecs/lib/codeclib.c b/apps/codecs/lib/codeclib.c index 2494fe5..ac6e362 100644 --- a/apps/codecs/lib/codeclib.c +++ b/apps/codecs/lib/codeclib.c @@ -23,6 +23,7 @@ #include "playback.h" #include "codeclib.h" #include "xxx2wav.h" +#include "id3.h" struct codec_api *local_rb; @@ -34,3 +35,11 @@ int codec_init(struct codec_api* rb) return 0; } + +void codec_set_replaygain(struct mp3entry* id3) +{ + local_rb->configure(DSP_SET_TRACK_GAIN, (long *) id3->track_gain); + local_rb->configure(DSP_SET_ALBUM_GAIN, (long *) id3->album_gain); + local_rb->configure(DSP_SET_TRACK_PEAK, (long *) id3->track_peak); + local_rb->configure(DSP_SET_ALBUM_PEAK, (long *) id3->album_peak); +} diff --git a/apps/codecs/lib/codeclib.h b/apps/codecs/lib/codeclib.h index 77276fb..3fc03bd 100644 --- a/apps/codecs/lib/codeclib.h +++ b/apps/codecs/lib/codeclib.h @@ -37,4 +37,4 @@ int memcmp(const void *s1, const void *s2, size_t n); void* memmove(const void *s1, const void *s2, size_t n); int codec_init(struct codec_api* rb); - +void codec_set_replaygain(struct mp3entry* id3); diff --git a/apps/codecs/vorbis.c b/apps/codecs/vorbis.c index 8aa7f21..2976a05 100644 --- a/apps/codecs/vorbis.c +++ b/apps/codecs/vorbis.c @@ -105,16 +105,11 @@ bool vorbis_set_codec_parameters(OggVorbis_File *vf) return false; } - if (rb->id3->frequency != NATIVE_FREQUENCY) { - rb->configure(CODEC_DSP_ENABLE, (bool *)true); - } else { - rb->configure(CODEC_DSP_ENABLE, (bool *)false); - } - rb->configure(DSP_SET_FREQUENCY, (int *)rb->id3->frequency); + codec_set_replaygain(rb->id3); if (vi->channels == 2) { - rb->configure(DSP_SET_STEREO_MODE, (int *)STEREO_INTERLEAVED); + rb->configure(DSP_SET_STEREO_MODE, (int *)STEREO_NONINTERLEAVED); } else if (vi->channels == 1) { rb->configure(DSP_SET_STEREO_MODE, (int *)STEREO_MONO); } @@ -129,14 +124,12 @@ 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) { ov_callbacks callbacks; OggVorbis_File vf; + ogg_int32_t** pcm; int error; long n; @@ -157,10 +150,12 @@ enum codec_status codec_start(struct codec_api* api) #ifdef USE_IRAM rb->memcpy(iramstart, iramcopy, iramend-iramstart); #endif - - rb->configure(DSP_DITHER, (bool *)false); - rb->configure(DSP_SET_SAMPLE_DEPTH, (int *)(16)); + rb->configure(CODEC_DSP_ENABLE, (bool *)true); + rb->configure(DSP_DITHER, (bool *)false); + rb->configure(DSP_SET_SAMPLE_DEPTH, (long *) (24)); + rb->configure(DSP_SET_CLIP_MAX, (long *) ((1 << 24) - 1)); + rb->configure(DSP_SET_CLIP_MIN, (long *) -((1 << 24) - 1)); /* Note: These are sane defaults for these values. Perhaps * they should be set differently based on quality setting */ @@ -244,9 +239,9 @@ enum codec_status codec_start(struct codec_api* api) } rb->seek_time = 0; } - - /* Read host-endian signed 16 bit PCM samples */ - n=ov_read(&vf,pcmbuf,sizeof(pcmbuf),¤t_section); + + /* Read host-endian signed 24-bit PCM samples */ + n=ov_read_fixed(&vf,&pcm,1024,¤t_section); /* Change DSP and buffer settings for this bitstream */ if ( current_section != previous_section ) { @@ -262,9 +257,10 @@ enum codec_status codec_start(struct codec_api* api) } else if (n < 0) { DEBUGF("Error decoding frame\n"); } else { - while (!rb->pcmbuf_insert(pcmbuf, n)) { + while (!rb->pcmbuf_insert_split(pcm[0], pcm[1], + n * sizeof(ogg_int32_t))) { rb->sleep(1); - } + } rb->set_offset(ov_raw_tell(&vf)); rb->set_elapsed(ov_time_tell(&vf)); |