| /* ------------------------------------------------------------------ |
| * Copyright (C) 2008 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| /**************************************************************************************** |
| Portions of this file are derived from the following 3GPP standard: |
| |
| 3GPP TS 26.073 |
| ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec |
| Available from http://www.3gpp.org |
| |
| (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC) |
| Permission to distribute, modify and use this file under the standard license |
| terms listed above has been obtained from the copyright holder. |
| ****************************************************************************************/ |
| #ifndef GSMAMR_ENC_H_INCLUDED |
| #include "gsmamr_enc.h" |
| #endif |
| |
| #ifndef GSMAMR_ENCODER_WRAPPER_H_INCLUDED |
| #include "gsmamr_encoder_wrapper.h" |
| #endif |
| |
| #ifndef OSCL_DLL_H_INCLUDED |
| #include "oscl_dll.h" |
| #endif |
| |
| // Define entry point for this DLL |
| OSCL_DLL_ENTRY_POINT_DEFAULT() |
| |
| //---------------------------------------------------------------------------- |
| // CONSTANTS |
| //---------------------------------------------------------------------------- |
| |
| // Number of samples per frame |
| #define KGAMR_NUM_SAMPLES_PER_FRAME 160 |
| |
| // Default mode |
| #define KDFLT_GAMR_MODE MR475 |
| |
| // Default bits per sample for input audio |
| #define KDFLT_GAMR_BITS_PER_SAMPLE 16 |
| |
| // Default sampling rate for input audio (in Hz) |
| #define KDFLT_GAMR_SAMPLING_RATE 8000 |
| |
| // Default input clock rate for input audio (in ticks/sec) |
| #define KDFLT_GAMR_CLOCK_RATE 8000 |
| |
| // Default number of channels |
| #define KDFLT_GAMR_NUM_CHANNELS 1 |
| |
| // length of uncompressed audio frame in bytes |
| // Formula: (num_samples_per_frame * bits_per_sample) / num_bits_per_byte |
| #define PV_GSM_AMR_20_MSEC_SIZE \ |
| ((KGAMR_NUM_SAMPLES_PER_FRAME * KDFLT_GAMR_BITS_PER_SAMPLE) / 8) |
| |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| OSCL_EXPORT_REF |
| CPvGsmAmrEncoder::CPvGsmAmrEncoder() |
| { |
| // initialize member data to default values |
| iEncState = NULL; |
| iSidState = NULL; |
| iGsmAmrMode = (GSM_AMR_MODES)KDFLT_GAMR_MODE; |
| iLastModeUsed = 0; |
| iBitStreamFormatIf2 = AMR_TX_WMF; |
| iNumSamplesPerFrame = KGAMR_NUM_SAMPLES_PER_FRAME; |
| } |
| /////////////////////////////////////////////////////////////////////////////// |
| OSCL_EXPORT_REF CPvGsmAmrEncoder::~CPvGsmAmrEncoder() |
| { |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| OSCL_EXPORT_REF int32 CPvGsmAmrEncoder::InitializeEncoder(int32 aMaxOutputBufferSize, TEncodeProperties* aProps) |
| { |
| if (aProps == NULL) |
| { |
| // use default parameters |
| TEncodeProperties dfltProps; |
| aProps = &dfltProps; |
| dfltProps.iInBitsPerSample = KDFLT_GAMR_BITS_PER_SAMPLE; |
| dfltProps.iInSamplingRate = KDFLT_GAMR_SAMPLING_RATE; |
| dfltProps.iInClockRate = dfltProps.iInSamplingRate; |
| dfltProps.iInNumChannels = KDFLT_GAMR_NUM_CHANNELS; |
| iGsmAmrMode = (GSM_AMR_MODES)KDFLT_GAMR_MODE; |
| iBitStreamFormatIf2 = AMR_TX_WMF; |
| } |
| else |
| { |
| // check first if input parameters are valid |
| if ((IsModeValid(aProps->iMode) == false) || |
| (aProps->iInBitsPerSample == 0) || |
| (aProps->iInClockRate == 0) || |
| (aProps->iInSamplingRate == 0) || |
| (aProps->iInNumChannels == 0)) |
| { |
| return GSMAMR_ENC_INVALID_PARAM; |
| } |
| // set AMR mode (bits per second) |
| iGsmAmrMode = (GSM_AMR_MODES)aProps->iMode; |
| if (aProps->iBitStreamFormatIf2 == false) |
| { |
| iBitStreamFormatIf2 = AMR_TX_WMF; |
| } |
| else |
| { |
| iBitStreamFormatIf2 = AMR_TX_IF2; |
| } |
| } |
| |
| iBytesPerSample = aProps->iInBitsPerSample / 8; |
| |
| // set maximum buffer size for encoded data |
| iMaxOutputBufferSize = aMaxOutputBufferSize; |
| // return output parameters that will be used |
| aProps->iOutSamplingRate = KDFLT_GAMR_SAMPLING_RATE; |
| aProps->iOutNumChannels = KDFLT_GAMR_NUM_CHANNELS; |
| aProps->iOutClockRate = aProps->iOutSamplingRate; |
| |
| // initialize AMR encoder |
| int32 nResult = AMREncodeInit(&iEncState, &iSidState, false); |
| if (nResult < 0) return(GSMAMR_ENC_CODEC_INIT_FAILURE); |
| |
| return GSMAMR_ENC_NO_ERROR; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////// |
| OSCL_EXPORT_REF int32 CPvGsmAmrEncoder::Encode(TInputAudioStream& aInStream, |
| TOutputAudioStream& aOutStream) |
| { |
| // check first if mode specified is invalid |
| if (IsModeValid(aInStream.iMode) == false) |
| return GSMAMR_ENC_INVALID_MODE; |
| |
| |
| // set AMR mode for this set of samples |
| iGsmAmrMode = (GSM_AMR_MODES)aInStream.iMode; |
| |
| // get the maximum number of frames // BX |
| int32 bytesPerFrame = iNumSamplesPerFrame * iBytesPerSample; |
| int32 maxNumFrames = aInStream.iSampleLength / bytesPerFrame; |
| uint8 *pFrameIn = aInStream.iSampleBuffer; |
| uint8 *pFrameOut = aOutStream.iBitStreamBuffer; |
| int32 i; |
| |
| // encode samples |
| for (i = 0; i < maxNumFrames; i++) |
| { |
| |
| // ////////////////////////////////////////// |
| // encode this frame |
| // ////////////////////////////////////////// |
| Word16 nStatus = AMREncode(iEncState, iSidState, // BX, Word16 instead of int32 to avoid wierd case(IF2 format): the function returns 31, but nStatus ends up with a big wierd number |
| (Mode)iGsmAmrMode, |
| (Word16 *)pFrameIn, |
| (unsigned char *)pFrameOut, |
| (Frame_Type_3GPP*) & iLastModeUsed, |
| iBitStreamFormatIf2); |
| if (nStatus < 0) |
| { |
| // an error when encoding was received, so quit |
| return(GSMAMR_ENC_CODEC_ENCODE_FAILURE); |
| } |
| |
| // save nStatus as this indicates the encoded frame size |
| int32 encFrameSize = (int32)nStatus; |
| aOutStream.iSampleFrameSize[i] = encFrameSize; |
| pFrameOut += encFrameSize; |
| pFrameIn += bytesPerFrame; |
| } |
| |
| // set other values to be returned |
| aOutStream.iNumSampleFrames = maxNumFrames; |
| return(GSMAMR_ENC_NO_ERROR); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////// |
| OSCL_EXPORT_REF int32 CPvGsmAmrEncoder::CleanupEncoder() |
| { |
| // call terminate function of GSM AMR encoder |
| AMREncodeExit(&iEncState, &iSidState); |
| |
| iEncState = NULL; |
| iSidState = NULL; |
| |
| return GSMAMR_ENC_NO_ERROR; |
| } |
| |