Commit 34e72c5a authored by Philippe Gorley's avatar Philippe Gorley

audio_input: add resampler

RingBufferPool::getData overrides the format of the AudioBuffer, so
resampling may be required.

Protects AudioFormat with a mutex to avoid data races.

Change-Id: I0a9d8686f142c192f912887b175a42bacb0c1a57
parent 83a129c5
......@@ -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)
{
......
......@@ -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();
......
......@@ -75,6 +75,7 @@ LocalRecorder::startRecording()
Manager::instance().startAudioDriverStream();
audioInput_.reset(new AudioInput(path_));
audioInput_->setFormat(AudioFormat::STEREO());
audioInput_->initRecorder(recorder_);
#ifdef RING_VIDEO
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment