From 866ed6ea6f378815e7f73acd92fece78365ed8e4 Mon Sep 17 00:00:00 2001
From: Monty
Date: Thu, 17 Apr 2008 18:21:55 +0000
Subject: [PATCH] Commit 01-ov_read_filter patch from #381; closes feature
request #1352. Also updates included HTML documentation to cover the added
ov_read_filter() function.
svn path=/trunk/vorbis/; revision=14771
---
doc/vorbisfile/decoding.html | 11 +++-
doc/vorbisfile/ov_read_filter.html | 114 +++++++++++++++++++++++++++++++++++++
doc/vorbisfile/reference.html | 1 +
include/vorbis/vorbisfile.h | 3 +
lib/vorbisfile.c | 19 ++++++-
5 files changed, 143 insertions(+), 5 deletions(-)
create mode 100644 doc/vorbisfile/ov_read_filter.html
diff --git a/doc/vorbisfile/decoding.html b/doc/vorbisfile/decoding.html
index 3a2b405..4a39155 100644
--- a/doc/vorbisfile/decoding.html
+++ b/doc/vorbisfile/decoding.html
@@ -20,9 +20,10 @@ All libvorbisfile decoding routines are declared in "vorbis/vorbisfile.h".
After initialization, decoding audio
-is as simple as calling ov_read(). This
-function works similarly to reading from a normal file using
-read().
+is as simple as calling ov_read() (or the
+similar functions ov_read_float() and
+ov_read_filter). This function works
+similarly to reading from a normal file using read().
However, a few differences are worth noting:
@@ -68,6 +69,10 @@ or ov_open_callbacks().
+ ov_read_filter() is a variant of ov_read(), the main function used to decode
+ a Vorbis file within a loop. It passes the decoded floating point
+ PCM data to the filter specified in the function arguments before
+ converting the data to integer output samples. All other aspects of
+ its behavior are as with ov_read().
+
+
+
+
+
+
+
+long ov_read_filter(OggVorbis_File *vf, char *buffer, int length, int bigendianp, int word, int sgned, int *bitstream,
+ void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param);
+
+
+
+
+
+
Parameters
+
+
vf
+
A pointer to the OggVorbis_File structure--this is used for ALL the externally visible libvorbisfile
+functions.
+
buffer
+
A pointer to an output buffer. The decoded output is inserted into this buffer.
+
length
+
Number of bytes to be read into the buffer. Should be the same size as the buffer. A typical value is 4096.
+
bigendianp
+
Specifies big or little endian byte packing. 0 for little endian, 1 for b
+ig endian. Typical value is 0.
+
word
+
Specifies word size. Possible arguments are 1 for 8-bit samples, or 2 or
+16-bit samples. Typical value is 2.
+
sgned
+
Signed or unsigned data. 0 for unsigned, 1 for signed. Typically 1.
+
bitstream
+
A pointer to the number of the current logical bitstream.
+
filter
+
Filter function to process float PCM data prior to conversion to interleaved integer output.
+
filter_param
+
Data to pass through to the filter function.
+
+
+
+
+
Return Values
+
+
+
OV_HOLE
+
indicates there was an interruption in the data.
+ (one of: garbage between pages, loss of sync followed by
+ recapture, or a corrupt page)
+
OV_EBADLINK
+
indicates that an invalid stream section was supplied to
+ libvorbisfile, or the requested link is corrupt.
+
0
+
indicates EOF
+
n
+
indicates actual number of bytes read. ov_read() will
+ decode at most one vorbis packet per invocation, so the value
+ returned will generally be less than length.
+
+
+This reads up to 4096 bytes into a buffer, with signed 16-bit
+little-endian samples. The decoded data is passed to the function filter before integer conversiona nd interleave.
+
Seeking
diff --git a/include/vorbis/vorbisfile.h b/include/vorbis/vorbisfile.h
index c9c1af1..3966f7c 100644
--- a/include/vorbis/vorbisfile.h
+++ b/include/vorbis/vorbisfile.h
@@ -176,6 +176,9 @@ extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link);
extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples,
int *bitstream);
+extern long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
+ int bigendianp,int word,int sgned,int *bitstream,
+ void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param);
extern long ov_read(OggVorbis_File *vf,char *buffer,int length,
int bigendianp,int word,int sgned,int *bitstream);
extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2);
diff --git a/lib/vorbisfile.c b/lib/vorbisfile.c
index d878b4c..c940831 100644
--- a/lib/vorbisfile.c
+++ b/lib/vorbisfile.c
@@ -1721,6 +1721,11 @@ static int host_is_big_endian() {
index within the physical bitstream. Note that the accessor
functions above are aware of this dichotomy).
+ ov_read_filter is exactly the same as ov_read except that it processes
+ the decoded audio data through a filter before packing it into the
+ requested format. This gives greater accuracy than applying a filter
+ after the audio has been converted into integral PCM.
+
input values: buffer) a buffer to hold packed PCM data for return
length) the byte length requested to be placed into buffer
bigendianp) should the data be packed LSB first (0) or
@@ -1737,8 +1742,9 @@ static int host_is_big_endian() {
*section) set to the logical bitstream number */
-long ov_read(OggVorbis_File *vf,char *buffer,int length,
- int bigendianp,int word,int sgned,int *bitstream){
+long ov_read_filter(OggVorbis_File *vf,char *buffer,int length,
+ int bigendianp,int word,int sgned,int *bitstream,
+ void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param){
int i,j;
int host_endian = host_is_big_endian();
@@ -1776,6 +1782,10 @@ long ov_read(OggVorbis_File *vf,char *buffer,int length,
if(samples <= 0)
return OV_EINVAL;
+ /* Here. */
+ if(filter)
+ filter(pcm,channels,samples,filter_param);
+
/* a tight loop to pack each size */
{
int val;
@@ -1868,6 +1878,11 @@ long ov_read(OggVorbis_File *vf,char *buffer,int length,
}
}
+long ov_read(OggVorbis_File *vf,char *buffer,int length,
+ int bigendianp,int word,int sgned,int *bitstream){
+ return ov_read_filter(vf, buffer, length, bigendianp, word, sgned, bitstream, NULL, NULL);
+}
+
/* input values: pcm_channels) a float vector per channel of output
length) the sample length being read by the app
--
2.7.4