/*------------------------------------------------------------------------------ * Initialize the encoder *----------------------------------------------------------------------------*/ void VorbisLibEncoder :: init ( CastSink * 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 ( getOutSampleRate() == getInSampleRate() ) { resampleRatio = 1; converter = 0; } else { resampleRatio = ( (double) getOutSampleRate() / (double) getInSampleRate() ); // Determine if we can use linear interpolation. // The inverse of the ratio must be a power of two for linear mode to // be of sufficient quality. bool useLinear = true; double inverse = 1 / resampleRatio; int integer = (int) inverse; // Check that the inverse of the ratio is an integer if( integer == inverse ) { while( useLinear && integer ) { // Loop through the bits // If the lowest order bit is not the only one set if( integer & 1 && integer != 1 ) { // Not a power of two; cannot use linear useLinear = false; } else { // Shift all the bits over and try again integer >>= 1; } } } else { useLinear = false; } // If we get here and useLinear is still true, then we have // a power of two. // open the aflibConverter in // - high quality // - linear or quadratic (non-linear) based on algorithm // - not filter interpolation converter = new aflibConverter( true, useLinear, false); }
/*------------------------------------------------------------------------------ * Open an encoding session *----------------------------------------------------------------------------*/ bool LameLibEncoder :: open ( void ) throw ( Exception ) { if ( isOpen() ) { close(); } lameGlobalFlags = lame_init(); // ugly lame returns -1 in a pointer on allocation errors if ( !lameGlobalFlags || ((int)lameGlobalFlags) == -1 ) { throw Exception( __FILE__, __LINE__, "lame lib init error", (int) lameGlobalFlags); } if ( 0 > lame_set_num_channels( lameGlobalFlags, getInChannel()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting channels error", getInChannel() ); } if ( 0 > lame_set_mode( lameGlobalFlags, getOutChannel() == 1 ? MONO : JOINT_STEREO) ) { throw Exception( __FILE__, __LINE__, "lame lib setting mode error", JOINT_STEREO ); } reportEvent( 5, "set lame mode", lame_get_mode( lameGlobalFlags)); reportEvent( 5, "set lame channels", lame_get_num_channels( lameGlobalFlags)); if ( 0 > lame_set_in_samplerate( lameGlobalFlags, getInSampleRate()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting input sample rate error", getInSampleRate() ); } reportEvent( 5, "set lame in sample rate", lame_get_in_samplerate( lameGlobalFlags)); if ( 0 > lame_set_out_samplerate( lameGlobalFlags, getOutSampleRate()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting output sample rate error", getOutSampleRate() ); } reportEvent( 5, "set lame out sample rate", lame_get_out_samplerate( lameGlobalFlags)); 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; } if ( 0 > lame_set_lowpassfreq( lameGlobalFlags, lowpass) ) { throw Exception( __FILE__, __LINE__, "lame lib setting lowpass frequency error", lowpass ); } reportEvent( 5, "set lame lowpass frequency", lame_get_lowpassfreq( lameGlobalFlags)); if ( 0 > lame_set_highpassfreq( lameGlobalFlags, highpass) ) { throw Exception( __FILE__, __LINE__, "lame lib setting highpass frequency error", lowpass ); } reportEvent( 5, "set lame highpass frequency", lame_get_highpassfreq( lameGlobalFlags)); // not configurable lame settings if ( 0 > lame_set_exp_nspsytune( lameGlobalFlags, 1) ) { throw Exception( __FILE__, __LINE__, "lame lib setting psycho acoustic model error"); } reportEvent( 5, "set lame psycho acoustic model", lame_get_exp_nspsytune( lameGlobalFlags)); if ( 0 > lame_set_error_protection( lameGlobalFlags, 1) ) { throw Exception( __FILE__, __LINE__, "lame lib setting error protection error", 1 ); } reportEvent( 5, "set lame error protection", lame_get_error_protection( lameGlobalFlags)); // let lame init its own params based on our settings if ( 0 > lame_init_params( lameGlobalFlags) ) { throw Exception( __FILE__, __LINE__, "lame lib initializing params error" ); } lame_print_config( lameGlobalFlags); // open the underlying sink if ( !sink->open() ) { throw Exception( __FILE__, __LINE__, "lame lib opening underlying sink error"); } return true; }
/*------------------------------------------------------------------------------ * Initialize the encoder *----------------------------------------------------------------------------*/ void OpusLibEncoder :: init ( unsigned int outMaxBitrate ) throw ( Exception ) { 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 ( getOutSampleRate() != 48000 ) { throw Exception( __FILE__, __LINE__, "unsupported sample rate for this encoder, you should resample your input to 48000Hz", getOutSampleRate() ); } if ( getOutSampleRate() == getInSampleRate() ) { resampleRatio = 1; converter = 0; } else { resampleRatio = ( (double) getOutSampleRate() / (double) getInSampleRate() ); // Determine if we can use linear interpolation. // The inverse of the ratio must be a power of two for linear mode to // be of sufficient quality. bool useLinear = true; double inverse = 1 / resampleRatio; int integer = (int) inverse; // Check that the inverse of the ratio is an integer if( integer == inverse ) { while( useLinear && integer ) { // Loop through the bits // If the lowest order bit is not the only one set if( integer & 1 && integer != 1 ) { // Not a power of two; cannot use linear useLinear = false; } else { // Shift all the bits over and try again integer >>= 1; } } } else { useLinear = false; } // If we get here and useLinear is still true, then we have // a power of two. // open the aflibConverter in // - high quality // - linear or quadratic (non-linear) based on algorithm // - not filter interpolation #ifdef HAVE_SRC_LIB int srcError = 0; converter = src_new(useLinear == true ? SRC_LINEAR : SRC_SINC_FASTEST, getInChannel(), &srcError); if(srcError) throw Exception (__FILE__, __LINE__, "libsamplerate error: ", src_strerror (srcError)); #else converter = new aflibConverter( true, useLinear, false); #endif }
/*------------------------------------------------------------------------------ * Open an encoding session *----------------------------------------------------------------------------*/ bool LameLibEncoder :: open ( void ) throw ( Exception ) { if ( isOpen() ) { close(); } lameGlobalFlags = lame_init(); // ugly lame returns -1 in a pointer on allocation errors if ( !lameGlobalFlags || ((int)lameGlobalFlags) == -1 ) { throw Exception( __FILE__, __LINE__, "lame lib init error", (int) lameGlobalFlags); } if ( 0 > lame_set_num_channels( lameGlobalFlags, getInChannel()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting channels error", getInChannel() ); } if ( 0 > lame_set_mode( lameGlobalFlags, getInChannel() == 1 ? MONO : JOINT_STEREO) ) { throw Exception( __FILE__, __LINE__, "lame lib setting mode error", JOINT_STEREO ); } reportEvent( 5, "set lame mode", lame_get_mode( lameGlobalFlags)); reportEvent( 5, "set lame channels", lame_get_num_channels( lameGlobalFlags)); if ( 0 > lame_set_in_samplerate( lameGlobalFlags, getInSampleRate()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting input sample rate error", getInSampleRate() ); } reportEvent( 5, "set lame in sample rate", lame_get_in_samplerate( lameGlobalFlags)); if ( 0 > lame_set_out_samplerate( lameGlobalFlags, getOutSampleRate()) ) { throw Exception( __FILE__, __LINE__, "lame lib setting output sample rate error", getOutSampleRate() ); } reportEvent( 5, "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() ); } reportEvent( 5, "set lame bit rate", lame_get_brate( lameGlobalFlags)); if ( lowpass ) { if ( 0 > lame_set_lowpassfreq( lameGlobalFlags, lowpass) ) { throw Exception( __FILE__, __LINE__, "lame lib setting lowpass frequency error", lowpass ); } reportEvent( 5, "set lame lowpass frequency", lame_get_lowpassfreq( lameGlobalFlags)); } if ( highpass ) { if ( 0 > lame_set_highpassfreq( lameGlobalFlags, highpass) ) { throw Exception( __FILE__, __LINE__, "lame lib setting highpass frequency error", lowpass ); } reportEvent( 5, "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__, "lame lib setting psycho acoustic model error"); } reportEvent( 5, "set lame psycho acoustic model", lame_get_exp_nspsytune( lameGlobalFlags)); if ( 0 > lame_set_error_protection( lameGlobalFlags, 1) ) { throw Exception( __FILE__, __LINE__, "lame lib setting error protection error", 1 ); } reportEvent( 5, "set lame error protection", lame_get_error_protection( lameGlobalFlags)); // let lame init its own params based on our settings if ( 0 > lame_init_params( lameGlobalFlags) ) { throw Exception( __FILE__, __LINE__, "lame lib initializing params error" ); } lame_print_config( lameGlobalFlags); // open the underlying sink if ( !sink->open() ) { throw Exception( __FILE__, __LINE__, "lame lib opening underlying sink error"); } return true; }
/*------------------------------------------------------------------------------ * Open an encoding session *----------------------------------------------------------------------------*/ bool aacPlusEncoder :: open ( void ) throw ( Exception ) { if ( isOpen() ) { close(); } // open the underlying sink if ( !sink->open() ) { throw Exception( __FILE__, __LINE__, "aacplus lib opening underlying sink error"); } reportEvent(1, "Using aacplus codec version", "720 3gpp"); bitrate = getOutBitrate() * 1000; bandwidth = 0; useParametricStereo = 0; numAncDataBytes=0; coreWriteOffset = 0; envReadOffset = 0; writeOffset = INPUT_DELAY*MAX_CHANNELS; writtenSamples = 0; aacEnc = NULL; hEnvEnc=NULL; /* set up basic parameters for aacPlus codec */ AacInitDefaultConfig(&config); nChannelsAAC = nChannelsSBR = getOutChannel(); if ( (getInChannel() == 2) && (bitrate >= 16000) && (bitrate < 44001) ) { useParametricStereo = 1; nChannelsAAC = 1; nChannelsSBR = 2; reportEvent(10, "use Parametric Stereo"); envReadOffset = (MAX_DS_FILTER_DELAY + INPUT_DELAY)*MAX_CHANNELS; coreWriteOffset = CORE_INPUT_OFFSET_PS; writeOffset = envReadOffset; } else { /* set up 2:1 downsampling */ InitIIR21_Resampler(&(IIR21_reSampler[0])); InitIIR21_Resampler(&(IIR21_reSampler[1])); if(IIR21_reSampler[0].delay > MAX_DS_FILTER_DELAY) throw Exception(__FILE__, __LINE__, "IIR21 resampler delay is bigger then MAX_DS_FILTER_DELAY"); writeOffset += IIR21_reSampler[0].delay*MAX_CHANNELS; } sampleRateAAC = getInSampleRate(); config.bitRate = bitrate; config.nChannelsIn=getInChannel(); config.nChannelsOut=nChannelsAAC; config.bandWidth=bandwidth; /* set up SBR configuration */ if(!IsSbrSettingAvail(bitrate, nChannelsAAC, sampleRateAAC, &sampleRateAAC)) throw Exception(__FILE__, __LINE__, "No valid SBR configuration found"); InitializeSbrDefaults (&sbrConfig); sbrConfig.usePs = useParametricStereo; AdjustSbrSettings( &sbrConfig, bitrate, nChannelsAAC, sampleRateAAC, AACENC_TRANS_FAC, 24000); EnvOpen( &hEnvEnc, inBuf + coreWriteOffset, &sbrConfig, &config.bandWidth); /* set up AAC encoder, now that samling rate is known */ config.sampleRate = sampleRateAAC; if (AacEncOpen(&aacEnc, config) != 0){ AacEncClose(aacEnc); throw Exception(__FILE__, __LINE__, "Initialisation of AAC failed !"); } init_plans(); /* create the ADTS header */ adts_hdr(outBuf, &config); inSamples = AACENC_BLOCKSIZE * getInChannel() * 2; aacplusOpen = true; reportEvent(10, "bitrate=", bitrate); reportEvent(10, "nChannelsIn", getInChannel()); reportEvent(10, "nChannelsOut", getOutChannel()); reportEvent(10, "nChannelsSBR", nChannelsSBR); reportEvent(10, "nChannelsAAC", nChannelsAAC); reportEvent(10, "sampleRateAAC", sampleRateAAC); reportEvent(10, "inSamples", inSamples); return true; }