Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Unified Diff: webrtc/test/fake_audio_device.cc

Issue 2717623003: Add the ability to read/write to WAV files in FakeAudioDevice (Closed)
Patch Set: Prevent nested CritScope to fix 'use of an invalid mutex' Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« webrtc/test/fake_audio_device.h ('K') | « webrtc/test/fake_audio_device.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/test/fake_audio_device.cc
diff --git a/webrtc/test/fake_audio_device.cc b/webrtc/test/fake_audio_device.cc
index 623ff518d7b0e9f3aba9e0e98e4d0505f77dbb3f..9e81c6f2687f6e95642d7f6b04b723e9d0ac8434 100644
--- a/webrtc/test/fake_audio_device.cc
+++ b/webrtc/test/fake_audio_device.cc
@@ -11,10 +11,11 @@
#include "webrtc/test/fake_audio_device.h"
#include <algorithm>
+#include <utility>
-#include "webrtc/base/array_view.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/random.h"
+#include "webrtc/common_audio/wav_file.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"
namespace webrtc {
@@ -24,58 +25,144 @@ namespace {
constexpr int kFrameLengthMs = 10;
constexpr int kFramesPerSecond = 1000 / kFrameLengthMs;
-} // namespace
-namespace test {
-
// Assuming 10ms audio packets..
-class FakeAudioDevice::PulsedNoiseCapturer {
+class PulsedNoiseCapturer final : public test::FakeAudioDevice::Capturer {
public:
- PulsedNoiseCapturer(size_t num_samples_per_frame, int16_t max_amplitude)
- : fill_with_zero_(false),
+ PulsedNoiseCapturer(int16_t max_amplitude, int sampling_frequency_in_hz)
+ : Capturer(sampling_frequency_in_hz),
+ fill_with_zero_(false),
random_generator_(1),
- max_amplitude_(max_amplitude),
- random_audio_(num_samples_per_frame),
- silent_audio_(num_samples_per_frame, 0) {
+ max_amplitude_(max_amplitude) {
RTC_DCHECK_GT(max_amplitude, 0);
}
- rtc::ArrayView<const int16_t> Capture() {
+ bool Capture(rtc::BufferT<int16_t>* buffer) override {
fill_with_zero_ = !fill_with_zero_;
- if (!fill_with_zero_) {
- std::generate(random_audio_.begin(), random_audio_.end(), [&]() {
- return random_generator_.Rand(-max_amplitude_, max_amplitude_);
- });
- }
- return fill_with_zero_ ? silent_audio_ : random_audio_;
+ buffer->SetData(SamplesPerFrame(), [&](rtc::ArrayView<int16_t> data) {
+ if (fill_with_zero_) {
+ std::fill(data.begin(), data.end(), 0);
+ } else {
+ std::generate(data.begin(), data.end(), [&]() {
+ return random_generator_.Rand(-max_amplitude_, max_amplitude_);
+ });
+ }
+ return data.size();
+ });
kwiberg-webrtc 2017/03/13 10:18:22 Excellent use of SetData with a lambda!
+ return true;
}
private:
bool fill_with_zero_;
Random random_generator_;
const int16_t max_amplitude_;
- std::vector<int16_t> random_audio_;
- std::vector<int16_t> silent_audio_;
};
-FakeAudioDevice::FakeAudioDevice(float speed,
- int sampling_frequency_in_hz,
- int16_t max_amplitude)
+class WavFileReader final : public test::FakeAudioDevice::Capturer {
+ public:
+ WavFileReader(std::string filename, int sampling_frequency_in_hz)
+ : test::FakeAudioDevice::Capturer(sampling_frequency_in_hz),
+ wav_reader_(filename) {
+ RTC_CHECK_EQ(wav_reader_.sample_rate(), sampling_frequency_in_hz);
+ RTC_CHECK_EQ(wav_reader_.num_channels(), 1);
+ }
+
+ bool Capture(rtc::BufferT<int16_t>* buffer) override {
+ buffer->SetData(SamplesPerFrame(), [&](rtc::ArrayView<int16_t> data) {
+ return wav_reader_.ReadSamples(data.size(), data.data());
+ });
+ return buffer->size() > 0;
+ }
+
+ private:
+ WavReader wav_reader_;
+};
+
+class WavFileWriter final : public test::FakeAudioDevice::Renderer {
+ public:
+ WavFileWriter(std::string filename, int sampling_frequency_in_hz)
+ : test::FakeAudioDevice::Renderer(sampling_frequency_in_hz),
+ wav_writer_(filename, sampling_frequency_in_hz, 1) {}
+
+ bool Render(rtc::ArrayView<const int16_t> data) override {
+ wav_writer_.WriteSamples(data.data(), data.size());
+ return true;
+ }
+
+ private:
+ WavWriter wav_writer_;
+};
+
+class Discarder final : public test::FakeAudioDevice::Renderer {
+ public:
+ using Renderer::Renderer;
+
+ bool Render(rtc::ArrayView<const int16_t> data) override {
+ return true;
+ }
+};
+
+} // namespace
+namespace test {
+
+FakeAudioDevice::Streamer::Streamer(int sampling_frequency_in_hz)
: sampling_frequency_in_hz_(sampling_frequency_in_hz),
- num_samples_per_frame_(
- rtc::CheckedDivExact(sampling_frequency_in_hz_, kFramesPerSecond)),
+ num_samples_per_frame_(
+ rtc::CheckedDivExact(sampling_frequency_in_hz, kFramesPerSecond)) {
+ RTC_CHECK(
+ sampling_frequency_in_hz == 8000 || sampling_frequency_in_hz == 16000 ||
+ sampling_frequency_in_hz == 32000 || sampling_frequency_in_hz == 44100 ||
+ sampling_frequency_in_hz == 48000);
+}
+
+std::unique_ptr<FakeAudioDevice::Capturer>
+ FakeAudioDevice::CreatePulsedNoiseCapturer(
+ int16_t max_amplitude, int sampling_frequency_in_hz) {
+ return std::unique_ptr<FakeAudioDevice::Capturer>(
+ new PulsedNoiseCapturer(max_amplitude, sampling_frequency_in_hz));
+}
+
+std::unique_ptr<FakeAudioDevice::Capturer> FakeAudioDevice::CreateWavFileReader(
+ std::string filename, int sampling_frequency_in_hz) {
+ return std::unique_ptr<FakeAudioDevice::Capturer>(
+ new WavFileReader(filename, sampling_frequency_in_hz));
+}
+
+std::unique_ptr<FakeAudioDevice::Capturer> FakeAudioDevice::CreateWavFileReader(
+ std::string filename) {
+ int sampling_frequency_in_hz = WavReader(filename).sample_rate();
+ return std::unique_ptr<FakeAudioDevice::Capturer>(
+ new WavFileReader(filename, sampling_frequency_in_hz));
+}
+
+std::unique_ptr<FakeAudioDevice::Renderer> FakeAudioDevice::CreateWavFileWriter(
+ std::string filename, int sampling_frequency_in_hz) {
+ return std::unique_ptr<FakeAudioDevice::Renderer>(
+ new WavFileWriter(filename, sampling_frequency_in_hz));
+}
+
+std::unique_ptr<FakeAudioDevice::Renderer> FakeAudioDevice::CreateDiscarder(
+ int sampling_frequency_in_hz) {
+ return std::unique_ptr<FakeAudioDevice::Renderer>(
+ new Discarder(sampling_frequency_in_hz));
+}
+
+
+FakeAudioDevice::FakeAudioDevice(std::unique_ptr<Capturer> capturer,
+ std::unique_ptr<Renderer> renderer,
+ float speed)
+ : capturer_(std::move(capturer)),
+ renderer_(std::move(renderer)),
speed_(speed),
audio_callback_(nullptr),
rendering_(false),
capturing_(false),
- capturer_(new FakeAudioDevice::PulsedNoiseCapturer(num_samples_per_frame_,
- max_amplitude)),
- playout_buffer_(num_samples_per_frame_, 0),
+ done_rendering_(true, true),
+ done_capturing_(true, true),
tick_(EventTimerWrapper::Create()),
thread_(FakeAudioDevice::Run, this, "FakeAudioDevice") {
- RTC_DCHECK(
- sampling_frequency_in_hz == 8000 || sampling_frequency_in_hz == 16000 ||
- sampling_frequency_in_hz == 32000 || sampling_frequency_in_hz == 44100 ||
- sampling_frequency_in_hz == 48000);
+ if (renderer_) {
+ playout_buffer_.resize(renderer_->SamplesPerFrame(), 0);
+ }
}
FakeAudioDevice::~FakeAudioDevice() {
@@ -86,25 +173,31 @@ FakeAudioDevice::~FakeAudioDevice() {
int32_t FakeAudioDevice::StartPlayout() {
rtc::CritScope cs(&lock_);
+ RTC_CHECK(renderer_);
rendering_ = true;
+ done_rendering_.Reset();
return 0;
}
int32_t FakeAudioDevice::StopPlayout() {
rtc::CritScope cs(&lock_);
rendering_ = false;
+ done_rendering_.Set();
return 0;
}
int32_t FakeAudioDevice::StartRecording() {
rtc::CritScope cs(&lock_);
+ RTC_CHECK(capturer_);
capturing_ = true;
+ done_capturing_.Reset();
return 0;
}
int32_t FakeAudioDevice::StopRecording() {
rtc::CritScope cs(&lock_);
capturing_ = false;
+ done_capturing_.Set();
return 0;
}
@@ -117,7 +210,7 @@ int32_t FakeAudioDevice::Init() {
int32_t FakeAudioDevice::RegisterAudioCallback(AudioTransport* callback) {
rtc::CritScope cs(&lock_);
- RTC_DCHECK(callback || audio_callback_ != nullptr);
+ RTC_DCHECK(callback || audio_callback_);
audio_callback_ = callback;
return 0;
}
@@ -132,6 +225,14 @@ bool FakeAudioDevice::Recording() const {
return capturing_;
}
+bool FakeAudioDevice::WaitForPlayoutEnd(int timeout_ms) {
+ return done_rendering_.Wait(timeout_ms);
+}
+
+bool FakeAudioDevice::WaitForRecordingEnd(int timeout_ms) {
+ return done_capturing_.Wait(timeout_ms);
+}
+
bool FakeAudioDevice::Run(void* obj) {
static_cast<FakeAudioDevice*>(obj)->ProcessAudio();
return true;
@@ -142,19 +243,31 @@ void FakeAudioDevice::ProcessAudio() {
rtc::CritScope cs(&lock_);
if (capturing_) {
// Capture 10ms of audio. 2 bytes per sample.
- rtc::ArrayView<const int16_t> audio_data = capturer_->Capture();
- uint32_t new_mic_level = 0;
- audio_callback_->RecordedDataIsAvailable(
- audio_data.data(), audio_data.size(), 2, 1, sampling_frequency_in_hz_,
- 0, 0, 0, false, new_mic_level);
+ const bool keep_recording = capturer_->Capture(&recording_buffer_);
+ uint32_t new_mic_level;
+ if (recording_buffer_.size() > 0) {
+ audio_callback_->RecordedDataIsAvailable(
+ recording_buffer_.data(), recording_buffer_.size(), 2, 1,
+ capturer_->SamplingFrequency(), 0, 0, 0, false, new_mic_level);
+ }
+ if (!keep_recording) {
+ capturing_ = false;
+ done_capturing_.Set();
kwiberg-webrtc 2017/03/13 10:18:21 Nit: It looks like keep_recording could be named k
oprypin_webrtc 2017/03/13 13:55:14 Done.
+ }
}
if (rendering_) {
- size_t samples_out = 0;
- int64_t elapsed_time_ms = -1;
- int64_t ntp_time_ms = -1;
+ size_t samples_out;
+ int64_t elapsed_time_ms;
+ int64_t ntp_time_ms;
audio_callback_->NeedMorePlayData(
- num_samples_per_frame_, 2, 1, sampling_frequency_in_hz_,
+ renderer_->SamplesPerFrame(), 2, 1, renderer_->SamplingFrequency(),
playout_buffer_.data(), samples_out, &elapsed_time_ms, &ntp_time_ms);
+ const bool keep_rendering = renderer_->Render(
+ rtc::ArrayView<const int16_t>(playout_buffer_.data(), samples_out));
+ if (!keep_rendering) {
+ rendering_ = false;
+ done_rendering_.Set();
+ }
}
}
tick_->Wait(WEBRTC_EVENT_INFINITE);
« webrtc/test/fake_audio_device.h ('K') | « webrtc/test/fake_audio_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698