/*------------------------------------------------------------------------------ * 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); }
/*------------------------------------------------------------------------------ * Write data to the encoder *----------------------------------------------------------------------------*/ unsigned int VorbisLibEncoder :: write ( const void * buf, unsigned int len ) throw ( Exception ) { if ( !isOpen() ) { return 0; } 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); unsigned int nSamples = processed / sampleSize; float ** vorbisBuffer; // convert the byte-based raw input into a short buffer // with channels still interleaved unsigned int totalSamples = nSamples * channels; short int shortBuffer[totalSamples]; Util::conv( bitsPerSample, b, processed, shortBuffer, isInBigEndian()); if ( converter ) { // resample if needed int inCount = totalSamples; int outCount = (int) (inCount * resampleRatio); short int resampledBuffer[outCount * channels]; int converted; converted = converter->resample( inCount, outCount, shortBuffer, resampledBuffer ); vorbisBuffer = vorbis_analysis_buffer( &vorbisDspState, converted / channels); Util::conv( resampledBuffer, converted, vorbisBuffer, channels); vorbis_analysis_wrote( &vorbisDspState, converted / channels); } else { vorbisBuffer = vorbis_analysis_buffer( &vorbisDspState, nSamples); Util::conv( shortBuffer, totalSamples, vorbisBuffer, channels); vorbis_analysis_wrote( &vorbisDspState, nSamples); } vorbisBlocksOut(); return processed; }
/*------------------------------------------------------------------------------ * 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 = getOutSampleRate(); 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; // initialize the resampling coverter if needed if ( converter ) { #ifdef HAVE_SRC_LIB converterData.input_frames = 4096/((getInBitsPerSample() / 8) * getInChannel()); converterData.data_in = new float[converterData.input_frames*getInChannel()]; converterData.output_frames = (int) (converterData.input_frames * resampleRatio + 1); if ((int) inSamples > getInChannel() * converterData.output_frames) { resampledOffset = new float[2 * inSamples]; } else { resampledOffset = new float[2 * getInChannel() * converterData.input_frames]; } converterData.src_ratio = resampleRatio; converterData.end_of_input = 0; #else converter->initialize( resampleRatio, getInChannel()); //needed 2x(converted input samples) to handle offsets int outCount = 2 * getInChannel() * (inSamples + 1); if (resampleRatio > 1) outCount = (int) (outCount * resampleRatio); resampledOffset = new short int[outCount]; #endif resampledOffsetSize = 0; } 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; }
/*------------------------------------------------------------------------------ * Write data to the encoder *----------------------------------------------------------------------------*/ unsigned int aacPlusEncoder :: write ( const void * buf, unsigned int len ) throw ( Exception ) { if ( !isOpen() || len == 0) { return 0; } unsigned int channels = getInChannel(); unsigned int bitsPerSample = getInBitsPerSample(); unsigned int sampleSize = (bitsPerSample / 8) * channels; unsigned int processed = len - (len % sampleSize); unsigned int nSamples = processed / sampleSize; unsigned int samples = (unsigned int) nSamples * channels; int processedSamples = 0; if ( converter ) { unsigned int converted; #ifdef HAVE_SRC_LIB src_short_to_float_array ((short *) buf, converterData.data_in, samples); converterData.input_frames = nSamples; converterData.data_out = resampledOffset + (resampledOffsetSize * channels); int srcError = src_process (converter, &converterData); if (srcError) throw Exception (__FILE__, __LINE__, "libsamplerate error: ", src_strerror (srcError)); converted = converterData.output_frames_gen; #else int inCount = nSamples; short int * shortBuffer = new short int[samples]; int outCount = (int) (inCount * resampleRatio); unsigned char * b = (unsigned char*) buf; Util::conv( bitsPerSample, b, processed, shortBuffer, isInBigEndian()); converted = converter->resample( inCount, outCount+1, shortBuffer, &resampledOffset[resampledOffsetSize*channels]); delete[] shortBuffer; #endif resampledOffsetSize += converted; // encode samples (if enough) while(resampledOffsetSize - processedSamples >= inSamples/channels) { #ifdef HAVE_SRC_LIB short *shortData = new short[inSamples]; src_float_to_short_array(resampledOffset + (processedSamples * channels), shortData, inSamples) ; encodeAacSamples (shortData, inSamples, channels); delete [] shortData; #else encodeAacSamples (&resampledOffset[processedSamples*channels], inSamples, channels); #endif processedSamples+=inSamples/channels; } if (processedSamples && (int) resampledOffsetSize >= processedSamples) { resampledOffsetSize -= processedSamples; //move least part of resampled data to beginning if(resampledOffsetSize) #ifdef HAVE_SRC_LIB resampledOffset = (float *) memmove(resampledOffset, &resampledOffset[processedSamples*channels], resampledOffsetSize*channels*sizeof(float)); #else resampledOffset = (short *) memmove(resampledOffset, &resampledOffset[processedSamples*channels], resampledOffsetSize*sampleSize); #endif } } else { encodeAacSamples ((short *) buf, samples, channels); } return samples; }
/*------------------------------------------------------------------------------ * Write data to the encoder *----------------------------------------------------------------------------*/ unsigned int LameLibEncoder :: write ( const void * buf, unsigned int len ) throw ( Exception ) { if ( !isOpen() ) { return 0; } unsigned int bitsPerSample = getInBitsPerSample(); unsigned int inChannels = getInChannel(); unsigned int sampleSize = (bitsPerSample / 8) * inChannels; unsigned char * b = (unsigned char*) buf; unsigned int processed = len - (len % sampleSize); unsigned int nSamples = processed / sampleSize; short int * leftBuffer = new short int[nSamples]; short int * rightBuffer = new short int[nSamples]; if ( bitsPerSample == 8 ) { Util::conv8( b, processed, leftBuffer, rightBuffer, inChannels); } else if ( bitsPerSample == 16 ) { Util::conv16( b, processed, leftBuffer, rightBuffer, inChannels, isInBigEndian()); } else { delete[] leftBuffer; delete[] rightBuffer; throw Exception( __FILE__, __LINE__, "unsupported number of bits per sample for the encoder", bitsPerSample ); } // data chunk size estimate according to lame documentation // NOTE: mp3Size is calculated based on the number of input channels // which may be bigger than need, as output channels can be less unsigned int mp3Size = (unsigned int) (1.25 * nSamples + 7200); unsigned char * mp3Buf = new unsigned char[mp3Size]; int ret; ret = lame_encode_buffer( lameGlobalFlags, leftBuffer, inChannels == 2 ? rightBuffer : leftBuffer, nSamples, mp3Buf, mp3Size ); delete[] leftBuffer; delete[] rightBuffer; if ( ret < 0 ) { reportEvent( 3, "lame encoding error", ret); delete[] mp3Buf; return 0; } unsigned int written = sink->write( mp3Buf, ret); delete[] mp3Buf; // just let go data that could not be written if ( written < (unsigned int) ret ) { reportEvent( 2, "couldn't write all from encoder to underlying sink", ret - written); } return processed; }
/*------------------------------------------------------------------------------ * Open an encoding session *----------------------------------------------------------------------------*/ bool FaacEncoder :: open ( void ) throw ( Exception ) { if ( isOpen() ) { close(); } // open the underlying sink if ( !getSink()->open() ) { throw Exception( __FILE__, __LINE__, "faac lib opening underlying sink error"); } char * faacVersion; char * faacCopyright; faacEncGetVersion(&faacVersion, &faacCopyright); reportEvent(1, "Using faac codec version", faacVersion); encoderHandle = faacEncOpen(getOutSampleRate(), getInChannel(), &inputSamples, &maxOutputBytes); faacEncConfiguration * faacConfig; faacConfig = faacEncGetCurrentConfiguration(encoderHandle); faacConfig->aacObjectType = MAIN; faacConfig->mpegVersion = MPEG2; faacConfig->useTns = 1; faacConfig->shortctl = SHORTCTL_NORMAL; faacConfig->useLfe = 0; faacConfig->allowMidside = 1; faacConfig->bitRate = getOutBitrate() * 1000 / getOutChannel(); faacConfig->bandWidth = lowpass; faacConfig->quantqual = (unsigned long) (getOutQuality() * 1000.0); faacConfig->outputFormat = 1; faacConfig->inputFormat = FAAC_INPUT_16BIT; if (!faacEncSetConfiguration(encoderHandle, faacConfig)) { throw Exception(__FILE__, __LINE__, "error configuring faac library"); } // initialize the resampling coverter if needed if ( converter ) { #ifdef HAVE_SRC_LIB converterData.input_frames = 4096/((getInBitsPerSample() / 8) * getInChannel()); converterData.data_in = new float[converterData.input_frames*getInChannel()]; converterData.output_frames = (int) (converterData.input_frames * resampleRatio + 1); if ((int) inputSamples > getInChannel() * converterData.output_frames) { resampledOffset = new float[2 * inputSamples]; } else { resampledOffset = new float[2 * getInChannel() * converterData.input_frames]; } converterData.src_ratio = resampleRatio; converterData.end_of_input = 0; #else converter->initialize( resampleRatio, getInChannel()); //needed 2x(converted input samples) to handle offsets int outCount = 2 * getInChannel() * (inputSamples + 1); if (resampleRatio > 1) outCount = (int) (outCount * resampleRatio); resampledOffset = new short int[outCount]; #endif resampledOffsetSize = 0; } faacOpen = true; return true; }
/*------------------------------------------------------------------------------ * Write data to the encoder *----------------------------------------------------------------------------*/ unsigned int LameLibEncoder :: write ( const void * buf, unsigned int len ) throw ( Exception ) { if ( !isOpen() ) { return 0; } 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); unsigned int nSamples = processed / sampleSize; short int leftBuffer[nSamples]; short int rightBuffer[nSamples]; if ( bitsPerSample == 8 ) { conv8( b, processed, leftBuffer, rightBuffer, channels); } else if ( bitsPerSample == 16 ) { conv16( b, processed, leftBuffer, rightBuffer, channels); } else { throw Exception( __FILE__, __LINE__, "unsupported number of bits per sample for the encoder", bitsPerSample ); } // data chunk size estimate according to lame documentation unsigned int mp3Size = (unsigned int) (1.25 * nSamples + 7200); unsigned char mp3Buf[mp3Size]; int ret; ret = lame_encode_buffer( lameGlobalFlags, leftBuffer, channels == 2 ? rightBuffer : leftBuffer, nSamples, mp3Buf, mp3Size ); if ( ret < 0 ) { reportEvent( 3, "lame encoding error", ret); return 0; } unsigned int written = sink->write( mp3Buf, ret); // just let go data that could not be written if ( written < (unsigned int) ret ) { reportEvent( 2, "couldn't write all from encoder to underlying sink", ret - written); } return processed; }
/*------------------------------------------------------------------------------ * 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"); encoderHandle = aacplusEncOpen(getOutSampleRate(), getInChannel(), &inputSamples, &maxOutputBytes); aacplusEncConfiguration * aacplusConfig; aacplusConfig = aacplusEncGetCurrentConfiguration(encoderHandle); aacplusConfig->bitRate = getOutBitrate() * 1000; aacplusConfig->bandWidth = lowpass; aacplusConfig->outputFormat = 1; aacplusConfig->inputFormat = AACPLUS_INPUT_16BIT; aacplusConfig->nChannelsOut = getOutChannel(); if (!aacplusEncSetConfiguration(encoderHandle, aacplusConfig)) { throw Exception(__FILE__, __LINE__, "error configuring libaacplus library"); } // initialize the resampling coverter if needed if ( converter ) { #ifdef HAVE_SRC_LIB converterData.input_frames = 4096/((getInBitsPerSample() / 8) * getInChannel()); converterData.data_in = new float[converterData.input_frames*getInChannel()]; converterData.output_frames = (int) (converterData.input_frames * resampleRatio + 1); if ((int) inputSamples > getInChannel() * converterData.output_frames) { resampledOffset = new float[2 * inputSamples]; } else { resampledOffset = new float[2 * getInChannel() * converterData.input_frames]; } converterData.src_ratio = resampleRatio; converterData.end_of_input = 0; #else converter->initialize( resampleRatio, getInChannel()); //needed 2x(converted input samples) to handle offsets int outCount = 2 * getInChannel() * (inputSamples + 1); if (resampleRatio > 1) outCount = (int) (outCount * resampleRatio); resampledOffset = new short int[outCount]; #endif resampledOffsetSize = 0; } aacplusOpen = true; reportEvent(10, "nChannelsAAC", aacplusConfig->nChannelsOut); reportEvent(10, "sampleRateAAC", aacplusConfig->sampleRate); reportEvent(10, "inSamples", inputSamples); 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 }
/*------------------------------------------------------------------------------ * Write data to the encoder *----------------------------------------------------------------------------*/ unsigned int aacPlusEncoder :: write ( const void * buf, unsigned int len ) throw ( Exception ) { if ( !isOpen() || len == 0) { return 0; } unsigned int channels = getInChannel(); unsigned int bitsPerSample = getInBitsPerSample(); unsigned int sampleSize = (bitsPerSample / 8) * channels; unsigned int processed = len - (len % sampleSize); unsigned int nSamples = processed / sampleSize; unsigned int samples = (unsigned int) nSamples * channels; unsigned int i; int ch, outSamples, numOutBytes; reportEvent(10, "converting short to float"); short *TimeDataPcm = (short *) buf; if(channels == 2) { for (i=0; i<samples; i++) inBuf[i+writeOffset+writtenSamples] = (float) TimeDataPcm[i]; } else { /* using only left channel buffer for mono encoder */ for (i=0; i<samples; i++) inBuf[writeOffset+2*writtenSamples+2*i] = (float) TimeDataPcm[i]; } writtenSamples+=samples; reportEvent(10, "writtenSamples", writtenSamples); if (writtenSamples < inSamples) return samples; /* encode one SBR frame */ reportEvent(10, "encode one SBR frame"); EnvEncodeFrame( hEnvEnc, inBuf + envReadOffset, inBuf + coreWriteOffset, MAX_CHANNELS, &numAncDataBytes, ancDataBytes); reportEvent(10, "numAncDataBytes=", numAncDataBytes); /* 2:1 downsampling for AAC core */ if (!useParametricStereo) { reportEvent(10, "2:1 downsampling for AAC core"); for( ch=0; ch<nChannelsAAC; ch++ ) IIR21_Downsample( &(IIR21_reSampler[ch]), inBuf + writeOffset+ch, writtenSamples/channels, MAX_CHANNELS, inBuf+ch, &outSamples, MAX_CHANNELS); reportEvent(10, "outSamples=", outSamples); } /* encode one AAC frame */ reportEvent(10, "encode one AAC frame"); AacEncEncode( aacEnc, inBuf, useParametricStereo ? 1 : MAX_CHANNELS, /* stride (step) */ ancDataBytes, &numAncDataBytes, (unsigned *) (outBuf+ADTS_HEADER_SIZE), &numOutBytes); if (useParametricStereo) { memcpy( inBuf,inBuf+AACENC_BLOCKSIZE,CORE_INPUT_OFFSET_PS*sizeof(float)); } else { memmove( inBuf,inBuf+AACENC_BLOCKSIZE*2*MAX_CHANNELS,writeOffset*sizeof(float)); } /* Write one frame of encoded audio */ if (numOutBytes) { reportEvent(10, "Write one frame of encoded audio:", numOutBytes+ADTS_HEADER_SIZE); adts_hdr_up(outBuf, numOutBytes); sink->write(outBuf, numOutBytes+ADTS_HEADER_SIZE); } writtenSamples=0; return samples; }
/*------------------------------------------------------------------------------ * Write data to the encoder *----------------------------------------------------------------------------*/ unsigned int aacPlusEncoder :: write ( const void * buf, unsigned int len ) throw ( Exception ) { if ( !isOpen() || len == 0) { return 0; } unsigned int channels = getInChannel(); unsigned int bitsPerSample = getInBitsPerSample(); unsigned int sampleSize = (bitsPerSample / 8) * channels; unsigned char * b = (unsigned char*) buf; unsigned int processed = len - (len % sampleSize); unsigned int nSamples = processed / sampleSize; unsigned char * aacplusBuf = new unsigned char[maxOutputBytes]; int samples = (int) nSamples * channels; int processedSamples = 0; if ( converter ) { unsigned int converted; #ifdef HAVE_SRC_LIB src_short_to_float_array ((short *) b, converterData.data_in, samples); converterData.input_frames = nSamples; converterData.data_out = resampledOffset + (resampledOffsetSize * channels); int srcError = src_process (converter, &converterData); if (srcError) throw Exception (__FILE__, __LINE__, "libsamplerate error: ", src_strerror (srcError)); converted = converterData.output_frames_gen; #else int inCount = nSamples; short int * shortBuffer = new short int[samples]; int outCount = (int) (inCount * resampleRatio); Util::conv( bitsPerSample, b, processed, shortBuffer, isInBigEndian()); converted = converter->resample( inCount, outCount+1, shortBuffer, &resampledOffset[resampledOffsetSize*channels]); delete[] shortBuffer; #endif resampledOffsetSize += converted; // encode samples (if enough) while(resampledOffsetSize - processedSamples >= inputSamples/channels) { #ifdef HAVE_SRC_LIB short *shortData = new short[inputSamples]; src_float_to_short_array(resampledOffset + (processedSamples * channels), shortData, inputSamples) ; int outputBytes = aacplusEncEncode(encoderHandle, (int32_t*) shortData, inputSamples, aacplusBuf, maxOutputBytes); delete [] shortData; #else int outputBytes = aacplusEncEncode(encoderHandle, (int32_t*) &resampledOffset[processedSamples*channels], inputSamples, aacplusBuf, maxOutputBytes); #endif unsigned int wrote = getSink()->write(aacplusBuf, outputBytes); if (wrote < outputBytes) { reportEvent(3, "aacPlusEncoder :: write, couldn't write full data to underlying sink"); } processedSamples+=inputSamples/channels; } if (processedSamples && (int) resampledOffsetSize >= processedSamples) { resampledOffsetSize -= processedSamples; //move least part of resampled data to beginning if(resampledOffsetSize) #ifdef HAVE_SRC_LIB resampledOffset = (float *) memmove(resampledOffset, &resampledOffset[processedSamples*channels], resampledOffsetSize*channels*sizeof(float)); #else resampledOffset = (short *) memmove(resampledOffset, &resampledOffset[processedSamples*channels], resampledOffsetSize*sampleSize); #endif } } else { while (processedSamples < samples) { int inSamples = samples - processedSamples < (int) inputSamples ? samples - processedSamples : inputSamples; int outputBytes = aacplusEncEncode(encoderHandle, (int32_t*) (b + processedSamples/sampleSize), inSamples, aacplusBuf, maxOutputBytes); unsigned int wrote = getSink()->write(aacplusBuf, outputBytes); if (wrote < outputBytes) { reportEvent(3, "aacPlusEncoder :: write, couldn't write full data to underlying sink"); } processedSamples += inSamples; } } delete[] aacplusBuf; // return processedSamples; return samples * sampleSize; }