diff --git a/common/resampler.cpp b/common/resampler.cpp index 5dcf2861..b5ef02ba 100644 --- a/common/resampler.cpp +++ b/common/resampler.cpp @@ -57,6 +57,16 @@ Resampler::Resampler(const SampleFormat& in_format, const SampleFormat& out_form } +bool Resampler::resamplingNeeded() const +{ +#ifdef HAS_SOXR + return soxr_ != nullptr; +#else + return false; +#endif +} + + // std::shared_ptr Resampler::resample(std::shared_ptr chunk, chronos::usec duration) // { // auto resampled_chunk = resample(chunk); @@ -85,43 +95,44 @@ Resampler::Resampler(const SampleFormat& in_format, const SampleFormat& out_form // // } // } -shared_ptr Resampler::resample(shared_ptr chunk) + +std::shared_ptr Resampler::resample(const msg::PcmChunk& chunk) { #ifndef HAS_SOXR - return chunk; + return std::make_shared(chunk); #else - if (soxr_ == nullptr) + if (!resamplingNeeded()) { - return chunk; + return std::make_shared(chunk); } else { if (in_format_.bits() == 24) { // sox expects 32 bit input, shift 8 bits left - int32_t* frames = (int32_t*)chunk->payload; - for (size_t n = 0; n < chunk->getSampleCount(); ++n) + int32_t* frames = (int32_t*)chunk.payload; + for (size_t n = 0; n < chunk.getSampleCount(); ++n) frames[n] = frames[n] << 8; } size_t idone; size_t odone; auto resample_buffer_framesize = resample_buffer_.size() / out_format_.frameSize(); - auto error = soxr_process(soxr_, chunk->payload, chunk->getFrameCount(), &idone, resample_buffer_.data(), resample_buffer_framesize, &odone); + auto error = soxr_process(soxr_, chunk.payload, chunk.getFrameCount(), &idone, resample_buffer_.data(), resample_buffer_framesize, &odone); if (error) { LOG(ERROR, LOG_TAG) << "Error soxr_process: " << error << "\n"; } else { - LOG(TRACE, LOG_TAG) << "Resample idone: " << idone << "/" << chunk->getFrameCount() << ", odone: " << odone << "/" + LOG(TRACE, LOG_TAG) << "Resample idone: " << idone << "/" << chunk.getFrameCount() << ", odone: " << odone << "/" << resample_buffer_.size() / out_format_.frameSize() << ", delay: " << soxr_delay(soxr_) << "\n"; // some data has been resampled (odone frames) and some is still in the pipe (soxr_delay frames) if (odone > 0) { // get the resampled ts from the input ts - auto input_end_ts = chunk->start() + chunk->duration(); + auto input_end_ts = chunk.start() + chunk.duration(); double resampled_ms = (odone + soxr_delay(soxr_)) / out_format_.msRate(); auto resampled_start = input_end_ts - std::chrono::microseconds(static_cast(resampled_ms * 1000.)); @@ -172,6 +183,23 @@ shared_ptr Resampler::resample(shared_ptr chunk) } +shared_ptr Resampler::resample(shared_ptr chunk) +{ +#ifndef HAS_SOXR + return chunk; +#else + if (!resamplingNeeded()) + { + return chunk; + } + else + { + return resample(*chunk); + } +#endif +} + + Resampler::~Resampler() { #ifdef HAS_SOXR diff --git a/common/resampler.hpp b/common/resampler.hpp index b496df6e..6cdc2140 100644 --- a/common/resampler.hpp +++ b/common/resampler.hpp @@ -36,6 +36,8 @@ public: // std::shared_ptr resample(std::shared_ptr chunk, chronos::usec duration); std::shared_ptr resample(std::shared_ptr chunk); + std::shared_ptr resample(const msg::PcmChunk& chunk); + bool resamplingNeeded() const; private: std::vector resample_buffer_; diff --git a/server/streamreader/meta_stream.cpp b/server/streamreader/meta_stream.cpp index 1f1547dc..cc18e097 100644 --- a/server/streamreader/meta_stream.cpp +++ b/server/streamreader/meta_stream.cpp @@ -62,10 +62,7 @@ MetaStream::MetaStream(PcmListener* pcmListener, std::vectorgetSampleFormat().rate()) || (sampleFormat_.bits() != active_stream_->getSampleFormat().bits())) - resampler_ = make_unique(active_stream_->getSampleFormat(), sampleFormat_); - else - resampler_ = nullptr; + resampler_ = make_unique(active_stream_->getSampleFormat(), sampleFormat_); } } @@ -112,10 +109,7 @@ void MetaStream::onStateChanged(const PcmStream* pcmStream, ReaderState state) if (active_stream_ != stream) { active_stream_ = stream; - if ((sampleFormat_.rate() != active_stream_->getSampleFormat().rate()) || (sampleFormat_.bits() != active_stream_->getSampleFormat().bits())) - resampler_ = make_unique(active_stream_->getSampleFormat(), sampleFormat_); - else - resampler_ = nullptr; + resampler_ = make_unique(active_stream_->getSampleFormat(), sampleFormat_); } setState(ReaderState::kPlaying); @@ -164,9 +158,9 @@ void MetaStream::onChunkRead(const PcmStream* pcmStream, const msg::PcmChunk& ch } } - if (resampler_) + if (resampler_ && resampler_->resamplingNeeded()) { - auto resampled_chunk = resampler_->resample(std::make_shared(chunk)); + auto resampled_chunk = resampler_->resample(chunk); if (resampled_chunk) chunkRead(*resampled_chunk); }