diff --git a/src/media/audio/audio_input.cpp b/src/media/audio/audio_input.cpp index 64f869b82c5aa01caecd4b8810f709b70f3420da..7bf5d4d7b1969fc194b5742532e43982ed89f719 100644 --- a/src/media/audio/audio_input.cpp +++ b/src/media/audio/audio_input.cpp @@ -25,6 +25,7 @@ #include <chrono> #include "socket_pair.h" #include "audio/ringbufferpool.h" +#include "audio/resampler.h" #include "manager.h" #include "smartools.h" @@ -34,6 +35,8 @@ static constexpr auto MS_PER_PACKET = std::chrono::milliseconds(20); AudioInput::AudioInput(const std::string& id) : id_(id), + format_(Manager::instance().getRingBufferPool().getInternalAudioFormat()), + resampler_(new Resampler), loop_([] { return true; }, [this] { process(); }, [] {}) @@ -73,7 +76,7 @@ AudioInput::process() return; } - // get data + // getData resets the format to internal hardware format, will have to be resampled micData_.setFormat(bufferFormat); micData_.resize(samplesToGet); const auto samples = mainBuffer.getData(micData_, id_); @@ -83,9 +86,17 @@ AudioInput::process() if (muteState_) // audio is muted, set samples to 0 micData_.reset(); - // record frame - AVFrame* frame = micData_.toAVFrame(); - auto ms = MediaStream("a:local", micData_.getFormat()); + std::lock_guard<std::mutex> lk(fmtMutex_); + AudioBuffer resampled; + resampled.setFormat(format_); + if (bufferFormat != format_) { + resampler_->resample(micData_, resampled); + } else { + resampled = micData_; + } + + AVFrame* frame = resampled.toAVFrame(); + auto ms = MediaStream("a:local", format_); frame->pts = getNextTimestamp(sent_samples, ms.sampleRate, static_cast<rational<int64_t>>(ms.timeBase)); sent_samples += frame->nb_samples; @@ -97,6 +108,13 @@ AudioInput::process() } } +void +AudioInput::setFormat(const AudioFormat& fmt) +{ + std::lock_guard<std::mutex> lk(fmtMutex_); + format_ = fmt; +} + void AudioInput::setMuted(bool isMuted) { diff --git a/src/media/audio/audio_input.h b/src/media/audio/audio_input.h index 54319ed4ee4a6e5ae4899425a7d703b8d1b9d077..4623a4df11b5dd71bf0e8e90c59af713e5f4798e 100644 --- a/src/media/audio/audio_input.h +++ b/src/media/audio/audio_input.h @@ -22,6 +22,7 @@ #pragma once #include <future> +#include <mutex> #include "audio/audiobuffer.h" #include "media_device.h" @@ -31,6 +32,7 @@ namespace ring { class MediaRecorder; +class Resampler; class AudioInput { @@ -40,16 +42,20 @@ public: std::shared_future<DeviceParams> switchInput(const std::string& resource); + void setFormat(const AudioFormat& fmt); void setMuted(bool isMuted); void initRecorder(const std::shared_ptr<MediaRecorder>& rec); private: - std::weak_ptr<MediaRecorder> recorder_; - uint64_t sent_samples = 0; - std::string id_; AudioBuffer micData_; bool muteState_ = false; + uint64_t sent_samples = 0; + std::mutex fmtMutex_ {}; + AudioFormat format_; + + std::unique_ptr<Resampler> resampler_; + std::weak_ptr<MediaRecorder> recorder_; ThreadLoop loop_; void process(); diff --git a/src/media/localrecorder.cpp b/src/media/localrecorder.cpp index 893b0dda76f5ac4557f27fdd3a5191f529b65f66..d2a27cc5c01d92e0c61f933747f89af78fad2181 100644 --- a/src/media/localrecorder.cpp +++ b/src/media/localrecorder.cpp @@ -75,6 +75,7 @@ LocalRecorder::startRecording() Manager::instance().startAudioDriverStream(); audioInput_.reset(new AudioInput(path_)); + audioInput_->setFormat(AudioFormat::STEREO()); audioInput_->initRecorder(recorder_); #ifdef RING_VIDEO