From 6099b4fc04c2168bf23b98ad37d99c55fe1112ac Mon Sep 17 00:00:00 2001 From: Dmytro Bogovych Date: Fri, 2 Nov 2018 16:39:38 +0200 Subject: [PATCH] - update (C) --- src/engine/audio/Audio_Resampler.cpp | 245 ++++++++++++++------------- src/engine/audio/Audio_Resampler.h | 64 +++---- 2 files changed, 155 insertions(+), 154 deletions(-) diff --git a/src/engine/audio/Audio_Resampler.cpp b/src/engine/audio/Audio_Resampler.cpp index cb923169..6fc6e5cb 100644 --- a/src/engine/audio/Audio_Resampler.cpp +++ b/src/engine/audio/Audio_Resampler.cpp @@ -1,4 +1,4 @@ -/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) +/* Copyright(C) 2007-2018 VoIP objects (voipobjects.com) * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -16,94 +16,95 @@ using namespace Audio; #define IS_FRACTIONAL_RATE(X) (((X) % 8000) != 0) SpeexResampler::SpeexResampler() -:mContext(NULL), mErrorCode(0), mSourceRate(0), mDestRate(0), mLastSample(0) + :mContext(NULL), mErrorCode(0), mSourceRate(0), mDestRate(0), mLastSample(0) { } void SpeexResampler::start(int channels, int sourceRate, int destRate) { - if (mSourceRate == sourceRate && mDestRate == destRate && mContext) - return; + if (mSourceRate == sourceRate && mDestRate == destRate && mContext) + return; - if (mContext) - stop(); + if (mContext) + stop(); - mSourceRate = sourceRate; - mDestRate = destRate; - mChannels = channels; + mSourceRate = sourceRate; + mDestRate = destRate; + mChannels = channels; - if (sourceRate != destRate) - { - // Defer context creation until first request - //mContext = speex_resampler_init(channels, sourceRate, destRate, AUDIO_RESAMPLER_QUALITY, &mErrorCode); - //assert(mContext != NULL); - } + if (sourceRate != destRate) + { + // Defer context creation until first request + //mContext = speex_resampler_init(channels, sourceRate, destRate, AUDIO_RESAMPLER_QUALITY, &mErrorCode); + //assert(mContext != NULL); + } } void SpeexResampler::stop() { - if (mContext) - { - speex_resampler_destroy((SpeexResamplerState*)mContext); - mContext = NULL; - } + if (mContext) + { + speex_resampler_destroy((SpeexResamplerState*)mContext); + mContext = NULL; + } } SpeexResampler::~SpeexResampler() { - stop(); + stop(); } int SpeexResampler::processBuffer(const void* src, int sourceLength, int& sourceProcessed, void* dest, int destCapacity) { - assert(mSourceRate != 0 && mDestRate != 0); + assert(mSourceRate != 0 && mDestRate != 0); - if (mDestRate == mSourceRate) - { - assert(destCapacity >= sourceLength); - memcpy(dest, src, (size_t)sourceLength); - sourceProcessed = sourceLength; - return sourceLength; - } + if (mDestRate == mSourceRate) + { + assert(destCapacity >= sourceLength); + memcpy(dest, src, (size_t)sourceLength); + sourceProcessed = sourceLength; + return sourceLength; + } - if (!mContext) - { - mContext = speex_resampler_init(mChannels, mSourceRate, mDestRate, AUDIO_RESAMPLER_QUALITY, &mErrorCode); if (!mContext) - return 0; - } + { + mContext = speex_resampler_init(mChannels, mSourceRate, mDestRate, AUDIO_RESAMPLER_QUALITY, &mErrorCode); + if (!mContext) + return 0; + } - // Check if there is zero samples passed - if (sourceLength / (sizeof(short) * mChannels) == 0) - { - // Consume all data - sourceProcessed = sourceLength; + // Check if there is zero samples passed + if (sourceLength / (sizeof(short) * mChannels) == 0) + { + // Consume all data + sourceProcessed = sourceLength; - // But no output - return 0; - } - unsigned outLen = getDestLength(sourceLength); - if (outLen > (unsigned)destCapacity) - return 0; // Skip resampling if not enough space + // But no output + return 0; + } - assert((unsigned)destCapacity >= outLen); + unsigned outLen = getDestLength(sourceLength); + if (outLen > (unsigned)destCapacity) + return 0; // Skip resampling if not enough space - // Calculate number of samples - input length is in bytes - unsigned inLen = sourceLength / (sizeof(short) * mChannels); - outLen /= sizeof(short) * mChannels; - assert(mContext != NULL); - int speexCode = speex_resampler_process_interleaved_int((SpeexResamplerState *)mContext, (spx_int16_t*)src, &inLen, - (spx_int16_t*)dest, &outLen); - assert(speexCode == RESAMPLER_ERR_SUCCESS); + assert((unsigned)destCapacity >= outLen); - // Return results in bytes - sourceProcessed = inLen * sizeof(short) * mChannels; - return outLen * sizeof(short) * mChannels; + // Calculate number of samples - input length is in bytes + unsigned inLen = sourceLength / (sizeof(short) * mChannels); + outLen /= sizeof(short) * mChannels; + assert(mContext != NULL); + int speexCode = speex_resampler_process_interleaved_int((SpeexResamplerState *)mContext, (spx_int16_t*)src, &inLen, + (spx_int16_t*)dest, &outLen); + assert(speexCode == RESAMPLER_ERR_SUCCESS); + + // Return results in bytes + sourceProcessed = inLen * sizeof(short) * mChannels; + return outLen * sizeof(short) * mChannels; } int SpeexResampler::sourceRate() { - return mSourceRate; + return mSourceRate; } int SpeexResampler::destRate() @@ -113,18 +114,18 @@ int SpeexResampler::destRate() int SpeexResampler::getDestLength(int sourceLen) { - return int(sourceLen * (float(mDestRate) / mSourceRate) + 0.5) / 2 * 2; + return int(sourceLen * (float(mDestRate) / mSourceRate) + 0.5) / 2 * 2; } int SpeexResampler::getSourceLength(int destLen) { - return int(destLen * (float(mSourceRate) / mDestRate) + 0.5) / 2 * 2; + return int(destLen * (float(mSourceRate) / mDestRate) + 0.5) / 2 * 2; } // Returns instance + speex resampler size in bytes int SpeexResampler::getSize() const { - return sizeof(*this) + 200; // 200 is approximate size of speex resample structure + return sizeof(*this) + 200; // 200 is approximate size of speex resample structure } // -------------------------- ChannelConverter -------------------- @@ -142,62 +143,62 @@ int ChannelConverter::stereoToMono(const void *source, int sourceLength, void *d int ChannelConverter::monoToStereo(const void *source, int sourceLength, void *dest, int destLength) { - assert(destLength == sourceLength * 2); - const short* input = (const short*)source; - short* output = (short*)dest; - // Convert starting from the end of buffer to allow inplace conversion - for (int sampleIndex = sourceLength/2 - 1; sampleIndex >= 0; sampleIndex--) - { - output[2*sampleIndex] = output[2*sampleIndex+1] = input[sampleIndex]; - } - return sourceLength * 2; + assert(destLength == sourceLength * 2); + const short* input = (const short*)source; + short* output = (short*)dest; + // Convert starting from the end of buffer to allow inplace conversion + for (int sampleIndex = sourceLength/2 - 1; sampleIndex >= 0; sampleIndex--) + { + output[2*sampleIndex] = output[2*sampleIndex+1] = input[sampleIndex]; + } + return sourceLength * 2; } #if defined(USE_WEBRTC_RESAMPLER) Resampler48kTo16k::Resampler48kTo16k() { - WebRtcSpl_ResetResample48khzTo16khz(&mContext); + WebRtcSpl_ResetResample48khzTo16khz(&mContext); } Resampler48kTo16k::~Resampler48kTo16k() { - WebRtcSpl_ResetResample48khzTo16khz(&mContext); + WebRtcSpl_ResetResample48khzTo16khz(&mContext); } int Resampler48kTo16k::process(const void *source, int sourceLen, void *dest, int destLen) { - const short* input = (const short*)source; int inputLen = sourceLen / 2; - short* output = (short*)dest; //int outputCapacity = destLen / 2; - assert(inputLen % 480 == 0); - int frames = inputLen / 480; - for (int i=0; i= sourceLength); - memcpy(destBuffer, sourceBuffer, (size_t)sourceLength); - sourceProcessed = sourceLength; - result = sourceLength; - } - else - { - PResampler r = findResampler(sourceRate, destRate); - result = r->processBuffer(sourceBuffer, sourceLength, sourceProcessed, destBuffer, destCapacity); - } - return result; + assert(destBuffer && sourceBuffer); + int result; + if (sourceRate == destRate) + { + assert(destCapacity >= sourceLength); + memcpy(destBuffer, sourceBuffer, (size_t)sourceLength); + sourceProcessed = sourceLength; + result = sourceLength; + } + else + { + PResampler r = findResampler(sourceRate, destRate); + result = r->processBuffer(sourceBuffer, sourceLength, sourceProcessed, destBuffer, destCapacity); + } + return result; } void UniversalResampler::preload() @@ -239,33 +240,33 @@ void UniversalResampler::preload() int UniversalResampler::getDestLength(int sourceRate, int destRate, int sourceLength) { - if (sourceRate == destRate) - return sourceLength; - else - return findResampler(sourceRate, destRate)->getDestLength(sourceLength); + if (sourceRate == destRate) + return sourceLength; + else + return findResampler(sourceRate, destRate)->getDestLength(sourceLength); } int UniversalResampler::getSourceLength(int sourceRate, int destRate, int destLength) { - if (sourceRate == destRate) - return destLength; - else - return findResampler(sourceRate, destRate)->getSourceLength(destLength); + if (sourceRate == destRate) + return destLength; + else + return findResampler(sourceRate, destRate)->getSourceLength(destLength); } PResampler UniversalResampler::findResampler(int sourceRate, int destRate) { - assert(sourceRate != destRate); - ResamplerMap::iterator resamplerIter = mResamplerMap.find(RatePair(sourceRate, destRate)); - PResampler r; - if (resamplerIter == mResamplerMap.end()) - { - r = PResampler(new Resampler()); - r->start(AUDIO_CHANNELS, sourceRate, destRate); - mResamplerMap[RatePair(sourceRate, destRate)] = r; - } - else - r = resamplerIter->second; - return r; + assert(sourceRate != destRate); + ResamplerMap::iterator resamplerIter = mResamplerMap.find(RatePair(sourceRate, destRate)); + PResampler r; + if (resamplerIter == mResamplerMap.end()) + { + r = PResampler(new Resampler()); + r->start(AUDIO_CHANNELS, sourceRate, destRate); + mResamplerMap[RatePair(sourceRate, destRate)] = r; + } + else + r = resamplerIter->second; + return r; } diff --git a/src/engine/audio/Audio_Resampler.h b/src/engine/audio/Audio_Resampler.h index ce4b3dfa..a6ac6669 100644 --- a/src/engine/audio/Audio_Resampler.h +++ b/src/engine/audio/Audio_Resampler.h @@ -1,4 +1,4 @@ -/* Copyright(C) 2007-2014 VoIP objects (voipobjects.com) +/* Copyright(C) 2007-2018 VoIP objects (voipobjects.com) * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -16,9 +16,9 @@ namespace Audio { - class SpeexResampler - { - public: +class SpeexResampler +{ +public: SpeexResampler(); ~SpeexResampler(); @@ -33,29 +33,29 @@ namespace Audio // Returns instance + speex encoder size in bytes int getSize() const; - protected: +protected: void* mContext; int mErrorCode; int mSourceRate, - mDestRate, - mChannels; - short mLastSample; - }; + mDestRate, + mChannels; + short mLastSample; +}; - typedef SpeexResampler Resampler; - typedef std::shared_ptr PResampler; +typedef SpeexResampler Resampler; +typedef std::shared_ptr PResampler; - class ChannelConverter - { - public: +class ChannelConverter +{ +public: static int stereoToMono(const void* source, int sourceLength, void* dest, int destLength); static int monoToStereo(const void* source, int sourceLength, void* dest, int destLength); - }; +}; - // Operates with AUDIO_CHANNELS number of channels - class UniversalResampler - { - public: +// Operates with AUDIO_CHANNELS number of channels +class UniversalResampler +{ +public: UniversalResampler(); ~UniversalResampler(); @@ -63,39 +63,39 @@ namespace Audio int getDestLength(int sourceRate, int destRate, int sourceLength); int getSourceLength(int sourceRate, int destRate, int destLength); - protected: +protected: typedef std::pair RatePair; typedef std::map ResamplerMap; ResamplerMap mResamplerMap; PResampler findResampler(int sourceRate, int destRate); void preload(); - }; +}; #ifdef USE_WEBRTC_RESAMPLER - // n*10 milliseconds buffers required! - class Resampler48kTo16k - { - public: +// n*10 milliseconds buffers required! +class Resampler48kTo16k +{ +public: Resampler48kTo16k(); ~Resampler48kTo16k(); int process(const void* source, int sourceLen, void* dest, int destLen); - protected: +protected: WebRtc_Word32 mTemp[496]; WebRtcSpl_State48khzTo16khz mContext; - }; +}; - class Resampler16kto48k - { - public: +class Resampler16kto48k +{ +public: Resampler16kto48k(); ~Resampler16kto48k(); int process(const void* source, int sourceLen, void* dest, int destLen); - protected: +protected: WebRtc_Word32 mTemp[336]; WebRtcSpl_State16khzTo48khz mContext; - }; +}; #endif }