Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

wvoggvorbis.h

Go to the documentation of this file.
00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * Provides a WvEncoder abstraction for Ogg vorbis files.
00006  * Only monaural audio is supported for now.
00007  */
00008 #ifndef __WVOGGVORBIS_H
00009 #define __WVOGGVORBIS_H
00010 
00011 #include "wvtypedencoder.h"
00012 #include "wvstringlist.h"
00013 #include <ogg/ogg.h>
00014 #include <vorbis/codec.h>
00015 #include <vorbis/vorbisenc.h>
00016 
00017 /**
00018  * Encodes PCM audio using the Ogg Vorbis stream format.
00019  * 
00020  * Input buffer must contain a sequence of signed 'float' type
00021  * values in machine order representing normalized PCM audio data.
00022  * 
00023  * Outbut buffer will contain part of an Ogg bitstream.
00024  * 
00025  */
00026 class WvOggVorbisEncoder :
00027     public WvTypedEncoder<float, unsigned char>
00028 {
00029 public:
00030     static const long RANDOM_SERIALNO = 0;
00031 
00032     /**
00033      * Bitrate specification.
00034      * 
00035      * Identifies a particular bitrate control mechanism.
00036      * Use one of the subclasses to initialize a suitable BitrateSpec.
00037      * 
00038      */
00039     class BitrateSpec
00040     {
00041         friend class WvOggVorbisEncoder;
00042     protected:
00043         enum Mode { VBR_QUALITY, VBR_BITRATE };
00044         Mode mode;
00045         float quality_index;
00046         long max_bitrate;
00047         long nominal_bitrate;
00048         long min_bitrate;
00049         
00050         BitrateSpec(Mode mode) : mode(mode) { }
00051     public:
00052         // allow creation of uninitialized objects for later assignment
00053         BitrateSpec() { }
00054     };
00055     
00056     /**
00057      * Specifies a variable bitrate based on a quality index ranging
00058      * from 0.0 (low quality) to 1.0 (high quality).
00059      */
00060     class VBRQuality : public BitrateSpec
00061     {
00062     public:
00063         /**
00064          * Creates a bitrate specification.
00065          * "quality" is the quality index
00066          */
00067         VBRQuality(float quality) : BitrateSpec(VBR_QUALITY)
00068         {
00069             quality_index = quality;
00070         }
00071     };
00072     
00073     /**
00074      * Specifies a variable bitrate based on max, nominal, and min
00075      * bitrates specified in bits per second.
00076      */
00077     class VBRBitrate : public BitrateSpec
00078     {
00079     public:
00080         /**
00081          * Creates a bitrate specification.
00082          * "nominal" is the nominal bitrate
00083          */
00084         VBRBitrate(long nominal) : BitrateSpec(VBR_BITRATE)
00085         {
00086             max_bitrate = -1;
00087             nominal_bitrate = nominal;
00088             min_bitrate = -1;
00089         }
00090         /**
00091          * Creates a bitrate specification.
00092          * "max" is the maximum bitrate
00093          * "nominal" is the nominal bitrate
00094          * "min" is the minimum bitrate
00095          */
00096         VBRBitrate(long max, long nominal, long min) :
00097             BitrateSpec(VBR_BITRATE)
00098         {
00099             max_bitrate = max;
00100             nominal_bitrate = nominal;
00101             min_bitrate = min;
00102         }
00103     };
00104     
00105     /**
00106      * Creates an Ogg Vorbis Encoder.
00107      * 
00108      * The special constant RANDOM_SERIALNO may be specified as the
00109      * serial number to let the encoder choose one at random.  The
00110      * implementation uses the rand() function and assumes that
00111      * the PRNG was previously seeded with srand().
00112      * 
00113      * "bitrate" is the bitrate specification
00114      * "samplingrate" is the number of samples per second
00115      * "channels" is number of channels (must be 1 for now),
00116      *        defaults to 1
00117      * "serialno" is the Ogg bitstream serial number,
00118      *        defaults to RANDOM_SERIALNO
00119      */
00120     WvOggVorbisEncoder(const BitrateSpec &bitratespec,
00121         int samplingrate, int channels = 1,
00122         long serialno = RANDOM_SERIALNO);
00123 
00124     virtual ~WvOggVorbisEncoder();
00125 
00126     /**
00127      * Adds a comment to the Ogg Vorbis stream.
00128      * 
00129      * Do not call after the first invocation of encode().
00130      * 
00131      * "comment" is the comment
00132      */
00133     void add_comment(WvStringParm comment);
00134     
00135     /**
00136      * Adds a comment to the Ogg Vorbis stream.
00137      * 
00138      * Do not call after the first invocation of encode().
00139      * 
00140      */
00141     void add_comment(WVSTRING_FORMAT_DECL)
00142         { add_comment(WvString(WVSTRING_FORMAT_CALL)); }
00143     
00144     /**
00145      * Adds a tag to the Ogg Vorbis stream.
00146      * 
00147      * Ogg Vorbis tags are special comment strings of the form
00148      * "=" and are typically used to store artist,
00149      * date, and other simple string encoded metadata.
00150      * 
00151      * Do not call after the first invocation of encode().
00152      * 
00153      * "tag" is the tag name
00154      * "value" is the value
00155      */
00156     void add_tag(WvStringParm tag, WvStringParm value);
00157 
00158 protected:
00159     virtual bool _typedencode(IBuffer &inbuf, OBuffer &outbuf,
00160         bool flush);
00161     virtual bool _typedfinish(OBuffer &outbuf);
00162 
00163 private:
00164     ogg_stream_state *oggstream;
00165     vorbis_info *ovinfo;
00166     vorbis_comment *ovcomment;
00167     vorbis_dsp_state *ovdsp;
00168     vorbis_block *ovblock;
00169     bool wrote_header;
00170 
00171     bool write_header(OBuffer &outbuf);
00172     bool write_stream(OBuffer &outbuf, bool flush = false);
00173     bool process_audio(OBuffer &outbuf);
00174 };
00175 
00176 
00177 /**
00178  * Decodes PCM audio using the Ogg Vorbis stream format.
00179  * 
00180  * Inbut buffer must contain part of an Ogg bitstream.
00181  * 
00182  * Output buffer will contain a sequence of signed 'float' type
00183  * values in machine order representing normalized PCM audio data.
00184  * 
00185  * If flush == false, then encode() will return true immediately
00186  * after isheaderok() becomes true without outputting any audio
00187  * data.  This allows the client to examine the header and to
00188  * tailor the actual decoding process based on that information.
00189  * 
00190  */
00191 class WvOggVorbisDecoder :
00192     public WvTypedEncoder<unsigned char, float>
00193 {
00194     WvStringList comment_list;
00195 
00196 public:
00197     /**
00198      * Creates a new Ogg Vorbis Decoder.
00199      * 
00200      * For now, if the input bitstream is stereo, outputs the left
00201      * channel only.  This behaviour may change later on.
00202      * 
00203      */
00204     WvOggVorbisDecoder();
00205     virtual ~WvOggVorbisDecoder();
00206 
00207     /**
00208      * Returns true when the entire stream header has been processed
00209      * and the comments and vendor fields are valid.
00210      * 
00211      * If false and isok(), try decoding more data.
00212      * 
00213      * Returns: true when the header has been decoded
00214      */
00215     bool isheaderok() const;
00216 
00217     /**
00218      * Returns the Ogg Vorbis vendor comment string.
00219      *
00220      * Returns: the vendor comment
00221      */
00222     WvString vendor() const
00223         { return ovcomment->vendor; }
00224 
00225     /**
00226      * Returns the Ogg Vorbis list of user comments.
00227      * 
00228      * The list is owned by the encoder, do not change.
00229      * 
00230      * Returns: the list of comments
00231      */
00232     WvStringList &comments()
00233         { return comment_list; }
00234 
00235     /**
00236      * Returns the number of channels in the stream.
00237      *
00238      * Returns: the number of channels, non-negative
00239      */
00240     int channels() const
00241         { return ovinfo->channels; }
00242 
00243     /**
00244      * Returns the sampling rate of the stream.
00245      *
00246      * Returns: the sampling rate
00247      */
00248     int samplingrate() const
00249         { return ovinfo->rate; }
00250     
00251 protected:
00252     virtual bool _typedencode(IBuffer &inbuf, OBuffer &outbuf,
00253         bool flush);
00254     virtual bool _typedfinish(OBuffer &outbuf);
00255 
00256 private:
00257     ogg_sync_state *oggsync;
00258     ogg_stream_state *oggstream;
00259     ogg_page *oggpage;
00260     vorbis_info *ovinfo;
00261     vorbis_comment *ovcomment;
00262     vorbis_dsp_state *ovdsp;
00263     vorbis_block *ovblock;
00264     bool need_serialno;
00265     int need_headers;
00266 
00267     bool process_page(ogg_page *oggpage, OBuffer &outbuf);
00268     bool process_packet(ogg_packet *oggpacket, OBuffer &outbuf);
00269     bool prepare_dsp();
00270     bool prepare_stream(long serialno);
00271 };
00272 
00273 #endif // __WVOGGVORBIS

Generated on Wed Dec 15 15:08:11 2004 for WvStreams by  doxygen 1.3.9.1