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

Unified Diff: webrtc/test/fake_audio_device.cc

Issue 2717623003: Add the ability to read/write to WAV files in FakeAudioDevice (Closed)
Patch Set: Remove obsolete files from build 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..5e757125c84e99d9631cfa9788940bcdd25a18a5 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 {
@@ -27,19 +28,30 @@ constexpr int kFramesPerSecond = 1000 / kFrameLengthMs;
} // namespace
kwiberg-webrtc 2017/03/09 10:04:10 The Capturers and Renderers should be in an anonym
oprypin_webrtc 2017/03/10 10:44:27 Done.
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)) {
+ 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);
+}
+
// Assuming 10ms audio packets..
-class FakeAudioDevice::PulsedNoiseCapturer {
+class FakeAudioDevice::PulsedNoiseCapturer : public FakeAudioDevice::Capturer {
public:
- PulsedNoiseCapturer(size_t num_samples_per_frame, int16_t max_amplitude)
- : fill_with_zero_(false),
+ PulsedNoiseCapturer(int sampling_frequency_in_hz, int16_t max_amplitude)
+ : 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) {
+ random_audio_(SamplesPerFrame()),
+ silent_audio_(SamplesPerFrame(), 0) {
RTC_DCHECK_GT(max_amplitude, 0);
}
- rtc::ArrayView<const int16_t> Capture() {
+ rtc::ArrayView<const int16_t> Capture() override {
fill_with_zero_ = !fill_with_zero_;
if (!fill_with_zero_) {
std::generate(random_audio_.begin(), random_audio_.end(), [&]() {
@@ -57,27 +69,112 @@ class FakeAudioDevice::PulsedNoiseCapturer {
std::vector<int16_t> silent_audio_;
};
-FakeAudioDevice::FakeAudioDevice(float speed,
- int sampling_frequency_in_hz,
- int16_t max_amplitude)
- : sampling_frequency_in_hz_(sampling_frequency_in_hz),
- num_samples_per_frame_(
- rtc::CheckedDivExact(sampling_frequency_in_hz_, kFramesPerSecond)),
+class FakeAudioDevice::WavFileReader : public FakeAudioDevice::Capturer {
kwiberg-webrtc 2017/03/09 10:04:10 This class (and the other three) can be final.
oprypin_webrtc 2017/03/10 10:44:27 Done.
+ public:
+ WavFileReader(std::string filename, int sampling_frequency_in_hz)
+ : FakeAudioDevice::Capturer(sampling_frequency_in_hz),
+ wav_reader_(filename),
+ buffer_(SamplesPerFrame(), 0) {
+ RTC_CHECK_EQ(wav_reader_.sample_rate(), sampling_frequency_in_hz);
+ RTC_CHECK_EQ(wav_reader_.num_channels(), 1);
+ }
+
+ rtc::ArrayView<const int16_t> Capture() override {
+ const size_t samples_out = wav_reader_.ReadSamples(buffer_.size(),
+ buffer_.data());
+ RTC_CHECK_LE(samples_out, buffer_.size());
+ return rtc::ArrayView<const int16_t>(buffer_.data(), samples_out);
+ }
+
+ private:
+ WavReader wav_reader_;
+ std::vector<int16_t> buffer_;
+ // This event is set when the input audio file ends
kwiberg-webrtc 2017/03/09 10:04:10 Orphaned comment.
oprypin_webrtc 2017/03/10 10:44:27 Done. Removed.
+};
+
+class FakeAudioDevice::WavFileWriter : public FakeAudioDevice::Renderer {
+ public:
+ WavFileWriter(std::string filename, int sampling_frequency_in_hz)
+ : FakeAudioDevice::Renderer(sampling_frequency_in_hz),
+ wav_writer_(filename, sampling_frequency_in_hz, 1) {}
+
+ bool Render(rtc::ArrayView<const int16_t> data) {
kwiberg-webrtc 2017/03/09 10:04:10 override?
oprypin_webrtc 2017/03/10 10:44:27 Done.
+ wav_writer_.WriteSamples(data.data(), data.size());
+ return true;
+ }
+
+ private:
+ WavWriter wav_writer_;
+};
+
+class FakeAudioDevice::Discarder : public FakeAudioDevice::Renderer {
+ public:
+ using Renderer::Renderer;
+
+ bool Render(rtc::ArrayView<const int16_t> data) {
+ return true;
+ }
+};
+
+std::unique_ptr<FakeAudioDevice::Capturer>
+ FakeAudioDevice::CreatePulsedNoiseCapturer(
+ int sampling_frequency_in_hz, int16_t max_amplitude) {
+ return std::unique_ptr<FakeAudioDevice::Capturer>(
+ new FakeAudioDevice::PulsedNoiseCapturer(
+ sampling_frequency_in_hz, max_amplitude));
+}
+
+std::unique_ptr<FakeAudioDevice::Capturer> FakeAudioDevice::CreateWavFileReader(
+ std::string filename, int sampling_frequency_in_hz) {
+ return std::unique_ptr<FakeAudioDevice::Capturer>(
+ new FakeAudioDevice::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 FakeAudioDevice::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 FakeAudioDevice::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 FakeAudioDevice::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(float speed,
+ int sampling_frequency_in_hz,
+ int16_t max_amplitude)
+ : FakeAudioDevice(
+ CreatePulsedNoiseCapturer(sampling_frequency_in_hz, max_amplitude),
+ CreateDiscarder(sampling_frequency_in_hz), speed) {}
+
FakeAudioDevice::~FakeAudioDevice() {
StopPlayout();
StopRecording();
@@ -86,25 +183,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 +220,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 +235,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;
@@ -144,17 +255,26 @@ void FakeAudioDevice::ProcessAudio() {
// 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);
+ if (audio_data.size() > 0) {
+ audio_callback_->RecordedDataIsAvailable(
+ audio_data.data(), audio_data.size(), 2, 1,
+ capturer_->SamplingFrequency(), 0, 0, 0, false, new_mic_level);
+ } else {
+ StopRecording();
+ }
}
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);
+ bool keep_rendering = renderer_->Render(
kwiberg-webrtc 2017/03/09 10:04:10 const?
oprypin_webrtc 2017/03/10 10:44:27 Done.
+ rtc::ArrayView<const int16_t>(playout_buffer_.data(), samples_out));
+ if (!keep_rendering) {
+ StopPlayout();
+ }
}
}
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