From 7e9555b97c3644385214427a456e4a0aaa876c92 Mon Sep 17 00:00:00 2001 From: darkeye Date: Sat, 13 Apr 2002 11:26:00 +0000 Subject: [PATCH] added cbr, abr and vbr setting feature with encoding quality --- darkice/trunk/ChangeLog | 6 + darkice/trunk/configure.in | 2 +- darkice/trunk/darkice.cfg | 6 +- darkice/trunk/man/darkice.1 | 5 +- darkice/trunk/man/darkice.cfg.5 | 79 ++++-- darkice/trunk/src/AudioEncoder.h | 135 +++++----- darkice/trunk/src/DarkIce.cpp | 325 ++++++++++++++++++------- darkice/trunk/src/LameLibEncoder.cpp | 95 ++++++-- darkice/trunk/src/LameLibEncoder.h | 37 ++- darkice/trunk/src/VorbisLibEncoder.cpp | 61 +++-- darkice/trunk/src/VorbisLibEncoder.h | 81 ++---- 11 files changed, 535 insertions(+), 297 deletions(-) diff --git a/darkice/trunk/ChangeLog b/darkice/trunk/ChangeLog index c00750a..85271b5 100644 --- a/darkice/trunk/ChangeLog +++ b/darkice/trunk/ChangeLog @@ -1,3 +1,9 @@ +DarkIce 0.10 + + o added possibility to select constant, average and variable bit rate + encoding modes with specifying encoding quality as well. + thanks to Nicu Pavel + 09-04-2002: DarkIce 0.9.1 released o bugfix: a memory leak was introduced in 0.9, which is fixed thanks to diff --git a/darkice/trunk/configure.in b/darkice/trunk/configure.in index 8bf2197..b3ae7f8 100644 --- a/darkice/trunk/configure.in +++ b/darkice/trunk/configure.in @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(src/DarkIce.cpp) -AM_INIT_AUTOMAKE(darkice, 0.9.1) +AM_INIT_AUTOMAKE(darkice, 0.10beta) AM_CONFIG_HEADER(config.h) diff --git a/darkice/trunk/darkice.cfg b/darkice/trunk/darkice.cfg index 14c3f43..0547de9 100644 --- a/darkice/trunk/darkice.cfg +++ b/darkice/trunk/darkice.cfg @@ -17,7 +17,9 @@ channel = 2 # channels. 1 = mono, 2 = stereo # there may be up to 8 of these sections, named [icecast-0] ... [icecast-7] # these can be mixed with [icecast2-x] and [shoutcast-x] sections [icecast-0] +bitrateMode = cbr # constant bit rate bitrate = 96 # bitrate of the mp3 stream sent to the server +quality = 0.8 # encoding quality server = yp.yourserver.com # host name of the server port = 8000 # port of the IceCast server, usually 8000 @@ -36,6 +38,7 @@ public = yes # advertise this stream? # there may be up to 8 of these sections, named [icecast2-0] ... [icecast2-7] # these can be mixed with [icecast-x] and [shoutcast-x] sections [icecast2-0] +bitrateMode = abr # average bit rate format = vorbis # format of the stream: ogg vorbis bitrate = 96 # bitrate of the stream sent to the server server = yp.yourserver.com @@ -56,7 +59,8 @@ public = yes # advertise this stream? # there may be up to 8 of these sections, named [shoutcast-0] ... [shoutcast-7] # these can be mixed with [icecast-x] and [icecast2-x] sections [shoutcast-0] -bitrate = 96 # bitrate of the mp3 stream sent to the server +bitrateMode = vbr # variable bit rate mode +quality = 0.5 # encoding quality server = yp.yourserver.com # host name of the server port = 8001 # source port of the ShoutCast server, usually 8001 diff --git a/darkice/trunk/man/darkice.1 b/darkice/trunk/man/darkice.1 index 44777a8..61cea60 100644 --- a/darkice/trunk/man/darkice.1 +++ b/darkice/trunk/man/darkice.1 @@ -1,4 +1,4 @@ -.TH darkice 1 "September 18, 2001" "DarkIce" "DarkIce live audio streamer" +.TH darkice 1 "April 13, 2002" "DarkIce" "DarkIce live audio streamer" .SH NAME darkice \- an icecast / shoutcast live audio streamer .SH SYNOPSIS @@ -81,6 +81,9 @@ Ogg Vorbis encoding code based on the contribution of aNa|0Gue BSD porting help from Robin P. Blanchard .I +CBR, ABR and VBR and encoding quality setting feature from Nicu Pavel +.I + .SH LINKS Project homepage: diff --git a/darkice/trunk/man/darkice.cfg.5 b/darkice/trunk/man/darkice.cfg.5 index 1c947ec..96acd5a 100644 --- a/darkice/trunk/man/darkice.cfg.5 +++ b/darkice/trunk/man/darkice.cfg.5 @@ -1,4 +1,4 @@ -.TH darkice.cfg 5 "March 28, 2002" "DarkIce" "DarkIce live audio streamer" +.TH darkice.cfg 5 "April 13, 2002" "DarkIce" "DarkIce live audio streamer" .SH NAME darkice.cfg \- configuration file for darkice .SH DESCRIPTION @@ -86,9 +86,21 @@ The stream will be reachable at Required values: +.TP +.I bitrateMode +The bit rate mode of the encoding, either "cbr", "abr" or "vbr", +standing for constant bit rate, average bit rate and variable bit +respectively. Use the bitrate and/or quality values to specify details +of the appropriate bit rate mode. .TP .I bitrate -Bit rate to encode to in kBits / sec (e.g. 96) +Bit rate to encode to in kBits / sec (e.g. 96). Only used when cbr or +abr bit rate modes are specified. +.TP +.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 cbr or vbr +bit rate modes are specified. .TP .I server The @@ -177,14 +189,20 @@ Format of the stream sent to the .B IceCast2 server. Currently the only supported value here is 'vorbis'. .TP +.I bitrateMode +The bit rate mode of the encoding, either "cbr", "abr" or "vbr", +standing for constant bit rate, average bit rate and variable bit +respectively. Use the bitrate and/or quality values to specify details +of the appropriate bit rate mode. +.TP .I bitrate -Bit rate to encode to in kBits / sec (e.g. 96) -If specified, the quality field may not be specified. +Bit rate to encode to in kBits / sec (e.g. 96). Only used when cbr or +abr bit rate modes are specified. .TP .I quality -Quality of a variable bitrate stream, a number between 0.0 ... 1.0 -(e.g. 0.8). -If specified, the bitrate field may not be specified. +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 cbr or vbr +bit rate modes are specified. .TP .I server The @@ -244,9 +262,21 @@ The stream will be reachable at Required values: +.TP +.I bitrateMode +The bit rate mode of the encoding, either "cbr", "abr" or "vbr", +standing for constant bit rate, average bit rate and variable bit +respectively. Use the bitrate and/or quality values to specify details +of the appropriate bit rate mode. .TP .I bitrate -Bit rate to encode to in kBits / sec (e.g. 96) +Bit rate to encode to in kBits / sec (e.g. 96). Only used when cbr or +abr bit rate modes are specified. +.TP +.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 cbr or vbr +bit rate modes are specified. .TP .I server The @@ -319,8 +349,20 @@ Required values: .I format Format to encode in. Must be either 'mp3' or 'vorbis'. .TP +.I bitrateMode +The bit rate mode of the encoding, either "cbr", "abr" or "vbr", +standing for constant bit rate, average bit rate and variable bit +respectively. Use the bitrate and/or quality values to specify details +of the appropriate bit rate mode. +.TP .I bitrate -Bit rate to encode to in kBits / sec (e.g. 96) +Bit rate to encode to in kBits / sec (e.g. 96). Only used when cbr or +abr bit rate modes are specified. +.TP +.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 cbr or vbr +bit rate modes are specified. .TP .I fileName The name of the local file to save the encoded data into. @@ -355,7 +397,8 @@ at 22.05kHz, 16 bit stereo. It will build up a connection to the .B IceCast server yp.yourserver.com on port 8000 with the password "hackme". -The stream will be encoded to 96 kb/s mp3, and will be reachable at +The stream will be encoded to 96 kb/s mp3 with quality 0.8, and will be +reachable at .I http://yp.yourserver.com:8000/live96 to mp3 players. The encoding session will be stored by @@ -380,7 +423,9 @@ bitsPerSample = 16 channel = 2 [icecast-0] +bitrateMode = cbr bitrate = 96 +quality = 0.8 server = yp.yourserver.com port = 8000 password = hackme @@ -397,8 +442,8 @@ localDumpFile = /tmp/encoder-dump.mp3 .PP The following sample configuration file simply encodes the 16 bit stereo -44.1 kHz sound card input into Ogg Vorbis at 96 kb/s for 60 seconds, and saves -it in the local file at /tmp/save.ogg. +44.1 kHz sound card input into Ogg Vorbis at average bit rate 96 kb/s for 60 +seconds, and saves it in the local file at /tmp/save.ogg. .nf [general] @@ -413,6 +458,7 @@ channel = 2 [file-0] format = vorbis +bitrateMode = abr bitrate = 96 fileName = /tmp/save.ogg .fi @@ -429,7 +475,8 @@ It will build up a connection to an .B IceCast server yp.your-ice-server.com on port 8000 with the password "ice-hackme". The sound for this stream will be cut at 10500 Hz from above. -The stream will be encoded to 96 kb/s mp3 and resampled to 22.05kHz. +The stream will be encoded to average bit rate 96 kb/s mp3 and resampled to +22.05kHz. The stream will be reachable at .I http://yp.your-ice-server.com:8000/live96 to mp3 players. @@ -442,7 +489,8 @@ on the server side. It will also connect to a .I ShoutCast server at yp.your-shout-server.com on port 8001 with the password "shout-hackme" -This stream will be encoded to 128 kb/s mp3, and will be reachable at +This stream will be encoded to constant bit rate 128 kb/s mp3 with quality +0.8, and will be reachable at .I http://yp.your-shout-server.com:8000 to mp3 players. @@ -459,6 +507,7 @@ channel = 2 [icecast-0] sampleRate = 22050 +bitrateMode = abr bitrate = 96 lowpass = 10500 server = yp.your-ice-server.com @@ -473,7 +522,9 @@ public = yes remoteDumpFile = /tmp/live96.mp3 [shoutcast-0] +bitrateMode = cbr bitrate = 128 +quality = 0.8 server = yp.your-shout-server.com port = 8001 password = shout-hackme diff --git a/darkice/trunk/src/AudioEncoder.h b/darkice/trunk/src/AudioEncoder.h index 7e5793b..b7dd035 100644 --- a/darkice/trunk/src/AudioEncoder.h +++ b/darkice/trunk/src/AudioEncoder.h @@ -57,6 +57,18 @@ */ class AudioEncoder : public Sink, public virtual Referable { + public: + /** + * Type to specify bitrate mode. Possible values: + * - cbr - constant bitrate mode + * described by bitrate + * - abr - average bitrate mode + * described by an average bitrate and quality + * - vbr - variable bitrate mode + * described by quality + */ + enum BitrateMode { cbr, abr, vbr }; + private: /** @@ -79,6 +91,11 @@ class AudioEncoder : public Sink, public virtual Referable */ bool inBigEndian; + /** + * The bitrate mode of the encoder + */ + BitrateMode outBitrateMode; + /** * Bit rate of the output in kbits/sec, for fixed bitrate encodings. */ @@ -105,7 +122,8 @@ class AudioEncoder : public Sink, public virtual Referable * @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. - * @param inBigEndian shows if the input is big or little endian + * @param inBigEndian shows if the input is big or little endian. + * @param outBitrateMode the bit rate mode of the output. * @param outBitrate bit rate of the output. * @param outSampleRate sample rate of the output. * @param outChannel number of channels of the output. @@ -116,8 +134,9 @@ class AudioEncoder : public Sink, public virtual Referable unsigned int inBitsPerSample, unsigned int inChannel, bool inBigEndian, + BitrateMode outBitrateMode, unsigned int outBitrate, - float outQuality, + double outQuality, unsigned int outSampleRate, unsigned int outChannel ) throw ( Exception ) { @@ -125,10 +144,15 @@ class AudioEncoder : public Sink, public virtual Referable this->inBitsPerSample = inBitsPerSample; this->inChannel = inChannel; this->inBigEndian = inBigEndian; + this->outBitrateMode = outBitrateMode; this->outBitrate = outBitrate; this->outQuality = outQuality; this->outSampleRate = outSampleRate; this->outChannel = outChannel; + + if ( outQuality < 0 || 1.0 < outQuality ) { + throw Exception( __FILE__, __LINE__, "invalid encoder quality"); + } } /** @@ -156,46 +180,14 @@ class AudioEncoder : public Sink, public virtual Referable } /** - * Constructor for fixed bitrate encoding. + * Constructor. * * @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. * @param inBigEndian shows if the input is big or little endian + * @param outBitrateMode the bit rate mode of the output. * @param outBitrate bit rate of the output (kbits/sec). - * @param outSampleRate sample rate of the output. - * If 0, inSampleRate is used. - * @param outChannel number of channels of the output. - * If 0, inChannel is used. - * @exception Exception - */ - inline - AudioEncoder ( unsigned int inSampleRate, - unsigned int inBitsPerSample, - unsigned int inChannel, - bool inBigEndian, - unsigned int outBitrate, - unsigned int outSampleRate = 0, - unsigned int outChannel = 0 ) - throw ( Exception ) - { - init ( inSampleRate, - inBitsPerSample, - inChannel, - inBigEndian, - outBitrate, - 0.0, - outSampleRate ? outSampleRate : inSampleRate, - outChannel ? outChannel : inChannel ); - } - - /** - * Constructor for variable bitrate encoding. - * - * @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. - * @param inBigEndian shows if the input is big or little endian * @param outQuality the quality of the stream. * @param outSampleRate sample rate of the output. * If 0, inSampleRate is used. @@ -208,6 +200,8 @@ class AudioEncoder : public Sink, public virtual Referable unsigned int inBitsPerSample, unsigned int inChannel, bool inBigEndian, + BitrateMode outBitrateMode, + unsigned int outBitrate, double outQuality, unsigned int outSampleRate = 0, unsigned int outChannel = 0 ) @@ -217,46 +211,20 @@ class AudioEncoder : public Sink, public virtual Referable inBitsPerSample, inChannel, inBigEndian, - 0, + outBitrateMode, + outBitrate, outQuality, outSampleRate ? outSampleRate : inSampleRate, outChannel ? outChannel : inChannel ); } /** - * Constructor for fixed bitrate encoding. + * Constructor. * * @param as get input sample rate, bits per sample and channels * from this AudioSource. + * @param outBitrateMode the bit rate mode of the output. * @param outBitrate bit rate of the output (kbits/sec). - * @param outSampleRate sample rate of the output. - * If 0, input sample rate is used. - * @param outChannel number of channels of the output. - * If 0, input channel is used. - * @exception Exception - */ - inline - AudioEncoder ( const AudioSource * as, - unsigned int outBitrate, - unsigned int outSampleRate = 0, - unsigned int outChannel = 0 ) - throw ( Exception) - { - init( as->getSampleRate(), - as->getBitsPerSample(), - as->getChannel(), - as->isBigEndian(), - outBitrate, - 0.0, - outSampleRate ? outSampleRate : as->getSampleRate(), - outChannel ? outChannel : as->getChannel() ); - } - - /** - * Constructor for variable bitrate encoding. - * - * @param as get input sample rate, bits per sample and channels - * from this AudioSource. * @param outQuality the quality of the stream. * @param outSampleRate sample rate of the output. * If 0, input sample rate is used. @@ -266,6 +234,8 @@ class AudioEncoder : public Sink, public virtual Referable */ inline AudioEncoder ( const AudioSource * as, + BitrateMode outBitrateMode, + unsigned int outBitrate, double outQuality, unsigned int outSampleRate = 0, unsigned int outChannel = 0 ) @@ -274,8 +244,9 @@ class AudioEncoder : public Sink, public virtual Referable init( as->getSampleRate(), as->getBitsPerSample(), as->getChannel(), - as->isBigEndian(), - 0, + as->isBigEndian(), + outBitrateMode, + outBitrate, outQuality, outSampleRate ? outSampleRate : as->getSampleRate(), outChannel ? outChannel : as->getChannel() ); @@ -293,6 +264,7 @@ class AudioEncoder : public Sink, public virtual Referable encoder.inBitsPerSample, encoder.inChannel, encoder.inBigEndian, + encoder.outBitrateMode, encoder.outBitrate, encoder.outQuality, encoder.outSampleRate, @@ -316,6 +288,7 @@ class AudioEncoder : public Sink, public virtual Referable encoder.inBitsPerSample, encoder.inChannel, encoder.inBigEndian, + encoder.outBitrateMode, encoder.outBitrate, encoder.outQuality, encoder.outSampleRate, @@ -405,6 +378,17 @@ class AudioEncoder : public Sink, public virtual Referable return outSampleRate; } + /** + * Get the bit rate mode of the output. + * + * @return the bit rate mode of the output. + */ + inline BitrateMode + getOutBitrateMode ( void ) const throw () + { + return outBitrateMode; + } + /** * Get the bit rate of the output in kbits/sec, for fixed bitrate * encodings. @@ -429,18 +413,6 @@ class AudioEncoder : public Sink, public virtual Referable return outQuality; } - /** - * Tell if this encoding is fixed bitrate or variable bitrate. - * - * @return true if this encoding is variable bitrate, - * false if fixed bitrate. - */ - inline bool - isVBR ( void ) const throw () - { - return outBitrate == 0; - } - /** * Check wether encoding is in progress. * @@ -484,6 +456,9 @@ class AudioEncoder : public Sink, public virtual Referable $Source$ $Log$ + Revision 1.7 2002/04/13 11:26:00 darkeye + added cbr, abr and vbr setting feature with encoding quality + Revision 1.6 2002/03/28 16:39:32 darkeye added interface for variable bitrate encoding diff --git a/darkice/trunk/src/DarkIce.cpp b/darkice/trunk/src/DarkIce.cpp index c92db99..763e64c 100644 --- a/darkice/trunk/src/DarkIce.cpp +++ b/darkice/trunk/src/DarkIce.cpp @@ -198,29 +198,68 @@ DarkIce :: configIceCast ( const Config & config, stream); #else - const char * str; + const char * str; - unsigned int sampleRate = 0; - unsigned int bitrate = 0; - const char * server = 0; - unsigned int port = 0; - const char * password = 0; - const char * mountPoint = 0; - const char * remoteDumpFile = 0; - const char * name = 0; - const char * description = 0; - const char * url = 0; - const char * genre = 0; - bool isPublic = false; - int lowpass = 0; - int highpass = 0; - const char * localDumpName = 0; - FileSink * localDumpFile = 0; + unsigned int sampleRate = 0; + AudioEncoder::BitrateMode bitrateMode; + unsigned int bitrate = 0; + double quality = 0.0; + const char * server = 0; + unsigned int port = 0; + const char * password = 0; + const char * mountPoint = 0; + const char * remoteDumpFile = 0; + const char * name = 0; + const char * description = 0; + const char * url = 0; + const char * genre = 0; + bool isPublic = false; + int lowpass = 0; + int highpass = 0; + const char * localDumpName = 0; + FileSink * localDumpFile = 0; str = cs->get( "sampleRate"); sampleRate = str ? Util::strToL( str) : dsp->getSampleRate(); - str = cs->getForSure("bitrate", " missing in section ", stream); - bitrate = Util::strToL( str); + + str = cs->get( "bitrate"); + bitrate = str ? Util::strToL( str) : 0; + str = cs->get( "quality"); + quality = str ? Util::strToD( str) : 0.0; + + str = cs->getForSure( "bitrateMode", + " not specified in section ", + stream); + if ( Util::strEq( str, "cbr") ) { + bitrateMode = AudioEncoder::cbr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for CBR encoding"); + } + if ( quality == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for CBR encoding"); + } + } else if ( Util::strEq( str, "abr") ) { + bitrateMode = AudioEncoder::abr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for ABR encoding"); + } + } else if ( Util::strEq( str, "vbr") ) { + bitrateMode = AudioEncoder::vbr; + + if ( quality == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for VBR encoding"); + } + } else { + throw Exception( __FILE__, __LINE__, + "invalid bitrate mode: ", str); + } + server = cs->getForSure( "server", " missing in section ", stream); str = cs->getForSure( "port", " missing in section ", stream); port = Util::strToL( str); @@ -239,6 +278,7 @@ DarkIce :: configIceCast ( const Config & config, lowpass = str ? Util::strToL( str) : 0; str = cs->get( "highpass"); highpass = str ? Util::strToL( str) : 0; + localDumpName = cs->get( "localDumpFile"); // go on and create the things @@ -278,7 +318,9 @@ DarkIce :: configIceCast ( const Config & config, audioOuts[u].encoder = new LameLibEncoder( audioOuts[u].server.get(), dsp.get(), + bitrateMode, bitrate, + quality, sampleRate, dsp->getChannel(), lowpass, @@ -316,23 +358,24 @@ DarkIce :: configIceCast2 ( const Config & config, break; } - const char * str; + const char * str; - IceCast2::StreamFormat format; - unsigned int sampleRate = 0; - unsigned int bitrate = 0; - double quality = 0.0; - const char * server = 0; - unsigned int port = 0; - const char * password = 0; - const char * mountPoint = 0; - const char * name = 0; - const char * description = 0; - const char * url = 0; - const char * genre = 0; - bool isPublic = false; - const char * localDumpName = 0; - FileSink * localDumpFile = 0; + IceCast2::StreamFormat format; + unsigned int sampleRate = 0; + AudioEncoder::BitrateMode bitrateMode; + unsigned int bitrate = 0; + double quality = 0.0; + const char * server = 0; + unsigned int port = 0; + const char * password = 0; + const char * mountPoint = 0; + const char * name = 0; + const char * description = 0; + const char * url = 0; + const char * genre = 0; + bool isPublic = false; + const char * localDumpName = 0; + FileSink * localDumpFile = 0; str = cs->getForSure( "format", " missing in section ", stream); if ( Util::strEq( str, "vorbis") ) { @@ -356,18 +399,40 @@ DarkIce :: configIceCast2 ( const Config & config, bitrate = str ? Util::strToL( str) : 0; str = cs->get( "quality"); quality = str ? Util::strToD( str) : 0.0; - - if ( bitrate == 0 && quality == 0.0 ) { - throw Exception( __FILE__, __LINE__, - "neither fixed bitrate nor VBR quality specified in ", - stream); - } - if ( bitrate != 0 && quality != 0.0 ) { - throw Exception( __FILE__, __LINE__, - "both fixed bitrate and VBR quality specified in ", - stream); - } + str = cs->getForSure( "bitrateMode", + " not specified in section ", + stream); + if ( Util::strEq( str, "cbr") ) { + bitrateMode = AudioEncoder::cbr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for CBR encoding"); + } + if ( quality == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for CBR encoding"); + } + } else if ( Util::strEq( str, "abr") ) { + bitrateMode = AudioEncoder::abr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for ABR encoding"); + } + } else if ( Util::strEq( str, "vbr") ) { + bitrateMode = AudioEncoder::vbr; + + if ( quality == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for VBR encoding"); + } + } else { + throw Exception( __FILE__, __LINE__, + "invalid bitrate mode: ", str); + } + server = cs->getForSure( "server", " missing in section ", stream); str = cs->getForSure( "port", " missing in section ", stream); port = Util::strToL( str); @@ -429,7 +494,9 @@ DarkIce :: configIceCast2 ( const Config & config, audioOuts[u].encoder = new LameLibEncoder( audioOuts[u].server.get(), dsp.get(), + bitrateMode, bitrate, + quality, sampleRate, dsp->getChannel() ); #endif // HAVE_LAME_LIB @@ -442,21 +509,14 @@ DarkIce :: configIceCast2 ( const Config & config, "thus can't Ogg Vorbis stream: ", stream); #else - if ( bitrate != 0 ) { - audioOuts[u].encoder = new VorbisLibEncoder( - audioOuts[u].server.get(), - dsp.get(), - bitrate, - sampleRate, - dsp->getChannel() ); - } else { - audioOuts[u].encoder = new VorbisLibEncoder( - audioOuts[u].server.get(), - dsp.get(), - quality, - sampleRate, - dsp->getChannel() ); - } + audioOuts[u].encoder = new VorbisLibEncoder( + audioOuts[u].server.get(), + dsp.get(), + bitrateMode, + bitrate, + quality, + sampleRate, + dsp->getChannel() ); #endif // HAVE_VORBIS_LIB break; @@ -480,7 +540,7 @@ DarkIce :: configShoutCast ( const Config & config, unsigned int bufferSecs ) throw ( Exception ) { - // look for IceCast encoder output streams, + // look for Shoutcast encoder output streams, // sections [shoutcast-0], [shoutcast-1], ... char stream[] = "shoutcast- "; size_t streamLen = Util::strLen( stream); @@ -503,29 +563,68 @@ DarkIce :: configShoutCast ( const Config & config, stream); #else - const char * str; + const char * str; - unsigned int sampleRate = 0; - unsigned int bitrate = 0; - const char * server = 0; - unsigned int port = 0; - const char * password = 0; - const char * name = 0; - const char * url = 0; - const char * genre = 0; - bool isPublic = false; - int lowpass = 0; - int highpass = 0; - const char * irc = 0; - const char * aim = 0; - const char * icq = 0; - const char * localDumpName = 0; - FileSink * localDumpFile = 0; + unsigned int sampleRate = 0; + AudioEncoder::BitrateMode bitrateMode; + unsigned int bitrate = 0; + double quality = 0.0; + const char * server = 0; + unsigned int port = 0; + const char * password = 0; + const char * name = 0; + const char * url = 0; + const char * genre = 0; + bool isPublic = false; + int lowpass = 0; + int highpass = 0; + const char * irc = 0; + const char * aim = 0; + const char * icq = 0; + const char * localDumpName = 0; + FileSink * localDumpFile = 0; str = cs->get( "sampleRate"); sampleRate = str ? Util::strToL( str) : dsp->getSampleRate(); - str = cs->getForSure("bitrate", " missing in section ", stream); - bitrate = Util::strToL( str); + + str = cs->get( "bitrate"); + bitrate = str ? Util::strToL( str) : 0; + str = cs->get( "quality"); + quality = str ? Util::strToD( str) : 0.0; + + str = cs->getForSure( "bitrateMode", + " not specified in section ", + stream); + if ( Util::strEq( str, "cbr") ) { + bitrateMode = AudioEncoder::cbr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for CBR encoding"); + } + if ( quality == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for CBR encoding"); + } + } else if ( Util::strEq( str, "abr") ) { + bitrateMode = AudioEncoder::abr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for ABR encoding"); + } + } else if ( Util::strEq( str, "vbr") ) { + bitrateMode = AudioEncoder::vbr; + + if ( quality == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for VBR encoding"); + } + } else { + throw Exception( __FILE__, __LINE__, + "invalid bitrate mode: ", str); + } + server = cs->getForSure( "server", " missing in section ", stream); str = cs->getForSure( "port", " missing in section ", stream); port = Util::strToL( str); @@ -581,7 +680,9 @@ DarkIce :: configShoutCast ( const Config & config, audioOuts[u].encoder = new LameLibEncoder( audioOuts[u].server.get(), dsp.get(), + bitrateMode, bitrate, + quality, sampleRate, dsp->getChannel(), lowpass, @@ -618,14 +719,16 @@ DarkIce :: configFileCast ( const Config & config ) break; } - const char * str; + const char * str; - const char * format = 0; - unsigned int bitrate = 0; - const char * targetFileName = 0; - unsigned int sampleRate = 0; - int lowpass = 0; - int highpass = 0; + const char * format = 0; + AudioEncoder::BitrateMode bitrateMode; + unsigned int bitrate = 0; + double quality = 0.0; + const char * targetFileName = 0; + unsigned int sampleRate = 0; + int lowpass = 0; + int highpass = 0; format = cs->getForSure( "format", " missing in section ", stream); if ( !Util::strEq( format, "vorbis") && !Util::strEq( format, "mp3") ) { @@ -640,6 +743,45 @@ DarkIce :: configFileCast ( const Config & config ) stream); str = cs->get( "sampleRate"); sampleRate = str ? Util::strToL( str) : dsp->getSampleRate(); + + str = cs->get( "bitrate"); + bitrate = str ? Util::strToL( str) : 0; + str = cs->get( "quality"); + quality = str ? Util::strToD( str) : 0.0; + + str = cs->getForSure( "bitrateMode", + " not specified in section ", + stream); + if ( Util::strEq( str, "cbr") ) { + bitrateMode = AudioEncoder::cbr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for CBR encoding"); + } + if ( quality == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for CBR encoding"); + } + } else if ( Util::strEq( str, "abr") ) { + bitrateMode = AudioEncoder::abr; + + if ( bitrate == 0 ) { + throw Exception( __FILE__, __LINE__, + "bitrate not specified for ABR encoding"); + } + } else if ( Util::strEq( str, "vbr") ) { + bitrateMode = AudioEncoder::vbr; + + if ( quality == 0 ) { + throw Exception( __FILE__, __LINE__, + "quality not specified for VBR encoding"); + } + } else { + throw Exception( __FILE__, __LINE__, + "invalid bitrate mode: ", str); + } + str = cs->get( "lowpass"); lowpass = str ? Util::strToL( str) : 0; str = cs->get( "highpass"); @@ -670,7 +812,9 @@ DarkIce :: configFileCast ( const Config & config ) audioOuts[u].encoder = new LameLibEncoder( audioOuts[u].server.get(), dsp.get(), + bitrateMode, bitrate, + quality, sampleRate, dsp->getChannel(), lowpass, @@ -686,7 +830,9 @@ DarkIce :: configFileCast ( const Config & config ) audioOuts[u].encoder = new VorbisLibEncoder( audioOuts[u].server.get(), dsp.get(), + bitrateMode, bitrate, + quality, dsp->getSampleRate(), dsp->getChannel() ); #endif // HAVE_VORBIS_LIB @@ -834,6 +980,9 @@ DarkIce :: run ( void ) throw ( Exception ) $Source$ $Log$ + Revision 1.27 2002/04/13 11:26:00 darkeye + added cbr, abr and vbr setting feature with encoding quality + Revision 1.26 2002/03/28 16:43:11 darkeye enabled resampling and variable bitrates for vorbis (icecast2) streams diff --git a/darkice/trunk/src/LameLibEncoder.cpp b/darkice/trunk/src/LameLibEncoder.cpp index 8300871..d444ed6 100644 --- a/darkice/trunk/src/LameLibEncoder.cpp +++ b/darkice/trunk/src/LameLibEncoder.cpp @@ -37,6 +37,7 @@ #ifdef HAVE_LAME_LIB + #include "Exception.h" #include "Util.h" #include "LameLibEncoder.h" @@ -117,14 +118,82 @@ LameLibEncoder :: open ( void ) "set lame out sample rate", lame_get_out_samplerate( lameGlobalFlags)); - if ( 0 > lame_set_brate( lameGlobalFlags, getOutBitrate()) ) { - throw Exception( __FILE__, __LINE__, - "lame lib setting output bit rate error", - getOutBitrate() ); + switch ( getOutBitrateMode() ) { + + case cbr: { + + if ( 0 > lame_set_brate( lameGlobalFlags, getOutBitrate()) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting output bit rate error", + getOutBitrate() ); + } + + reportEvent( 5, + "set lame bit rate", + lame_get_brate( lameGlobalFlags)); + + double d = (1.0 - getOutQuality()) * 10.0; + int q = int (d + 0.499999); + + if ( 0 > lame_set_quality( lameGlobalFlags, q) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting quality error", q); + } + + reportEvent( 5, + "set lame quality", + lame_get_quality( lameGlobalFlags)); + } break; + + case abr: + + if ( 0 > lame_set_VBR( lameGlobalFlags,vbr_abr)) { + throw Exception( __FILE__, __LINE__, + "lame lib setting abr error", vbr_abr); + } + + reportEvent( 5, + "set lame abr bitrate", + lame_get_VBR( lameGlobalFlags)); + + if ( 0 > lame_set_VBR_mean_bitrate_kbps( lameGlobalFlags, + getOutBitrate())) { + throw Exception( __FILE__, __LINE__, + "lame lib setting abr mean bitrate error", + getOutBitrate()); + } + + reportEvent( 5, + "set lame abr mean bitrate", + lame_get_VBR_mean_bitrate_kbps( lameGlobalFlags)); + break; + + case vbr: { + + if ( 0 > lame_set_VBR( lameGlobalFlags, vbr_mtrh)) { + throw Exception( __FILE__, __LINE__, + "lame lib setting vbr error", vbr_mtrh ); + } + + reportEvent( 5, + "set lame vbr bitrate", + lame_get_VBR( lameGlobalFlags)); + + double d = (1.0 - getOutQuality()) * 10.0; + int q = int (d + 0.499999); + + if ( 0 > lame_set_VBR_q( lameGlobalFlags, q) ) { + throw Exception( __FILE__, __LINE__, + "lame lib setting vbr quality error", q); + } + + reportEvent( 5, + "set lame vbr quality", + lame_get_VBR_q( lameGlobalFlags)); + } break; } - reportEvent( 5, "set lame bit rate", lame_get_brate( lameGlobalFlags)); - + if ( 0 > lame_set_lowpassfreq( lameGlobalFlags, lowpass) ) { throw Exception( __FILE__, __LINE__, "lame lib setting lowpass frequency error", @@ -145,15 +214,10 @@ LameLibEncoder :: open ( void ) "set lame highpass frequency", lame_get_highpassfreq( lameGlobalFlags)); + + + // not configurable lame settings - - if ( 0 > lame_set_quality( lameGlobalFlags, 2) ) { - throw Exception( __FILE__, __LINE__, - "lame lib setting quality error", - 2 ); - } - - reportEvent( 5, "set lame quality", lame_get_quality( lameGlobalFlags)); if ( 0 > lame_set_exp_nspsytune( lameGlobalFlags, 1) ) { throw Exception( __FILE__, __LINE__, @@ -315,6 +379,9 @@ LameLibEncoder :: close ( void ) throw ( Exception ) $Source$ $Log$ + Revision 1.11 2002/04/13 11:26:00 darkeye + added cbr, abr and vbr setting feature with encoding quality + Revision 1.10 2002/03/28 16:38:37 darkeye moved functions conv8() and conv16() to class Util diff --git a/darkice/trunk/src/LameLibEncoder.h b/darkice/trunk/src/LameLibEncoder.h index ac470d1..4714726 100644 --- a/darkice/trunk/src/LameLibEncoder.h +++ b/darkice/trunk/src/LameLibEncoder.h @@ -112,11 +112,11 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter inline void init ( Sink * sink, int lowpass, - int highpass ) throw ( Exception ) + int highpass ) throw ( Exception ) { - this->sink = sink; - this->lowpass = lowpass; - this->highpass = highpass; + this->sink = sink; + this->lowpass = lowpass; + this->highpass = highpass; if ( getInBitsPerSample() != 16 && getInBitsPerSample() != 8 ) { throw Exception( __FILE__, __LINE__, @@ -164,11 +164,14 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter * @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. - * @param outBitrate bit rate of the output (bits/sec). + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output (kbits/sec). + * @param outQuality the quality of the stream. * @param outSampleRate sample rate of the output. * If 0, inSampleRate is used. * @param outChannel number of channels of the output. * If 0, inChannel is used. + * @param inBigEndian shows if the input is big or little endian * @param lowpass frequency threshold for the lowpass filter. * Input above this frequency is cut. * If 0, lame's default values are used, @@ -184,7 +187,10 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter unsigned int inSampleRate, unsigned int inBitsPerSample, unsigned int inChannel, + bool inBigEndian, + BitrateMode outBitrateMode, unsigned int outBitrate, + double outQuality, unsigned int outSampleRate = 0, unsigned int outChannel = 0, int lowpass = 0, @@ -193,12 +199,15 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter : AudioEncoder ( inSampleRate, inBitsPerSample, - inChannel, + inChannel, + inBigEndian, + outBitrateMode, outBitrate, + outQuality, outSampleRate, outChannel ) { - init( sink, lowpass, highpass ); + init( sink, lowpass, highpass); } /** @@ -207,7 +216,9 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter * @param sink the sink to send mp3 output to * @param as get input sample rate, bits per sample and channels * from this AudioSource. - * @param outBitrate bit rate of the output (bits/sec). + * @param outBitrateMode the bit rate mode of the output. + * @param outBitrate bit rate of the output (kbits/sec). + * @param outQuality the quality of the stream. * @param outSampleRate sample rate of the output. * If 0, input sample rate is used. * @param outChannel number of channels of the output. @@ -225,7 +236,9 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter inline LameLibEncoder ( Sink * sink, const AudioSource * as, + BitrateMode outBitrateMode, unsigned int outBitrate, + double outQuality, unsigned int outSampleRate = 0, unsigned int outChannel = 0, int lowpass = 0, @@ -233,11 +246,13 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter throw ( Exception ) : AudioEncoder ( as, + outBitrateMode, outBitrate, + outQuality, outSampleRate, outChannel ) { - init( sink, lowpass, highpass ); + init( sink, lowpass, highpass); } /** @@ -252,6 +267,7 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter { init( encoder.sink.get(), encoder.lowpass, encoder.highpass ); } + /** * Destructor. @@ -420,6 +436,9 @@ class LameLibEncoder : public AudioEncoder, public virtual Reporter $Source$ $Log$ + Revision 1.12 2002/04/13 11:26:00 darkeye + added cbr, abr and vbr setting feature with encoding quality + Revision 1.11 2002/03/28 16:38:37 darkeye moved functions conv8() and conv16() to class Util diff --git a/darkice/trunk/src/VorbisLibEncoder.cpp b/darkice/trunk/src/VorbisLibEncoder.cpp index 77d67db..60b4293 100644 --- a/darkice/trunk/src/VorbisLibEncoder.cpp +++ b/darkice/trunk/src/VorbisLibEncoder.cpp @@ -73,37 +73,43 @@ VorbisLibEncoder :: open ( void ) vorbis_info_init( &vorbisInfo); - if ( isVBR() ) { + switch ( getOutBitrateMode() ) { - if ( (ret = vorbis_encode_init_vbr( &vorbisInfo, + case cbr: + case abr: +#ifdef VORBIS_LIB_RC3 + if ( (ret = vorbis_encode_init( &vorbisInfo, getInChannel(), getOutSampleRate(), - getOutQuality() )) ) { - throw Exception( __FILE__, __LINE__, - "vorbis encode init error", ret); - } - } else { -#ifdef VORBIS_LIB_RC3 - if ( (ret = vorbis_encode_init( &vorbisInfo, - getInChannel(), - getOutSampleRate(), - getOutBitrate() * 1024, - getOutBitrate() * 1024, - -1 )) ) { - throw Exception( __FILE__, __LINE__, - "vorbis encode init error", ret); - } + getOutBitrate() * 1000, + getOutBitrate() * 1000, + -1 )) ) { + throw Exception( __FILE__, __LINE__, + "vorbis encode init error", ret); + } #else - if ( (ret = vorbis_encode_init( &vorbisInfo, - getInChannel(), - getOutSampleRate(), - -1, - getOutBitrate() * 1024, - -1 )) ) { - throw Exception( __FILE__, __LINE__, - "vorbis encode init error", ret); - } + if ( (ret = vorbis_encode_init( &vorbisInfo, + getInChannel(), + getOutSampleRate(), + -1, + getOutBitrate() * 1000, + -1 )) ) { + throw Exception( __FILE__, __LINE__, + "vorbis encode init error", ret); + } #endif + break; + + case vbr: + + if ( (ret = vorbis_encode_init_vbr( &vorbisInfo, + getInChannel(), + getOutSampleRate(), + getOutQuality() )) ) { + throw Exception( __FILE__, __LINE__, + "vorbis encode init error", ret); + } + break; } if ( (ret = vorbis_analysis_init( &vorbisDspState, &vorbisInfo)) ) { @@ -310,6 +316,9 @@ VorbisLibEncoder :: close ( void ) throw ( Exception ) $Source$ $Log$ + Revision 1.8 2002/04/13 11:26:00 darkeye + added cbr, abr and vbr setting feature with encoding quality + Revision 1.7 2002/03/28 16:47:38 darkeye moved functions conv8() and conv16() to class Util (as conv()) added resampling functionality diff --git a/darkice/trunk/src/VorbisLibEncoder.h b/darkice/trunk/src/VorbisLibEncoder.h index 1e7a53a..5f2b3b2 100644 --- a/darkice/trunk/src/VorbisLibEncoder.h +++ b/darkice/trunk/src/VorbisLibEncoder.h @@ -191,13 +191,16 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter public: /** - * Constructor for fixed bitrate encoding. + * Constructor. * * @param sink the sink to send mp3 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. + * @param inBigEndian shows if the input is big or little endian + * @param outBitrateMode the bit rate mode of the output. * @param outBitrate bit rate of the output (kbits/sec). + * @param outQuality the quality of the stream. * @param outSampleRate sample rate of the output. * If 0, inSampleRate is used. * @param outChannel number of channels of the output. @@ -209,40 +212,9 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter unsigned int inSampleRate, unsigned int inBitsPerSample, unsigned int inChannel, + bool inBigEndian, + BitrateMode outBitrateMode, unsigned int outBitrate, - unsigned int outSampleRate = 0, - unsigned int outChannel = 0 ) - throw ( Exception ) - - : AudioEncoder ( inSampleRate, - inBitsPerSample, - inChannel, - outBitrate, - outSampleRate, - outChannel ) - { - init( sink); - } - - /** - * Constructor for variable bitrate encoding. - * - * @param sink the sink to send mp3 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. - * @param outQuality the quality of the stream (0.0 .. 1.0). - * @param outSampleRate sample rate of the output. - * If 0, inSampleRate is used. - * @param outChannel number of channels of the output. - * If 0, inChannel is used. - * @exception Exception - */ - inline - VorbisLibEncoder ( Sink * sink, - unsigned int inSampleRate, - unsigned int inBitsPerSample, - unsigned int inChannel, double outQuality, unsigned int outSampleRate = 0, unsigned int outChannel = 0 ) @@ -251,6 +223,9 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter : AudioEncoder ( inSampleRate, inBitsPerSample, inChannel, + inBigEndian, + outBitrateMode, + outBitrate, outQuality, outSampleRate, outChannel ) @@ -259,12 +234,14 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter } /** - * Constructor for fixed bitrate encoding. + * Constructor. * * @param sink the sink to send mp3 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. * @param outBitrate bit rate of the output (kbits/sec). + * @param outQuality the quality of the stream. * @param outSampleRate sample rate of the output. * If 0, input sample rate is used. * @param outChannel number of channels of the output. @@ -274,41 +251,16 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter inline VorbisLibEncoder ( Sink * sink, const AudioSource * as, + BitrateMode outBitrateMode, unsigned int outBitrate, - unsigned int outSampleRate = 0, - unsigned int outChannel = 0 ) - throw ( Exception ) - - : AudioEncoder ( as, - outBitrate, - outSampleRate, - outChannel ) - { - init( sink); - } - - /** - * Constructor for variable bitrate encoding. - * - * @param sink the sink to send mp3 output to - * @param as get input sample rate, bits per sample and channels - * from this AudioSource. - * @param outQuality the quality of the stream (0.0 .. 1.0). - * @param outSampleRate sample rate of the output. - * If 0, input sample rate is used. - * @param outChannel number of channels of the output. - * If 0, input channel is used. - * @exception Exception - */ - inline - VorbisLibEncoder ( Sink * sink, - const AudioSource * as, double outQuality, unsigned int outSampleRate = 0, unsigned int outChannel = 0 ) throw ( Exception ) : AudioEncoder ( as, + outBitrateMode, + outBitrate, outQuality, outSampleRate, outChannel ) @@ -493,6 +445,9 @@ class VorbisLibEncoder : public AudioEncoder, public virtual Reporter $Source$ $Log$ + Revision 1.5 2002/04/13 11:26:00 darkeye + added cbr, abr and vbr setting feature with encoding quality + Revision 1.4 2002/03/28 16:47:38 darkeye moved functions conv8() and conv16() to class Util (as conv()) added resampling functionality