From 9257e95c08096971faf25d126dc2322fd2cb7a7c Mon Sep 17 00:00:00 2001 From: darkeye Date: Tue, 20 Aug 2002 19:35:37 +0000 Subject: [PATCH] added possibility to specify maximum bitrate for Ogg Vorbis streams --- darkice/trunk/ChangeLog | 1 + darkice/trunk/man/darkice.cfg.5 | 11 ++- darkice/trunk/src/AudioEncoder.h | 5 +- darkice/trunk/src/DarkIce.cpp | 9 ++- darkice/trunk/src/VorbisLibEncoder.cpp | 94 ++++++++++++++++++++------ darkice/trunk/src/VorbisLibEncoder.h | 81 +++++++++++----------- 6 files changed, 134 insertions(+), 67 deletions(-) diff --git a/darkice/trunk/ChangeLog b/darkice/trunk/ChangeLog index 2403384..e22f1ae 100644 --- a/darkice/trunk/ChangeLog +++ b/darkice/trunk/ChangeLog @@ -1,5 +1,6 @@ DarkIce next version + o added possibility to specify maximum bitrate for Ogg Vorbis streams o added HTTP Basic authentication for icecast2 logins o added mp3 streaming for icecast2 o added possibility to stream in mono even when recording in stereo, diff --git a/darkice/trunk/man/darkice.cfg.5 b/darkice/trunk/man/darkice.cfg.5 index a22b8df..f433dbf 100644 --- a/darkice/trunk/man/darkice.cfg.5 +++ b/darkice/trunk/man/darkice.cfg.5 @@ -1,4 +1,4 @@ -.TH darkice.cfg 5 "August 3, 2002" "DarkIce" "DarkIce live audio streamer" +.TH darkice.cfg 5 "August 20, 2002" "DarkIce" "DarkIce live audio streamer" .SH NAME darkice.cfg \- configuration file for darkice .SH DESCRIPTION @@ -191,7 +191,7 @@ Required values: .I format Format of the stream sent to the .B IceCast2 -server. Currently the only supported value here is 'vorbis'. +server. Supported formats are 'vorbis' and 'mp3'. .TP .I bitrateMode The bit rate mode of the encoding, either "cbr", "abr" or "vbr", @@ -206,7 +206,8 @@ abr bit rate modes are specified. .I quality The quality of encoding a value between 0.0 .. 1.0 (e.g. 0.8), with 1.0 being the highest quality. Use a value greater than 0.0. Only used when vbr -bit rate mode is specified. +bit rate mode is specified for Ogg Vorbis format, or in vbr and abr +modes for mp3 format. .TP .I server The @@ -232,6 +233,10 @@ Optional values: The sample rate of the encoded mp3 output. If not specified, defaults to the value of the input sample rate. .TP +.I maxBitrate +The maximum bitrate of the stream. Only used when in cbr mode and in +Ogg Vorbis format. +.TP .I name Name of the stream .TP diff --git a/darkice/trunk/src/AudioEncoder.h b/darkice/trunk/src/AudioEncoder.h index b7dd035..97f0171 100644 --- a/darkice/trunk/src/AudioEncoder.h +++ b/darkice/trunk/src/AudioEncoder.h @@ -395,7 +395,7 @@ class AudioEncoder : public Sink, public virtual Referable * * @return the bit rate of the output. */ - inline int + inline unsigned int getOutBitrate ( void ) const throw () { return outBitrate; @@ -456,6 +456,9 @@ class AudioEncoder : public Sink, public virtual Referable $Source$ $Log$ + Revision 1.8 2002/08/20 19:35:37 darkeye + added possibility to specify maximum bitrate for Ogg Vorbis streams + Revision 1.7 2002/04/13 11:26:00 darkeye added cbr, abr and vbr setting feature with encoding quality diff --git a/darkice/trunk/src/DarkIce.cpp b/darkice/trunk/src/DarkIce.cpp index 8876e34..0b0f4a8 100644 --- a/darkice/trunk/src/DarkIce.cpp +++ b/darkice/trunk/src/DarkIce.cpp @@ -361,6 +361,7 @@ DarkIce :: configIceCast2 ( const Config & config, unsigned int sampleRate = 0; AudioEncoder::BitrateMode bitrateMode; unsigned int bitrate = 0; + unsigned int maxBitrate = 0; double quality = 0.0; const char * server = 0; unsigned int port = 0; @@ -390,6 +391,8 @@ DarkIce :: configIceCast2 ( const Config & config, // determine fixed bitrate or variable bitrate quality str = cs->get( "bitrate"); bitrate = str ? Util::strToL( str) : 0; + str = cs->get( "maxBitrate"); + maxBitrate = str ? Util::strToL( str) : 0; str = cs->get( "quality"); quality = str ? Util::strToD( str) : 0.0; @@ -499,7 +502,8 @@ DarkIce :: configIceCast2 ( const Config & config, bitrate, quality, sampleRate, - dsp->getChannel() ); + dsp->getChannel(), + maxBitrate); #endif // HAVE_VORBIS_LIB break; @@ -960,6 +964,9 @@ DarkIce :: run ( void ) throw ( Exception ) $Source$ $Log$ + Revision 1.31 2002/08/20 19:35:37 darkeye + added possibility to specify maximum bitrate for Ogg Vorbis streams + Revision 1.30 2002/08/20 18:37:49 darkeye added mp3 streaming possibility for icecast2 diff --git a/darkice/trunk/src/VorbisLibEncoder.cpp b/darkice/trunk/src/VorbisLibEncoder.cpp index ede879c..8dc5b18 100644 --- a/darkice/trunk/src/VorbisLibEncoder.cpp +++ b/darkice/trunk/src/VorbisLibEncoder.cpp @@ -58,6 +58,56 @@ static const char fileid[] = "$Id$"; /* ============================================================= module code */ +/*------------------------------------------------------------------------------ + * Initialize the encoder + *----------------------------------------------------------------------------*/ +void +VorbisLibEncoder :: init ( Sink * sink, + unsigned int outMaxBitrate ) + throw ( Exception ) +{ + this->sink = sink; + this->outMaxBitrate = outMaxBitrate; + + if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) { + throw Exception( __FILE__, __LINE__, + "specified bits per sample not supported", + getInBitsPerSample() ); + } + + if ( getInChannel() != 1 && getInChannel() != 2 ) { + throw Exception( __FILE__, __LINE__, + "unsupported number of channels for the encoder", + getInChannel() ); + } + if ( getInChannel() != getOutChannel() ) { + throw Exception( __FILE__, __LINE__, + "different number of input and output channels", + getOutChannel() ); + } + + if ( getOutSampleRate() == getInSampleRate() ) { + resampleRatio = 1; + converter = 0; + } else { + resampleRatio = ( (double) getOutSampleRate() / + (double) getInSampleRate() ); + // open the aflibConverter in + // - high quality + // - not linear (quadratic) interpolation + // - not filter interpolation + converter = new aflibConverter( true, true, false); + } + + if ( getInChannel() != getOutChannel() ) { + throw Exception( __FILE__, __LINE__, + "different in and out channels not supported"); + } + + encoderOpen = false; +} + + /*------------------------------------------------------------------------------ * Open an encoding session *----------------------------------------------------------------------------*/ @@ -75,14 +125,31 @@ VorbisLibEncoder :: open ( void ) switch ( getOutBitrateMode() ) { - case cbr: + case cbr: { + int maxBitrate = getOutMaxBitrate() * 1000; + if ( !maxBitrate ) { + maxBitrate = -1; + } + if ( (ret = vorbis_encode_init( &vorbisInfo, + getInChannel(), + getOutSampleRate(), + -1, + getOutBitrate() * 1000, + maxBitrate)) ) { + throw Exception( __FILE__, __LINE__, + "vorbis encode init error", ret); + } + } break; + + case abr: + /* set non-managed VBR around the average bitrate */ ret = vorbis_encode_setup_managed( &vorbisInfo, getInChannel(), getOutSampleRate(), -1, getOutBitrate() * 1000, - -1) - || vorbis_encode_ctl( &vorbisInfo, OV_ECTL_RATEMANAGE_AVG, NULL) + -1 ) + || vorbis_encode_ctl( &vorbisInfo, OV_ECTL_RATEMANAGE_SET, NULL) || vorbis_encode_setup_init( &vorbisInfo); if ( ret ) { throw Exception( __FILE__, __LINE__, @@ -90,18 +157,6 @@ VorbisLibEncoder :: open ( void ) } break; - case abr: - if ( (ret = vorbis_encode_init( &vorbisInfo, - getInChannel(), - getOutSampleRate(), - -1, - getOutBitrate() * 1000, - -1 )) ) { - throw Exception( __FILE__, __LINE__, - "vorbis encode init error", ret); - } - break; - case vbr: if ( (ret = vorbis_encode_init_vbr( &vorbisInfo, getInChannel(), @@ -184,12 +239,6 @@ VorbisLibEncoder :: write ( const void * buf, unsigned int bitsPerSample = getInBitsPerSample(); unsigned int channels = getInChannel(); - if ( channels != 1 && channels != 2 ) { - throw Exception( __FILE__, __LINE__, - "unsupported number of channels for the encoder", - channels ); - } - unsigned int sampleSize = (bitsPerSample / 8) * channels; unsigned char * b = (unsigned char*) buf; unsigned int processed = len - (len % sampleSize); @@ -319,6 +368,9 @@ VorbisLibEncoder :: close ( void ) throw ( Exception ) $Source$ $Log$ + Revision 1.13 2002/08/20 19:35:37 darkeye + added possibility to specify maximum bitrate for Ogg Vorbis streams + Revision 1.12 2002/08/03 10:30:46 darkeye resampling bugs fixed for vorbis streams diff --git a/darkice/trunk/src/VorbisLibEncoder.h b/darkice/trunk/src/VorbisLibEncoder.h index 94395dd..2f7af3b 100644 --- a/darkice/trunk/src/VorbisLibEncoder.h +++ b/darkice/trunk/src/VorbisLibEncoder.h @@ -105,10 +105,15 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter ogg_stream_state oggStreamState; /** - * The Sink to dump mp3 data to + * The Sink to dump encoded data to */ Ref sink; + /** + * Maximum bitrate of the output in kbits/sec. If 0, don't care. + */ + unsigned int outMaxBitrate; + /** * Resample ratio */ @@ -122,40 +127,13 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter /** * Initialize the object. * - * @param sink the sink to send mp3 output to + * @param sink the sink to send encoded output to + * @param the maximum bit rate * @exception Exception */ - inline void - init ( Sink * sink ) throw ( Exception ) - { - this->sink = sink; - - if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) { - throw Exception( __FILE__, __LINE__, - "specified bits per sample not supported", - getInBitsPerSample() ); - } - - if ( getOutSampleRate() == getInSampleRate() ) { - resampleRatio = 1; - converter = 0; - } else { - resampleRatio = ( (double) getOutSampleRate() / - (double) getInSampleRate() ); - // open the aflibConverter in - // - high quality - // - not linear (quadratic) interpolation - // - not filter interpolation - converter = new aflibConverter( true, true, false); - } - - if ( getInChannel() != getOutChannel() ) { - throw Exception( __FILE__, __LINE__, - "different in and out channels not supported"); - } - - encoderOpen = false; - } + void + init ( Sink * sink, + unsigned int outMaxBitrate ) throw ( Exception ); /** * De-initialize the object. @@ -193,7 +171,7 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter /** * Constructor. * - * @param sink the sink to send mp3 output to + * @param sink the sink to send encoded output to * @param inSampleRate sample rate of the input. * @param inBitsPerSample number of bits per sample of the input. * @param inChannel number of channels of the input. @@ -203,6 +181,8 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter * @param outQuality the quality of the stream. * @param outSampleRate sample rate of the output. * If 0, inSampleRate is used. + * @param outMaxBitrate maximum output bitrate. + * 0 if not used. * @param outChannel number of channels of the output. * If 0, inChannel is used. * @exception Exception @@ -217,7 +197,8 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter unsigned int outBitrate, double outQuality, unsigned int outSampleRate = 0, - unsigned int outChannel = 0 ) + unsigned int outChannel = 0, + unsigned int outMaxBitrate = 0 ) throw ( Exception ) : AudioEncoder ( inSampleRate, @@ -230,13 +211,13 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter outSampleRate, outChannel ) { - init( sink); + init( sink, outMaxBitrate); } /** * Constructor. * - * @param sink the sink to send mp3 output to + * @param sink the sink to send encoded output to * @param as get input sample rate, bits per sample and channels * from this AudioSource. * @param outBitrateMode the bit rate mode of the output. @@ -244,6 +225,8 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter * @param outQuality the quality of the stream. * @param outSampleRate sample rate of the output. * If 0, input sample rate is used. + * @param outMaxBitrate maximum output bitrate. + * 0 if not used. * @param outChannel number of channels of the output. * If 0, input channel is used. * @exception Exception @@ -255,7 +238,8 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter unsigned int outBitrate, double outQuality, unsigned int outSampleRate = 0, - unsigned int outChannel = 0 ) + unsigned int outChannel = 0, + unsigned int outMaxBitrate = 0 ) throw ( Exception ) : AudioEncoder ( as, @@ -265,7 +249,7 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter outSampleRate, outChannel ) { - init( sink); + init( sink, outMaxBitrate); } /** @@ -281,7 +265,7 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter if( encoder.isOpen() ) { throw Exception(__FILE__, __LINE__, "don't copy open encoders"); } - init( encoder.sink.get()); + init( encoder.sink.get(), encoder.getOutMaxBitrate() ); } /** @@ -315,12 +299,24 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter if ( this != &encoder ) { strip(); AudioEncoder::operator=( encoder); - init( encoder.sink.get()); + init( encoder.sink.get(), encoder.getOutMaxBitrate() ); } return *this; } + /** + * Get the maximum bit rate of the output in kbits/sec, + * for fixed / average bitrate encodings. + * + * @return the maximum bit rate of the output, or 0 if not set. + */ + inline unsigned int + getOutMaxBitrate ( void ) const throw () + { + return outMaxBitrate; + } + /** * Check wether encoding is in progress. * @@ -445,6 +441,9 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter $Source$ $Log$ + Revision 1.7 2002/08/20 19:35:37 darkeye + added possibility to specify maximum bitrate for Ogg Vorbis streams + Revision 1.6 2002/07/20 16:37:06 darkeye added fault tolerance in case a server connection is dropped