예제 #1
0
/*------------------------------------------------------------------------------
 *  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);
    }
예제 #2
0
/*------------------------------------------------------------------------------
 *  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;
}
예제 #3
0
/*------------------------------------------------------------------------------
 *  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;
}
예제 #4
0
/*------------------------------------------------------------------------------
 *  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;
}
예제 #5
0
/*------------------------------------------------------------------------------
 *  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;
}
예제 #6
0
/*------------------------------------------------------------------------------
 *  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;
}
예제 #7
0
/*------------------------------------------------------------------------------
 *  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;
}
예제 #8
0
/*------------------------------------------------------------------------------
 *  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;
}
예제 #9
0
/*------------------------------------------------------------------------------
 *  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
    }
예제 #10
0
/*------------------------------------------------------------------------------
 *  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;
}
예제 #11
0
/*------------------------------------------------------------------------------
 *  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;
}