diff --git a/src/engine/media/MT_AudioCodec.cpp b/src/engine/media/MT_AudioCodec.cpp index a2af9122..c4fe0cce 100644 --- a/src/engine/media/MT_AudioCodec.cpp +++ b/src/engine/media/MT_AudioCodec.cpp @@ -40,22 +40,22 @@ using namespace MT; const char* G729Codec::G729Factory::name() { - return "G729"; + return "G729"; } int G729Codec::G729Factory::channels() { - return 1; + return 1; } int G729Codec::G729Factory::samplerate() { - return 8000; + return 8000; } int G729Codec::G729Factory::payloadType() { - return 18; + return 18; } #if defined(USE_RESIP_INTEGRATION) @@ -65,14 +65,14 @@ void G729Codec::G729Factory::updateSdp(resip::SdpContents::Session::Medium::Code int G729Codec::G729Factory::processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) { - return 0; + return 0; } #endif PCodec G729Codec::G729Factory::create() { - return std::make_shared(); + return std::make_shared(); } G729Codec::G729Codec() @@ -82,148 +82,148 @@ G729Codec::G729Codec() G729Codec::~G729Codec() { - if (mEncoder) - { - free(mEncoder); - mEncoder = nullptr; - } + if (mEncoder) + { + free(mEncoder); + mEncoder = nullptr; + } - if (mDecoder) - { - free(mDecoder); - mDecoder = nullptr; - } + if (mDecoder) + { + free(mDecoder); + mDecoder = nullptr; + } } const char* G729Codec::name() { - return "G729"; + return "G729"; } int G729Codec::pcmLength() { - return 10 * 8 * 2; + return 10 * 8 * 2; } int G729Codec::rtpLength() { - return 10; + return 10; } int G729Codec::frameTime() { - return 10; + return 10; } int G729Codec::samplerate() { - return 8000; + return 8000; } int G729Codec::channels() { - return 1; + return 1; } // static const int SamplesPerFrame = 80; int G729Codec::encode(const void* input, int inputBytes, void* output, int outputCapacity) { - // Create encoder if it is not done yet - if (!mEncoder) - { - mEncoder = Init_Coder_ld8a(); - if (mEncoder) - Init_Pre_Process(mEncoder); - } - int result = 0; - if (mEncoder) - { - int nrOfFrames = inputBytes / 160; // 10ms frames - Word16 parm[PRM_SIZE]; // ITU's service buffer - for (int frameIndex = 0; frameIndex < nrOfFrames; frameIndex++) + // Create encoder if it is not done yet + if (!mEncoder) { - Copy((int16_t*)input + frameIndex * pcmLength() / 2, mEncoder->new_speech, pcmLength() / 2); - Pre_Process(mEncoder, mEncoder->new_speech, pcmLength() / 2); - Coder_ld8a(mEncoder, parm); - Store_Params(parm, (uint8_t*)output + frameIndex * rtpLength()); - result += rtpLength(); + mEncoder = Init_Coder_ld8a(); + if (mEncoder) + Init_Pre_Process(mEncoder); } - } - return result; + int result = 0; + if (mEncoder) + { + int nrOfFrames = inputBytes / 160; // 10ms frames + Word16 parm[PRM_SIZE]; // ITU's service buffer + for (int frameIndex = 0; frameIndex < nrOfFrames; frameIndex++) + { + Copy((int16_t*)input + frameIndex * pcmLength() / 2, mEncoder->new_speech, pcmLength() / 2); + Pre_Process(mEncoder, mEncoder->new_speech, pcmLength() / 2); + Coder_ld8a(mEncoder, parm); + Store_Params(parm, (uint8_t*)output + frameIndex * rtpLength()); + result += rtpLength(); + } + } + return result; } int G729Codec::decode(const void* input, int inputBytes, void* output, int outputCapacity) { - if (!mDecoder) - { - mDecoder = Init_Decod_ld8a(); + if (!mDecoder) + { + mDecoder = Init_Decod_ld8a(); + if (mDecoder) + { + Init_Post_Filter(mDecoder); + Init_Post_Process(mDecoder); + } + } + + int result = 0; if (mDecoder) { - Init_Post_Filter(mDecoder); - Init_Post_Process(mDecoder); + // See if there are silence bytes in the end + bool isSilence = (inputBytes % rtpLength()) / 2 != 0; + + // Find number of frames + int nrOfFrames = inputBytes / rtpLength(); + nrOfFrames = std::min(outputCapacity / pcmLength(), nrOfFrames); + + for (int frameIndex = 0; frameIndex < nrOfFrames; frameIndex++) + decodeFrame((const uint8_t*)input + frameIndex * rtpLength(), (int16_t*)output + frameIndex * pcmLength()); + + result += nrOfFrames * pcmLength(); + + if (isSilence && nrOfFrames < outputCapacity / pcmLength()) + { + memset((uint8_t*)output + nrOfFrames * pcmLength(), 0, pcmLength()); + result += pcmLength(); + } } - } - int result = 0; - if (mDecoder) - { - // See if there are silence bytes in the end - bool isSilence = (inputBytes % rtpLength()) / 2 != 0; - - // Find number of frames - int nrOfFrames = inputBytes / rtpLength(); - nrOfFrames = std::min(outputCapacity / pcmLength(), nrOfFrames); - - for (int frameIndex = 0; frameIndex < nrOfFrames; frameIndex++) - decodeFrame((const uint8_t*)input + frameIndex * rtpLength(), (int16_t*)output + frameIndex * pcmLength()); - - result += nrOfFrames * pcmLength(); - - if (isSilence && nrOfFrames < outputCapacity / pcmLength()) - { - memset((uint8_t*)output + nrOfFrames * pcmLength(), 0, pcmLength()); - result += pcmLength(); - } - } - - return result; + return result; } void G729Codec::decodeFrame(const uint8_t* rtp, int16_t* pcm) { - Word16 i; - Word16 *synth; - Word16 parm[PRM_SIZE + 1]; + Word16 i; + Word16 *synth; + Word16 parm[PRM_SIZE + 1]; - Restore_Params(rtp, &parm[1]); + Restore_Params(rtp, &parm[1]); - synth = mDecoder->synth_buf + M10; + synth = mDecoder->synth_buf + M10; - parm[0] = 1; - for (i = 0; i < PRM_SIZE; i++) - { - if (parm[i + 1] != 0) + parm[0] = 1; + for (i = 0; i < PRM_SIZE; i++) { - parm[0] = 0; - break; + if (parm[i + 1] != 0) + { + parm[0] = 0; + break; + } } - } - parm[4] = Check_Parity_Pitch(parm[3], parm[4]); + parm[4] = Check_Parity_Pitch(parm[3], parm[4]); - Decod_ld8a(mDecoder, parm, synth, mDecoder->Az_dec, mDecoder->T2, &mDecoder->bad_lsf); - Post_Filter(mDecoder, synth, mDecoder->Az_dec, mDecoder->T2); - Post_Process(mDecoder, synth, L_FRAME); + Decod_ld8a(mDecoder, parm, synth, mDecoder->Az_dec, mDecoder->T2, &mDecoder->bad_lsf); + Post_Filter(mDecoder, synth, mDecoder->Az_dec, mDecoder->T2); + Post_Process(mDecoder, synth, L_FRAME); - for (i = 0; i < pcmLength() / 2; i++) - pcm[i] = synth[i]; + for (i = 0; i < pcmLength() / 2; i++) + pcm[i] = synth[i]; } int G729Codec::plc(int lostFrames, void* output, int outputCapacity) { - return 0; + return 0; } #if defined(USE_OPUS_CODEC) @@ -235,133 +235,133 @@ int G729Codec::plc(int lostFrames, void* output, int outputCapacity) #define OPUS_CODEC_COMPLEXITY 2 OpusCodec::Params::Params() - :mUseDtx(false), mUseInbandFec(true), mStereo(true), mPtime(20) + :mUseDtx(false), mUseInbandFec(true), mStereo(true), mPtime(20) { - mExpectedPacketLoss = OPUS_PACKET_LOSS; - mTargetBitrate = OPUS_TARGET_BITRATE; + mExpectedPacketLoss = OPUS_PACKET_LOSS; + mTargetBitrate = OPUS_TARGET_BITRATE; } #if defined(USE_RESIP_INTEGRATION) resip::Data OpusCodec::Params::toString() const { - std::ostringstream oss; - //oss << "ptime=" << mPTime << ";"; - if (mUseDtx) - oss << "usedtx=" << (mUseDtx ? "1" : "0") << ";"; - if (mUseInbandFec) - oss << "useinbandfec=" << (mUseInbandFec ? "1" : "0") << ";"; - std::string r = oss.str(); + std::ostringstream oss; + //oss << "ptime=" << mPTime << ";"; + if (mUseDtx) + oss << "usedtx=" << (mUseDtx ? "1" : "0") << ";"; + if (mUseInbandFec) + oss << "useinbandfec=" << (mUseInbandFec ? "1" : "0") << ";"; + std::string r = oss.str(); - // Erase last semicolon - if (r.size()) - r.erase(r.size()-1); + // Erase last semicolon + if (r.size()) + r.erase(r.size()-1); - //oss << "stereo=" << (mStereo ? "1" : "0") << ";"; - return resip::Data(r); + //oss << "stereo=" << (mStereo ? "1" : "0") << ";"; + return resip::Data(r); } struct CodecParam { - resip::Data mName; - resip::Data mValue; + resip::Data mName; + resip::Data mValue; }; static void splitParams(const resip::Data& s, std::list& params) { - resip::Data::size_type p = 0; - while (p != resip::Data::npos) - { - resip::Data::size_type p1 = s.find(";", p); - - resip::Data param; - if (p1 != resip::Data::npos) + resip::Data::size_type p = 0; + while (p != resip::Data::npos) { - param = s.substr(p, p1 - p); - p = p1 + 1; - } - else - { - param = s.substr(p); - p = resip::Data::npos; - } + resip::Data::size_type p1 = s.find(";", p); + + resip::Data param; + if (p1 != resip::Data::npos) + { + param = s.substr(p, p1 - p); + p = p1 + 1; + } + else + { + param = s.substr(p); + p = resip::Data::npos; + } - CodecParam cp; - // See if there is '=' inside - resip::Data::size_type ep = param.find("="); - if (ep != resip::Data::npos) - { - cp.mName = param.substr(0, ep); - cp.mValue = param.substr(ep + 1); - } - else - cp.mName = param; + CodecParam cp; + // See if there is '=' inside + resip::Data::size_type ep = param.find("="); + if (ep != resip::Data::npos) + { + cp.mName = param.substr(0, ep); + cp.mValue = param.substr(ep + 1); + } + else + cp.mName = param; - params.push_back(cp); - } + params.push_back(cp); + } } void OpusCodec::Params::parse(const resip::Data ¶ms) { - // There is opus codec in sdp. Be simple - use the parameters from remote peer to operate - std::list parsed; - splitParams(params, parsed); + // There is opus codec in sdp. Be simple - use the parameters from remote peer to operate + std::list parsed; + splitParams(params, parsed); - std::list::const_iterator paramIter; - for (paramIter = parsed.begin(); paramIter != parsed.end(); ++paramIter) - { - if (paramIter->mName == "usedtx") - mUseDtx = paramIter->mValue == "1"; - else - if (paramIter->mName == "useinbandfec") - mUseInbandFec = paramIter->mValue == "1"; - else - if (paramIter->mName == "stereo") - mStereo = paramIter->mValue == "1"; - else - if (paramIter->mName == "ptime") - mPtime = strx::toInt(paramIter->mValue.c_str(), 20); - } + std::list::const_iterator paramIter; + for (paramIter = parsed.begin(); paramIter != parsed.end(); ++paramIter) + { + if (paramIter->mName == "usedtx") + mUseDtx = paramIter->mValue == "1"; + else + if (paramIter->mName == "useinbandfec") + mUseInbandFec = paramIter->mValue == "1"; + else + if (paramIter->mName == "stereo") + mStereo = paramIter->mValue == "1"; + else + if (paramIter->mName == "ptime") + mPtime = strx::toInt(paramIter->mValue.c_str(), 20); + } } #endif OpusCodec::OpusFactory::OpusFactory(int samplerate, int channels, int ptype) { - mSamplerate = samplerate; - mChannels = channels; - mPType = ptype; + mSamplerate = samplerate; + mChannels = channels; + mPType = ptype; } const char* OpusCodec::OpusFactory::name() { - return OPUS_CODEC_NAME; + return OPUS_CODEC_NAME; } int OpusCodec::OpusFactory::channels() { - return mChannels; + return mChannels; } int OpusCodec::OpusFactory::samplerate() { - return mSamplerate; + return mSamplerate; } int OpusCodec::OpusFactory::payloadType() { - return mPType; + return mPType; } #if defined(USE_RESIP_INTEGRATION) void OpusCodec::OpusFactory::updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) { - // Put opus codec record - resip::Codec opus(name(), payloadType(), samplerate()); - if (mParams.mStereo) - opus.encodingParameters() = "2"; - opus.parameters() = resip::Data(mParams.toString().c_str()); + // Put opus codec record + resip::Codec opus(name(), payloadType(), samplerate()); + if (mParams.mStereo) + opus.encodingParameters() = "2"; + opus.parameters() = resip::Data(mParams.toString().c_str()); - codecs.push_back(opus); + codecs.push_back(opus); } #if defined(TARGET_ANDROID) @@ -370,165 +370,169 @@ void OpusCodec::OpusFactory::updateSdp(resip::SdpContents::Session::Medium::Code int OpusCodec::OpusFactory::processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) { - resip::SdpContents::Session::Medium::CodecContainer::const_iterator codecIter; - for (codecIter = codecs.begin(); codecIter != codecs.end(); ++codecIter) - { - const resip::Codec& resipCodec = *codecIter; - // Accept only 48000Hz configurations - if (stricmp(resipCodec.getName().c_str(), name()) == 0 && resipCodec.getRate() == 48000) + resip::SdpContents::Session::Medium::CodecContainer::const_iterator codecIter; + for (codecIter = codecs.begin(); codecIter != codecs.end(); ++codecIter) { - mParams.parse(resipCodec.parameters()); + const resip::Codec& resipCodec = *codecIter; + // Accept only 48000Hz configurations + if (stricmp(resipCodec.getName().c_str(), name()) == 0 && resipCodec.getRate() == 48000) + { + mParams.parse(resipCodec.parameters()); - // Check number of channels - mParams.mStereo |= codecIter->encodingParameters() == "2"; + // Check number of channels + mParams.mStereo |= codecIter->encodingParameters() == "2"; - // Here changes must be applied to instantiated codec - for (CodecList::iterator instanceIter = mCodecList.begin(); instanceIter != mCodecList.end(); ++instanceIter) - { - Codec& c = **instanceIter; - if ((c.channels() == (mParams.mStereo ? 2 : 1)) && resipCodec.getRate() == c.samplerate()) - dynamic_cast(c).applyParams(mParams); - } - return codecIter->payloadType(); + // Here changes must be applied to instantiated codec + for (CodecList::iterator instanceIter = mCodecList.begin(); instanceIter != mCodecList.end(); ++instanceIter) + { + Codec& c = **instanceIter; + if ((c.channels() == (mParams.mStereo ? 2 : 1)) && resipCodec.getRate() == c.samplerate()) + dynamic_cast(c).applyParams(mParams); + } + return codecIter->payloadType(); + } } - } - return -1; + return -1; } #endif PCodec OpusCodec::OpusFactory::create() { - OpusCodec* result = new OpusCodec(mSamplerate, mChannels, mParams.mPtime); - result->applyParams(mParams); - PCodec c(result); - mCodecList.push_back(c); + OpusCodec* result = new OpusCodec(mSamplerate, mChannels, mParams.mPtime); + result->applyParams(mParams); + PCodec c(result); + mCodecList.push_back(c); - return c; + return c; } OpusCodec::OpusCodec(int samplerate, int channels, int ptime) - :mEncoderCtx(NULL), mDecoderCtx(NULL), mChannels(channels), mPTime(ptime), mSamplerate(samplerate) + :mEncoderCtx(NULL), mDecoderCtx(NULL), mChannels(channels), mPTime(ptime), mSamplerate(samplerate) { - int status; - mEncoderCtx = opus_encoder_create(48000, mChannels, OPUS_APPLICATION_VOIP, &status); - if (OPUS_OK != opus_encoder_ctl(mEncoderCtx, OPUS_SET_COMPLEXITY(OPUS_CODEC_COMPLEXITY))) - ICELogError(<< "Failed to set Opus encoder complexity"); - //if (OPUS_OK != opus_encoder_ctl(mEncoderCtx, OPUS_SET_FORCE_CHANNELS(AUDIO_CHANNELS))) - // ICELogCritical(<<"Failed to set channel number in Opus encoder"); - mDecoderCtx = opus_decoder_create(48000, mChannels, &status); + int status; + mEncoderCtx = opus_encoder_create(48000, mChannels, OPUS_APPLICATION_VOIP, &status); + if (OPUS_OK != opus_encoder_ctl(mEncoderCtx, OPUS_SET_COMPLEXITY(OPUS_CODEC_COMPLEXITY))) + ICELogError(<< "Failed to set Opus encoder complexity"); + //if (OPUS_OK != opus_encoder_ctl(mEncoderCtx, OPUS_SET_FORCE_CHANNELS(AUDIO_CHANNELS))) + // ICELogCritical(<<"Failed to set channel number in Opus encoder"); + mDecoderCtx = opus_decoder_create(48000, mChannels, &status); } void OpusCodec::applyParams(const Params ¶ms) { - int error; - if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_DTX(params.mUseDtx ? 1 : 0)))) - ICELogError(<< "Failed to (un)set DTX mode in Opus encoder. Error " << opus_strerror(error)); + int error; + if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_DTX(params.mUseDtx ? 1 : 0)))) + ICELogError(<< "Failed to (un)set DTX mode in Opus encoder. Error " << opus_strerror(error)); - if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_INBAND_FEC(params.mUseInbandFec ? 1 : 0)))) - ICELogError(<< "Failed to (un)set FEC mode in Opus encoder. Error " << opus_strerror(error)); + if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_INBAND_FEC(params.mUseInbandFec ? 1 : 0)))) + ICELogError(<< "Failed to (un)set FEC mode in Opus encoder. Error " << opus_strerror(error)); - if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_BITRATE(params.mTargetBitrate ? params.mTargetBitrate : OPUS_AUTO)))) - ICELogError(<< "Failed to (un)set target bandwidth. Error " << opus_strerror(error)); + if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_BITRATE(params.mTargetBitrate ? params.mTargetBitrate : OPUS_AUTO)))) + ICELogError(<< "Failed to (un)set target bandwidth. Error " << opus_strerror(error)); - if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_PACKET_LOSS_PERC(params.mExpectedPacketLoss)))) - ICELogError(<< "Failed to (un)set expected packet loss. Error " << opus_strerror(error)); + if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_PACKET_LOSS_PERC(params.mExpectedPacketLoss)))) + ICELogError(<< "Failed to (un)set expected packet loss. Error " << opus_strerror(error)); - mDecodeResampler.start(channels(), 48000, mSamplerate); + mDecodeResampler.start(channels(), 48000, mSamplerate); } OpusCodec::~OpusCodec() { - if (mDecoderCtx) - { - opus_decoder_destroy(mDecoderCtx); - mDecoderCtx = NULL; - } + if (mDecoderCtx) + { + opus_decoder_destroy(mDecoderCtx); + mDecoderCtx = NULL; + } - if (mEncoderCtx) - { - opus_encoder_destroy(mEncoderCtx); - mEncoderCtx = NULL; - } + if (mEncoderCtx) + { + opus_encoder_destroy(mEncoderCtx); + mEncoderCtx = NULL; + } } const char* OpusCodec::name() { - return OPUS_CODEC_NAME; + return OPUS_CODEC_NAME; } int OpusCodec::pcmLength() { - return (samplerate() / 1000 ) * frameTime() * sizeof(short) * channels(); + return (samplerate() / 1000 ) * frameTime() * sizeof(short) * channels(); } int OpusCodec::channels() { - return mChannels; + return mChannels; } int OpusCodec::rtpLength() { - return 0; // VBR + return 0; // VBR } int OpusCodec::frameTime() { - return mPTime; + return mPTime; } int OpusCodec::samplerate() { - return mSamplerate; + return mSamplerate; } int OpusCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity) { - // Send number of samples for input and number of bytes for output - int written = opus_encode(mEncoderCtx, (const opus_int16*)input, inputBytes / (sizeof(short) * channels()), (unsigned char*)output, outputCapacity / (sizeof(short) * channels())); - if (written < 0) - return 0; - else - return written; + // Send number of samples for input and number of bytes for output + int written = opus_encode(mEncoderCtx, (const opus_int16*)input, inputBytes / (sizeof(short) * channels()), (unsigned char*)output, outputCapacity / (sizeof(short) * channels())); + if (written < 0) + return 0; + else + return written; } int OpusCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity) { - int nr_of_channels = opus_packet_get_nb_channels((const unsigned char*)input); - assert(nr_of_channels == channels()); - - int nr_of_frames = opus_decoder_get_nb_samples(mDecoderCtx, (const unsigned char*)input, inputBytes); - if (nr_of_frames > 0) - { - // Send number of bytes for input and number of samples for output - int capacity = nr_of_frames * sizeof(opus_int16) * channels(); - - // Dangerous ! - opus_int16* buffer = (opus_int16*)alloca(capacity); - int decoded = opus_decode(mDecoderCtx, (const unsigned char*)input, inputBytes, (opus_int16*)buffer, capacity / (sizeof(short) * channels()), 0 /* FEC decoding is for lost packets */); - if (decoded < 0) - return 0; - else + int nr_of_channels = opus_packet_get_nb_channels((const unsigned char*)input); + if (nr_of_channels != channels()) { - // Resample 48000 to requested samplerate - size_t processed = 0; - return mDecodeResampler.processBuffer(buffer, decoded * sizeof(short) * channels(), processed, output, outputCapacity); + // Most probably bad configuration + return 0; } - } - else - return 0; + + int nr_of_frames = opus_decoder_get_nb_samples(mDecoderCtx, (const unsigned char*)input, inputBytes); + if (nr_of_frames > 0) + { + // Send number of bytes for input and number of samples for output + int capacity = nr_of_frames * sizeof(opus_int16) * channels(); + + // Dangerous ! + opus_int16* buffer = (opus_int16*)alloca(capacity); + int decoded = opus_decode(mDecoderCtx, (const unsigned char*)input, inputBytes, (opus_int16*)buffer, capacity / (sizeof(short) * channels()), 0 /* FEC decoding is for lost packets */); + if (decoded < 0) + return 0; + else + { + // Resample 48000 to requested samplerate + size_t processed = 0; + return mDecodeResampler.processBuffer(buffer, decoded * sizeof(short) * channels(), processed, output, outputCapacity); + } + } + else + return 0; } int OpusCodec::plc(int lostFrames, void* output, int outputCapacity) { - int nrOfSamplesInFrame = pcmLength() / (sizeof(short) * channels()); - memset(output, 0, outputCapacity); + int nrOfSamplesInFrame = pcmLength() / (sizeof(short) * channels()); + memset(output, 0, outputCapacity); - int nr_of_decoded_samples = 0; - for (int i=0; igetName().c_str(), "ilbc") == 0) + resip::SdpContents::Session::Medium::CodecContainer::const_iterator codecIter; + int pt = -1, ptime = 0; + for (codecIter = codecs.begin(); codecIter != codecs.end(); codecIter++) { - const resip::Data& p = codecIter->parameters(); - int codecPtime = 0; - if (p.size()) - { - if (strstr(p.c_str(), "mode=") == p.c_str()) - sscanf(p.c_str(), "mode=%d", &codecPtime); - else - if (strstr(p.c_str(), "ptime=")) - sscanf(p.c_str(), "ptime=%d", &codecPtime); - } - - if (codecPtime > ptime) - { - pt = codecIter->payloadType(); - ptime = codecPtime; - } - else - if (!codecPtime) - { - // Suppose it is 30ms ilbc - pt = codecIter->payloadType(); - ptime = 30; - } - } - } + if (stricmp(codecIter->getName().c_str(), "ilbc") == 0) + { + const resip::Data& p = codecIter->parameters(); + int codecPtime = 0; + if (p.size()) + { + if (strstr(p.c_str(), "mode=") == p.c_str()) + sscanf(p.c_str(), "mode=%d", &codecPtime); + else + if (strstr(p.c_str(), "ptime=")) + sscanf(p.c_str(), "ptime=%d", &codecPtime); + } - if (pt != -1) - mPtime = ptime; - return pt; + if (codecPtime > ptime) + { + pt = codecIter->payloadType(); + ptime = codecPtime; + } + else + if (!codecPtime) + { + // Suppose it is 30ms ilbc + pt = codecIter->payloadType(); + ptime = 30; + } + } + } + + if (pt != -1) + mPtime = ptime; + return pt; } #endif @@ -720,139 +724,139 @@ int IlbcCodec::IlbcFactory::processSdp(const resip::SdpContents::Session::Medium #define ISAC_CODEC_NAME "ISAC" IsacCodec::IsacCodec(int samplerate) -:mSamplerate(samplerate) + :mSamplerate(samplerate) { - // This code initializes isac encoder to automatic mode - it will adjust its bitrate automatically. - // Frame time is 60 ms - WebRtcIsacfix_Create(&mEncoderCtx); - WebRtcIsacfix_EncoderInit(mEncoderCtx, 0); - //WebRtcIsacfix_Control(mEncoderCtx, mSamplerate, 30); - //WebRtcIsacfix_SetEncSampRate(mEncoderCtx, mSampleRate == 16000 ? kIsacWideband : kIsacSuperWideband); - WebRtcIsacfix_Create(&mDecoderCtx); - WebRtcIsacfix_DecoderInit(mDecoderCtx); - //WebRtcIsacfix_Control(mDecoderCtx, mSamplerate, 30); - //WebRtcIsacfix_SetDecSampRate(mDecoderCtx, mSampleRate == 16000 ? kIsacWideband : kIsacSuperWideband); + // This code initializes isac encoder to automatic mode - it will adjust its bitrate automatically. + // Frame time is 60 ms + WebRtcIsacfix_Create(&mEncoderCtx); + WebRtcIsacfix_EncoderInit(mEncoderCtx, 0); + //WebRtcIsacfix_Control(mEncoderCtx, mSamplerate, 30); + //WebRtcIsacfix_SetEncSampRate(mEncoderCtx, mSampleRate == 16000 ? kIsacWideband : kIsacSuperWideband); + WebRtcIsacfix_Create(&mDecoderCtx); + WebRtcIsacfix_DecoderInit(mDecoderCtx); + //WebRtcIsacfix_Control(mDecoderCtx, mSamplerate, 30); + //WebRtcIsacfix_SetDecSampRate(mDecoderCtx, mSampleRate == 16000 ? kIsacWideband : kIsacSuperWideband); } IsacCodec::~IsacCodec() { - WebRtcIsacfix_Free(mEncoderCtx); mEncoderCtx = NULL; - WebRtcIsacfix_Free(mDecoderCtx); mDecoderCtx = NULL; + WebRtcIsacfix_Free(mEncoderCtx); mEncoderCtx = NULL; + WebRtcIsacfix_Free(mDecoderCtx); mDecoderCtx = NULL; } const char* IsacCodec::name() { - return "isac"; + return "isac"; } int IsacCodec::frameTime() { - return 60; + return 60; } int IsacCodec::samplerate() { - return mSamplerate; + return mSamplerate; } int IsacCodec::pcmLength() { - return frameTime() * samplerate() / 1000 * sizeof(short); + return frameTime() * samplerate() / 1000 * sizeof(short); } int IsacCodec::rtpLength() { - return 0; + return 0; } int IsacCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity) { - unsigned nrOfSamples = inputBytes / 2; - unsigned timeLength = nrOfSamples / (mSamplerate / 1000); - int encoded = 0; - char* dataOut = (char*)output; - const WebRtc_Word16* dataIn = (const WebRtc_Word16*)input; + unsigned nrOfSamples = inputBytes / 2; + unsigned timeLength = nrOfSamples / (mSamplerate / 1000); + int encoded = 0; + char* dataOut = (char*)output; + const WebRtc_Word16* dataIn = (const WebRtc_Word16*)input; - // Iterate 10 milliseconds chunks - for (unsigned i=0; i 0) - dataOut += encoded; - } - return dataOut - (char*)output; + // Iterate 10 milliseconds chunks + for (unsigned i=0; i 0) + dataOut += encoded; + } + return dataOut - (char*)output; } int IsacCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity) { - WebRtc_Word16 speechType = 0; - unsigned produced = WebRtcIsacfix_Decode(mDecoderCtx, (const WebRtc_UWord16*)input, inputBytes, (WebRtc_Word16*)output, &speechType); - if (produced == (unsigned)-1) - return 0; + WebRtc_Word16 speechType = 0; + unsigned produced = WebRtcIsacfix_Decode(mDecoderCtx, (const WebRtc_UWord16*)input, inputBytes, (WebRtc_Word16*)output, &speechType); + if (produced == (unsigned)-1) + return 0; - return produced * 2; + return produced * 2; } int IsacCodec::plc(int lostFrames, void* output, int outputCapacity) { - // lostFrames are 30-milliseconds frames; but used encoding mode is 60 milliseconds. - // So lostFrames * 2 - lostFrames *=2 ; - if (-1 == WebRtcIsacfix_DecodePlc(mDecoderCtx, (WebRtc_Word16*)output, lostFrames )) - return 0; - - return lostFrames * 30 * (samplerate()/1000 * sizeof(short)); + // lostFrames are 30-milliseconds frames; but used encoding mode is 60 milliseconds. + // So lostFrames * 2 + lostFrames *=2 ; + if (-1 == WebRtcIsacfix_DecodePlc(mDecoderCtx, (WebRtc_Word16*)output, lostFrames )) + return 0; + + return lostFrames * 30 * (samplerate()/1000 * sizeof(short)); } // --- IsacFactory16K --- IsacCodec::IsacFactory16K::IsacFactory16K(int ptype) - :mPType(ptype) + :mPType(ptype) {} const char* IsacCodec::IsacFactory16K::name() { - return ISAC_CODEC_NAME; + return ISAC_CODEC_NAME; } int IsacCodec::IsacFactory16K::samplerate() { - return 16000; + return 16000; } int IsacCodec::IsacFactory16K::payloadType() { - return mPType; + return mPType; } PCodec IsacCodec::IsacFactory16K::create() { - return PCodec(new IsacCodec(16000)); + return PCodec(new IsacCodec(16000)); } // --- IsacFactory32K --- IsacCodec::IsacFactory32K::IsacFactory32K(int ptype) - :mPType(ptype) + :mPType(ptype) {} const char* IsacCodec::IsacFactory32K::name() { - return ISAC_CODEC_NAME; + return ISAC_CODEC_NAME; } int IsacCodec::IsacFactory32K::samplerate() { - return 32000; + return 32000; } int IsacCodec::IsacFactory32K::payloadType() { - return mPType; + return mPType; } PCodec IsacCodec::IsacFactory32K::create() { - return PCodec(new IsacCodec(32000)); + return PCodec(new IsacCodec(32000)); } // --- G711 --- @@ -860,7 +864,7 @@ PCodec IsacCodec::IsacFactory32K::create() #define ALAW_CODEC_NAME "PCMA" G711Codec::G711Codec(int type) -:mType(type) + :mType(type) { } @@ -870,222 +874,222 @@ G711Codec::~G711Codec() const char* G711Codec::name() { - return "g711"; + return "g711"; } int G711Codec::pcmLength() { - return frameTime() * 16; + return frameTime() * 16; } int G711Codec::rtpLength() { - return frameTime() * 8; + return frameTime() * 8; } - + int G711Codec::frameTime() { - return 10; + return 10; } int G711Codec::samplerate() { - return 8000; + return 8000; } int G711Codec::encode(const void* input, int inputBytes, void* output, int outputCapacity) { - int result; - if (mType == ALaw) - result = WebRtcG711_EncodeA(NULL, (WebRtc_Word16*)input, inputBytes/2, (WebRtc_Word16*)output); - else - result = WebRtcG711_EncodeU(NULL, (WebRtc_Word16*)input, inputBytes/2, (WebRtc_Word16*)output); - - if (result == -1) - throw Exception(ERR_WEBRTC, -1); - - return result; + int result; + if (mType == ALaw) + result = WebRtcG711_EncodeA(NULL, (WebRtc_Word16*)input, inputBytes/2, (WebRtc_Word16*)output); + else + result = WebRtcG711_EncodeU(NULL, (WebRtc_Word16*)input, inputBytes/2, (WebRtc_Word16*)output); + + if (result == -1) + throw Exception(ERR_WEBRTC, -1); + + return result; } int G711Codec::decode(const void* input, int inputBytes, void* output, int outputCapacity) { - assert(outputCapacity >= inputBytes * 2); + assert(outputCapacity >= inputBytes * 2); - int result; - WebRtc_Word16 speechType; + int result; + WebRtc_Word16 speechType; - if (mType == ALaw) - result = WebRtcG711_DecodeA(NULL, (WebRtc_Word16*)input, inputBytes, (WebRtc_Word16*)output, &speechType); - else - result = WebRtcG711_DecodeU(NULL, (WebRtc_Word16*)input, inputBytes, (WebRtc_Word16*)output, &speechType); - - if (result == -1) - throw Exception(ERR_WEBRTC, -1); - - return result * 2; + if (mType == ALaw) + result = WebRtcG711_DecodeA(NULL, (WebRtc_Word16*)input, inputBytes, (WebRtc_Word16*)output, &speechType); + else + result = WebRtcG711_DecodeU(NULL, (WebRtc_Word16*)input, inputBytes, (WebRtc_Word16*)output, &speechType); + + if (result == -1) + throw Exception(ERR_WEBRTC, -1); + + return result * 2; } int G711Codec::plc(int lostSamples, void* output, int outputCapacity) { - return 0; + return 0; } // --- AlawFactory --- const char* G711Codec::AlawFactory::name() { - return ALAW_CODEC_NAME; + return ALAW_CODEC_NAME; } int G711Codec::AlawFactory::samplerate() { - return 8000; + return 8000; } int G711Codec::AlawFactory::payloadType() { - return 8; + return 8; } PCodec G711Codec::AlawFactory::create() { - return PCodec(new G711Codec(G711Codec::ALaw)); + return PCodec(new G711Codec(G711Codec::ALaw)); } // --- UlawFactory --- const char* G711Codec::UlawFactory::name() { - return ULAW_CODEC_NAME; + return ULAW_CODEC_NAME; } int G711Codec::UlawFactory::samplerate() { - return 8000; + return 8000; } int G711Codec::UlawFactory::payloadType() { - return 0; + return 0; } PCodec G711Codec::UlawFactory::create() { - return PCodec(new G711Codec(G711Codec::ULaw)); + return PCodec(new G711Codec(G711Codec::ULaw)); } // ---------- GsmCodec ------------- GsmCodec::GsmFactory::GsmFactory(Type codecType, int pt) - :mCodecType(codecType), mPayloadType(pt) + :mCodecType(codecType), mPayloadType(pt) {} const char* GsmCodec::GsmFactory::name() { - return GSM_MIME_NAME; + return GSM_MIME_NAME; } int GsmCodec::GsmFactory::samplerate() { - return 8000; + return 8000; } int GsmCodec::GsmFactory::payloadType() { - return mPayloadType; + return mPayloadType; } PCodec GsmCodec::GsmFactory::create() { - return PCodec(new GsmCodec(mCodecType)); + return PCodec(new GsmCodec(mCodecType)); } GsmCodec::GsmCodec(Type codecType) - :mCodecType(codecType) + :mCodecType(codecType) { - mGSM = gsm_create(); - if (codecType != Type::Bytes_33) - { - int optval = 1; - gsm_option(mGSM, GSM_OPT_WAV49, &optval); - } + mGSM = gsm_create(); + if (codecType != Type::Bytes_33) + { + int optval = 1; + gsm_option(mGSM, GSM_OPT_WAV49, &optval); + } } GsmCodec::~GsmCodec() { - gsm_destroy(mGSM); + gsm_destroy(mGSM); } const char* GsmCodec::name() { - return "GSM-06.10"; + return "GSM-06.10"; } int GsmCodec::rtpLength() { - switch (mCodecType) - { - case Type::Bytes_31: - return GSM_RTPFRAME_SIZE_31; - break; + switch (mCodecType) + { + case Type::Bytes_31: + return GSM_RTPFRAME_SIZE_31; + break; - case Type::Bytes_32: - return GSM_RTPFRAME_SIZE_32; + case Type::Bytes_32: + return GSM_RTPFRAME_SIZE_32; + + case Type::Bytes_33: + return GSM_RTPFRAME_SIZE_33; + + case Type::Bytes_65: + return GSM_RTPFRAME_SIZE_32 + GSM_RTPFRAME_SIZE_33; + + } - case Type::Bytes_33: return GSM_RTPFRAME_SIZE_33; - - case Type::Bytes_65: - return GSM_RTPFRAME_SIZE_32 + GSM_RTPFRAME_SIZE_33; - - } - - return GSM_RTPFRAME_SIZE_33; } int GsmCodec::pcmLength() { - return GSM_AUDIOFRAME_TIME * 16; + return GSM_AUDIOFRAME_TIME * 16; } int GsmCodec::frameTime() { - return GSM_AUDIOFRAME_TIME; + return GSM_AUDIOFRAME_TIME; } int GsmCodec::samplerate() { - return 8000; + return 8000; } int GsmCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity) { - int outputBytes = 0; + int outputBytes = 0; - char* outputBuffer = (char*)output; + char* outputBuffer = (char*)output; - for (int i = 0; i < inputBytes/pcmLength(); i++) - { - gsm_encode(mGSM, (gsm_signal *)input+160*i, (gsm_byte*)outputBuffer); - outputBuffer += rtpLength(); - outputBytes += rtpLength(); - } - return outputBytes; + for (int i = 0; i < inputBytes/pcmLength(); i++) + { + gsm_encode(mGSM, (gsm_signal *)input+160*i, (gsm_byte*)outputBuffer); + outputBuffer += rtpLength(); + outputBytes += rtpLength(); + } + return outputBytes; } int GsmCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity) { - if (inputBytes % rtpLength() != 0) - return 0; + if (inputBytes % rtpLength() != 0) + return 0; - int i=0; - for (i = 0; i < inputBytes/rtpLength(); i++) - gsm_decode(mGSM, (gsm_byte *)input + 33 * i, (gsm_signal *)output + 160 * i); + int i=0; + for (i = 0; i < inputBytes/rtpLength(); i++) + gsm_decode(mGSM, (gsm_byte *)input + 33 * i, (gsm_signal *)output + 160 * i); - return i * 320; + return i * 320; } int GsmCodec::plc(int lostFrames, void* output, int outputCapacity) { - if (outputCapacity < lostFrames * pcmLength()) - return 0; + if (outputCapacity < lostFrames * pcmLength()) + return 0; - // Return silence frames - memset(output, 0, lostFrames * pcmLength()); - return lostFrames * pcmLength(); + // Return silence frames + memset(output, 0, lostFrames * pcmLength()); + return lostFrames * pcmLength(); } @@ -1093,66 +1097,66 @@ int GsmCodec::plc(int lostFrames, void* output, int outputCapacity) G722Codec::G722Codec() { - mEncoder = g722_encode_init(NULL, 64000, 0); - mDecoder = g722_decode_init(NULL, 64000, 0); + mEncoder = g722_encode_init(NULL, 64000, 0); + mDecoder = g722_decode_init(NULL, 64000, 0); } G722Codec::~G722Codec() { - g722_decode_release((g722_decode_state_t*)mDecoder); - g722_encode_release((g722_encode_state_t*)mEncoder); + g722_decode_release((g722_decode_state_t*)mDecoder); + g722_encode_release((g722_encode_state_t*)mEncoder); } const char* G722Codec::name() { - return G722_MIME_NAME; + return G722_MIME_NAME; } int G722Codec::pcmLength() { - return 640; + return 640; } int G722Codec::frameTime() { - return 20; + return 20; } int G722Codec::rtpLength() { - return 160; + return 160; } int G722Codec::samplerate() { - return 8000; + return 8000; } int G722Codec::encode(const void* input, int inputBytes, void* output, int outputCapacity) { - if (outputCapacity < inputBytes / 4) - return 0; // Destination buffer not big enough + if (outputCapacity < inputBytes / 4) + return 0; // Destination buffer not big enough - return g722_encode((g722_encode_state_t *)mEncoder, (unsigned char*)output, ( short*)input, inputBytes / 2); + return g722_encode((g722_encode_state_t *)mEncoder, (unsigned char*)output, ( short*)input, inputBytes / 2); } int G722Codec::decode(const void* input, int inputBytes, void* output, int outputCapacity) { - if (outputCapacity < inputBytes * 4) - return 0; // Destination buffer not big enough + if (outputCapacity < inputBytes * 4) + return 0; // Destination buffer not big enough - return g722_decode((g722_decode_state_t *)mDecoder, ( short*)output, (unsigned char*)input, inputBytes) * 2; + return g722_decode((g722_decode_state_t *)mDecoder, ( short*)output, (unsigned char*)input, inputBytes) * 2; } int G722Codec::plc(int lostFrames, void* output, int outputCapacity) { - if (outputCapacity < lostFrames * pcmLength()) - return 0; + if (outputCapacity < lostFrames * pcmLength()) + return 0; - // Return silence frames - memset(output, 0, lostFrames * pcmLength()); - return lostFrames * pcmLength(); + // Return silence frames + memset(output, 0, lostFrames * pcmLength()); + return lostFrames * pcmLength(); } G722Codec::G722Factory::G722Factory() @@ -1160,23 +1164,23 @@ G722Codec::G722Factory::G722Factory() const char* G722Codec::G722Factory::name() { - return G722_MIME_NAME; + return G722_MIME_NAME; } int G722Codec::G722Factory::samplerate() { - // Although G722 uses 16000 as rate for timestamping RTP frames - in fact it is 8KHz codec. So return 8KHz here. - return 8000; + // Although G722 uses 16000 as rate for timestamping RTP frames - in fact it is 8KHz codec. So return 8KHz here. + return 8000; } int G722Codec::G722Factory::payloadType() { - return G722_PAYLOAD_TYPE; + return G722_PAYLOAD_TYPE; } PCodec G722Codec::G722Factory::create() { - return PCodec(new G722Codec()); + return PCodec(new G722Codec()); } #ifndef TARGET_ANDROID @@ -1189,197 +1193,197 @@ PCodec G722Codec::G722Factory::create() static bool repackHalfRate(BitReader& br, uint16_t frame[22], bool& lastItem) { - // Check if it is last chunk - lastItem = br.readBit() == 0; + // Check if it is last chunk + lastItem = br.readBit() == 0; - // Read frame type - uint8_t frametype = (uint8_t)br.readBits(3); // Read frame type + // Read frame type + uint8_t frametype = (uint8_t)br.readBits(3); // Read frame type - // Read reserved bits - br.readBits(4); + // Read reserved bits + br.readBits(4); - switch (frametype) - { - case GSMHR_GOODSPEECH: - case GSMHR_GOODSID: - frame[0] = br.readBits(5); // R0 - frame[1] = br.readBits(11); // LPC1 - frame[2] = br.readBits(9); // LPC2 - frame[3] = br.readBits(8); // LPC3 - frame[4] = br.readBits(1); // INT_LPC - frame[5] = br.readBits(2); // MODE - // Parse speech frame - if (frame[5]) + switch (frametype) { - // Voiced mode - frame[6] = br.readBits(8); // LAG_1 - frame[7] = br.readBits(9); // CODE_1 - frame[8] = br.readBits(5); // GSP0_1 + case GSMHR_GOODSPEECH: + case GSMHR_GOODSID: + frame[0] = br.readBits(5); // R0 + frame[1] = br.readBits(11); // LPC1 + frame[2] = br.readBits(9); // LPC2 + frame[3] = br.readBits(8); // LPC3 + frame[4] = br.readBits(1); // INT_LPC + frame[5] = br.readBits(2); // MODE + // Parse speech frame + if (frame[5]) + { + // Voiced mode + frame[6] = br.readBits(8); // LAG_1 + frame[7] = br.readBits(9); // CODE_1 + frame[8] = br.readBits(5); // GSP0_1 - frame[9] = br.readBits(4); // LAG_2 - frame[10] = br.readBits(9); // CODE_2 - frame[11] = br.readBits(5); // GSP0_2 + frame[9] = br.readBits(4); // LAG_2 + frame[10] = br.readBits(9); // CODE_2 + frame[11] = br.readBits(5); // GSP0_2 - frame[12] = br.readBits(4); // LAG_3 - frame[13] = br.readBits(9); // CODE_3 - frame[14] = br.readBits(5); // GSP0_3 + frame[12] = br.readBits(4); // LAG_3 + frame[13] = br.readBits(9); // CODE_3 + frame[14] = br.readBits(5); // GSP0_3 - frame[15] = br.readBits(4); // LAG_4 - frame[16] = br.readBits(9); // CODE_4 - frame[17] = br.readBits(5); // GSP0_4 - } - else - { - // Unvoiced mode - frame[6] = br.readBits(7); // CODE1_1 - frame[7] = br.readBits(7); // CODE2_1 - frame[8] = br.readBits(5); // GSP0_1 + frame[15] = br.readBits(4); // LAG_4 + frame[16] = br.readBits(9); // CODE_4 + frame[17] = br.readBits(5); // GSP0_4 + } + else + { + // Unvoiced mode + frame[6] = br.readBits(7); // CODE1_1 + frame[7] = br.readBits(7); // CODE2_1 + frame[8] = br.readBits(5); // GSP0_1 - frame[9] = br.readBits(7); // CODE1_2 - frame[10] = br.readBits(7); // CODE2_2 - frame[11] = br.readBits(5); // GSP0_2 + frame[9] = br.readBits(7); // CODE1_2 + frame[10] = br.readBits(7); // CODE2_2 + frame[11] = br.readBits(5); // GSP0_2 - frame[12] = br.readBits(7); // CODE1_3 - frame[13] = br.readBits(7); // CODE2_3 - frame[14] = br.readBits(5); // GSP0_3; + frame[12] = br.readBits(7); // CODE1_3 + frame[13] = br.readBits(7); // CODE2_3 + frame[14] = br.readBits(5); // GSP0_3; - frame[15] = br.readBits(7); // CODE1_4; - frame[16] = br.readBits(7); // CODE2_4; - frame[17] = br.readBits(5); // GSP0_4; + frame[15] = br.readBits(7); // CODE1_4; + frame[16] = br.readBits(7); // CODE2_4; + frame[17] = br.readBits(5); // GSP0_4; + } + + frame[18] = 0; frame[19] = 0; + frame[20] = 0; frame[21] = 0; + break; + + case GSMHR_NODATA: + break; + + default: + return false; } - frame[18] = 0; frame[19] = 0; - frame[20] = 0; frame[21] = 0; - break; - - case GSMHR_NODATA: - break; - - default: - return false; - } - - return true; + return true; } GsmHrCodec::GsmHrCodec() - :mDecoder(nullptr) + :mDecoder(nullptr) { - mDecoder = new GsmHr::Codec(); + mDecoder = new GsmHr::Codec(); } GsmHrCodec::~GsmHrCodec() { - delete reinterpret_cast(mDecoder); - mDecoder = nullptr; + delete reinterpret_cast(mDecoder); + mDecoder = nullptr; } const char* GsmHrCodec::name() { - return "GSM-HR-08"; + return "GSM-HR-08"; } int GsmHrCodec::pcmLength() { - return frameTime() * 8 * 2; + return frameTime() * 8 * 2; } int GsmHrCodec::rtpLength() { - return 0; + return 0; } int GsmHrCodec::frameTime() { - return 20; + return 20; } int GsmHrCodec::samplerate() { - return 8000; + return 8000; } int GsmHrCodec::encode(const void* input, int inputBytes, void* output, int outputCapacity) { - return 0; + return 0; } static const int params_unvoiced[] = { - 5, /* R0 */ - 11, /* k1Tok3 */ - 9, /* k4Tok6 */ - 8, /* k7Tok10 */ - 1, /* softInterpolation */ - 2, /* voicingDecision */ - 7, /* code1_1 */ - 7, /* code2_1 */ - 5, /* gsp0_1 */ - 7, /* code1_2 */ - 7, /* code2_2 */ - 5, /* gsp0_2 */ - 7, /* code1_3 */ - 7, /* code2_3 */ - 5, /* gsp0_3 */ - 7, /* code1_4 */ - 7, /* code2_4 */ - 5, /* gsp0_4 */ + 5, /* R0 */ + 11, /* k1Tok3 */ + 9, /* k4Tok6 */ + 8, /* k7Tok10 */ + 1, /* softInterpolation */ + 2, /* voicingDecision */ + 7, /* code1_1 */ + 7, /* code2_1 */ + 5, /* gsp0_1 */ + 7, /* code1_2 */ + 7, /* code2_2 */ + 5, /* gsp0_2 */ + 7, /* code1_3 */ + 7, /* code2_3 */ + 5, /* gsp0_3 */ + 7, /* code1_4 */ + 7, /* code2_4 */ + 5, /* gsp0_4 */ }; static const int params_voiced[] = { - 5, /* R0 */ - 11, /* k1Tok3 */ - 9, /* k4Tok6 */ - 8, /* k7Tok10 */ - 1, /* softInterpolation */ - 2, /* voicingDecision */ - 8, /* frameLag */ - 9, /* code_1 */ - 5, /* gsp0_1 */ - 4, /* deltaLag_2 */ - 9, /* code_2 */ - 5, /* gsp0_2 */ - 4, /* deltaLag_3 */ - 9, /* code_3 */ - 5, /* gsp0_3 */ - 4, /* deltaLag_4 */ - 9, /* code_4 */ - 5, /* gsp0_4 */ + 5, /* R0 */ + 11, /* k1Tok3 */ + 9, /* k4Tok6 */ + 8, /* k7Tok10 */ + 1, /* softInterpolation */ + 2, /* voicingDecision */ + 8, /* frameLag */ + 9, /* code_1 */ + 5, /* gsp0_1 */ + 4, /* deltaLag_2 */ + 9, /* code_2 */ + 5, /* gsp0_2 */ + 4, /* deltaLag_3 */ + 9, /* code_3 */ + 5, /* gsp0_3 */ + 4, /* deltaLag_4 */ + 9, /* code_4 */ + 5, /* gsp0_4 */ }; static int msb_get_bit(const uint8_t *buf, int bn) { - int pos_byte = bn >> 3; - int pos_bit = 7 - (bn & 7); + int pos_byte = bn >> 3; + int pos_bit = 7 - (bn & 7); - return (buf[pos_byte] >> pos_bit) & 1; + return (buf[pos_byte] >> pos_bit) & 1; } static int hr_ref_from_canon(uint16_t *hr_ref, const uint8_t *canon) { - int i, j, voiced; - const int *params; + int i, j, voiced; + const int *params; - voiced = (msb_get_bit(canon, 34) << 1) | msb_get_bit(canon, 35); - params = voiced ? ¶ms_voiced[0] : ¶ms_unvoiced[0]; + voiced = (msb_get_bit(canon, 34) << 1) | msb_get_bit(canon, 35); + params = voiced ? ¶ms_voiced[0] : ¶ms_unvoiced[0]; - for (i=0,j=0; i<18; i++) - { - uint16_t w; - int l, k; + for (i=0,j=0; i<18; i++) + { + uint16_t w; + int l, k; - l = params[i]; + l = params[i]; - w = 0; - for (k=0; k(mDecoder)->speechDecoder((int16_t*)hr_ref, (int16_t*)output); - return 320; + reinterpret_cast(mDecoder)->speechDecoder((int16_t*)hr_ref, (int16_t*)output); + return 320; } int GsmHrCodec::plc(int lostFrames, void* output, int outputCapacity) { - return 0; + return 0; } GsmHrCodec::GsmHrFactory::GsmHrFactory(int ptype) - :mPtype(ptype) + :mPtype(ptype) {} const char* GsmHrCodec::GsmHrFactory::name() { - return "GSM-HR-08"; + return "GSM-HR-08"; } int GsmHrCodec::GsmHrFactory::samplerate() { - return 8000; + return 8000; } int GsmHrCodec::GsmHrFactory::payloadType() { - return mPtype; + return mPtype; } PCodec GsmHrCodec::GsmHrFactory::create() { - return PCodec(new GsmHrCodec()); + return PCodec(new GsmHrCodec()); } #endif diff --git a/src/engine/media/MT_CodecList.cpp b/src/engine/media/MT_CodecList.cpp index 03614914..44279c02 100644 --- a/src/engine/media/MT_CodecList.cpp +++ b/src/engine/media/MT_CodecList.cpp @@ -116,7 +116,7 @@ CodecList::Settings::OpusSpec CodecList::Settings::OpusSpec::parse(const std::st { OpusSpec result; - auto parts = strx::split(spec, "-"); + auto parts = strx::split(spec, "-/"); if (parts.size() == 3) { result.mPayloadType = strx::toInt(strx::trim(parts.front()).c_str(), -1);