summaryrefslogtreecommitdiff
path: root/apps/codecs
diff options
context:
space:
mode:
authorMagnus Holmgren <magnushol@gmail.com>2005-07-24 15:32:28 +0000
committerMagnus Holmgren <magnushol@gmail.com>2005-07-24 15:32:28 +0000
commit4a53787992b396d28c001f7567bc91644fae861c (patch)
tree0ab4fee5b878e957fa781d6581efbe6f103c0fd2 /apps/codecs
parent6bd8e5db08e42130d1a72377b3c0cec0b8d57a69 (diff)
downloadrockbox-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.h2
-rw-r--r--apps/codecs/Tremor/vorbisfile.c44
-rw-r--r--apps/codecs/lib/codeclib.c9
-rw-r--r--apps/codecs/lib/codeclib.h2
-rw-r--r--apps/codecs/vorbis.c32
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),&current_section);
+
+ /* Read host-endian signed 24-bit PCM samples */
+ n=ov_read_fixed(&vf,&pcm,1024,&current_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));