From 1bd22d30a806f0ccaf61e05fab2983071c3c9ba1 Mon Sep 17 00:00:00 2001 From: Alexandre Savard <alexandre.savard@savoirfairelinux.com> Date: Thu, 3 May 2012 15:35:58 -0400 Subject: [PATCH] #10230: Use a different samplerate converter for rtp encoding and decoding --- .../audiortp/audio_rtp_record_handler.cpp | 60 ++++++++++++++----- .../audio/audiortp/audio_rtp_record_handler.h | 6 +- daemon/src/audio/mainbuffer.cpp | 2 +- daemon/src/audio/pulseaudio/pulselayer.cpp | 24 +++++++- 4 files changed, 72 insertions(+), 20 deletions(-) diff --git a/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp b/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp index d300a67665..0a36cc96bd 100644 --- a/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp +++ b/daemon/src/audio/audiortp/audio_rtp_record_handler.cpp @@ -36,10 +36,17 @@ #include "audio/audiolayer.h" #include "manager.h" +#include <fstream> + namespace sfl { static const SFLDataFormat INIT_FADE_IN_FACTOR = 32000; +#ifdef RECTODISK +std::ofstream rtpResampled ("testRtpOutputResampled.raw", std::ifstream::binary); +std::ofstream rtpNotResampled("testRtpOutput.raw", std::ifstream::binary); +#endif + AudioRtpRecord::AudioRtpRecord() : audioCodec_(0) , audioCodecMutex_() @@ -48,13 +55,15 @@ AudioRtpRecord::AudioRtpRecord() : , decData_() // std::tr1::arrays will be 0-initialized , resampledData_() , encodedData_() - , converter_(0) + , converterEncode_(0) + , converterDecode_(0) , codecSampleRate_(0) , codecFrameSize_(0) , converterSamplingRate_(0) , dtmfQueue_() , fadeFactor_(INIT_FADE_IN_FACTOR) - , noiseSuppress_(0) + , noiseSuppressEncode_(0) + , noiseSuppressDecode_(0) , audioProcessMutex_() , callId_("") , dtmfPayloadType_(101) // same as Asterisk @@ -62,9 +71,16 @@ AudioRtpRecord::AudioRtpRecord() : AudioRtpRecord::~AudioRtpRecord() { - delete converter_; +#ifdef RECTODISK + rtpResampled.close(); + rtpNotResampled.close(); +#endif + + delete converterEncode_; + delete converterDecode_; delete audioCodec_; - delete noiseSuppress_; + delete noiseSuppressEncode_; + delete noiseSuppressDecode_; } @@ -98,15 +114,19 @@ void AudioRtpRecordHandler::initBuffers() // initialize SampleRate converter using AudioLayer's sampling rate // (internal buffers initialized with maximal sampling rate and frame size) - delete audioRtpRecord_.converter_; - audioRtpRecord_.converter_ = new SamplerateConverter(getCodecSampleRate()); + delete audioRtpRecord_.converterEncode_; + audioRtpRecord_.converterEncode_ = new SamplerateConverter(getCodecSampleRate()); + delete audioRtpRecord_.converterDecode_; + audioRtpRecord_.converterDecode_ = new SamplerateConverter(getCodecSampleRate()); } void AudioRtpRecordHandler::initNoiseSuppress() { ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_); - delete audioRtpRecord_.noiseSuppress_; - audioRtpRecord_.noiseSuppress_ = new NoiseSuppress(getCodecFrameSize(), getCodecSampleRate()); + delete audioRtpRecord_.noiseSuppressEncode_; + audioRtpRecord_.noiseSuppressEncode_ = new NoiseSuppress(getCodecFrameSize(), getCodecSampleRate()); + delete audioRtpRecord_.noiseSuppressDecode_; + audioRtpRecord_.noiseSuppressDecode_ = new NoiseSuppress(getCodecFrameSize(), getCodecSampleRate()); } void AudioRtpRecordHandler::putDtmfEvent(int digit) @@ -131,6 +151,10 @@ int AudioRtpRecordHandler::processDataEncode() SFLDataFormat *micData = audioRtpRecord_.decData_.data(); int bytes = Manager::instance().getMainBuffer()->getData(micData, bytesToGet, id_); +#ifdef RECTODISK + rtpNotResampled.write((const char *)micData, bytes); +#endif + if (bytes != bytesToGet) { ERROR("Asked for %d bytes from mainbuffer, got %d", bytesToGet, bytes); return 0; @@ -146,19 +170,25 @@ int AudioRtpRecordHandler::processDataEncode() SFLDataFormat *out = micData; if (codecSampleRate != mainBufferSampleRate) { - assert(audioRtpRecord_.converter_); - audioRtpRecord_.converter_->resample(micData, + assert(audioRtpRecord_.converterEncode_); + + audioRtpRecord_.converterEncode_->resample(micData, audioRtpRecord_.resampledData_.data(), - audioRtpRecord_.resampledData_.size(), codecSampleRate, - mainBufferSampleRate, + audioRtpRecord_.resampledData_.size(), + mainBufferSampleRate, codecSampleRate, samplesToGet); + +#ifdef RECTODISK + rtpResampled.write((const char *)audioRtpRecord_.resampledData_.data(), samplesToGet*sizeof(SFLDataFormat)/2 ); +#endif + out = audioRtpRecord_.resampledData_.data(); } if (Manager::instance().audioPreference.getNoiseReduce()) { ost::MutexLock lock(audioRtpRecord_.audioProcessMutex_); - assert(audioRtpRecord_.noiseSuppress_); - audioRtpRecord_.noiseSuppress_->process(micData, getCodecFrameSize()); + assert(audioRtpRecord_.noiseSuppressEncode_); + audioRtpRecord_.noiseSuppressEncode_->process(micData, getCodecFrameSize()); } { @@ -198,7 +228,7 @@ void AudioRtpRecordHandler::processDataDecode(unsigned char *spkrData, size_t si out = audioRtpRecord_.resampledData_.data(); // Do sample rate conversion outSamples = ((float) inSamples * ((float) mainBufferSampleRate / (float) codecSampleRate)); - audioRtpRecord_.converter_->resample(spkrDataDecoded, out, + audioRtpRecord_.converterDecode_->resample(spkrDataDecoded, out, audioRtpRecord_.resampledData_.size(), codecSampleRate, mainBufferSampleRate, inSamples); } diff --git a/daemon/src/audio/audiortp/audio_rtp_record_handler.h b/daemon/src/audio/audiortp/audio_rtp_record_handler.h index c3c76692f8..3f3a7ec649 100644 --- a/daemon/src/audio/audiortp/audio_rtp_record_handler.h +++ b/daemon/src/audio/audiortp/audio_rtp_record_handler.h @@ -85,13 +85,15 @@ class AudioRtpRecord { // FIXME: resampledData should be resized as needed std::tr1::array<SFLDataFormat, DEC_BUFFER_SIZE * 4> resampledData_; std::tr1::array<unsigned char, DEC_BUFFER_SIZE> encodedData_; - SamplerateConverter *converter_; + SamplerateConverter *converterEncode_; + SamplerateConverter *converterDecode_; int codecSampleRate_; int codecFrameSize_; int converterSamplingRate_; std::list<int> dtmfQueue_; SFLDataFormat fadeFactor_; - NoiseSuppress *noiseSuppress_; + NoiseSuppress *noiseSuppressEncode_; + NoiseSuppress *noiseSuppressDecode_; ost::Mutex audioProcessMutex_; std::string callId_; unsigned int dtmfPayloadType_; diff --git a/daemon/src/audio/mainbuffer.cpp b/daemon/src/audio/mainbuffer.cpp index 6925bf0f43..f77a00954e 100644 --- a/daemon/src/audio/mainbuffer.cpp +++ b/daemon/src/audio/mainbuffer.cpp @@ -37,7 +37,7 @@ const char * const MainBuffer::DEFAULT_ID = "audiolayer_id"; -MainBuffer::MainBuffer() : ringBufferMap_(), callIDMap_(), mutex_(), internalSamplingRate_(8000) +MainBuffer::MainBuffer() : ringBufferMap_(), callIDMap_(), mutex_(), internalSamplingRate_(16000) {} MainBuffer::~MainBuffer() diff --git a/daemon/src/audio/pulseaudio/pulselayer.cpp b/daemon/src/audio/pulseaudio/pulselayer.cpp index 1d61c4b99a..fcf3884ebd 100644 --- a/daemon/src/audio/pulseaudio/pulselayer.cpp +++ b/daemon/src/audio/pulseaudio/pulselayer.cpp @@ -38,6 +38,9 @@ #include "logger.h" #include "manager.h" +#include <stdlib.h> +#include <fstream> + namespace { void playback_callback(pa_stream * /*s*/, size_t /*bytes*/, void* userdata) @@ -62,6 +65,11 @@ void stream_moved_callback(pa_stream *s, void *userdata UNUSED) } // end anonymous namespace +#ifdef RECTODISK +std::ofstream outfileResampled ("testMicOuputResampled.raw", std::ifstream::binary); +std::ofstream outfile("testMicOuput.raw", std::ifstream::binary); +#endif + PulseLayer::PulseLayer() : playback_(0) , record_(0) @@ -106,6 +114,11 @@ PulseLayer::PulseLayer() PulseLayer::~PulseLayer() { +#ifdef RECTODISK + outfile.close(); + outfileResampled.close(); +#endif + disconnectAudioStream(); if (mainloop_) @@ -416,12 +429,19 @@ void PulseLayer::readFromMic() mic_buffer_ = new SFLDataFormat[samples]; } - if (resample) +#ifdef RECTODISK + outfile.write((const char *)data, bytes); +#endif + if (resample) { converter_.resample((SFLDataFormat*)data, mic_buffer_, samples, mainBufferSampleRate, sampleRate_, samples); + } - dcblocker_.process(mic_buffer_, resample ? mic_buffer_ : (SFLDataFormat*)data, samples); + dcblocker_.process(mic_buffer_, (SFLDataFormat*)data, samples); applyGain(mic_buffer_, bytes / sizeof(SFLDataFormat), getCaptureGain()); Manager::instance().getMainBuffer()->putData(mic_buffer_, bytes, MainBuffer::DEFAULT_ID); +#ifdef RECTODISK + outfileResampled.write((const char *)mic_buffer_, bytes); +#endif if (pa_stream_drop(record_->pulseStream()) < 0) ERROR("Capture stream drop failed: %s" , pa_strerror(pa_context_errno(context_))); -- GitLab