blob: 57f9dba0f5598e8aeb25e6b6b8fc720182ecd67b [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/media/audio/audio_core/audio_input.h"
#include "src/media/audio/audio_core/audio_device_manager.h"
#include "src/media/audio/audio_core/audio_driver.h"
#include "src/media/audio/audio_core/loudness_transform.h"
#include "src/media/audio/audio_core/testing/fake_audio_driver.h"
#include "src/media/audio/audio_core/testing/threading_model_fixture.h"
namespace media::audio {
namespace {
constexpr int64_t kRingBufferSizeBytes = 8 * PAGE_SIZE;
class AudioInputTestDriver : public testing::ThreadingModelFixture,
public ::testing::WithParamInterface<int32_t> {
protected:
AudioInputTestDriver()
: ThreadingModelFixture(
ProcessConfig::Builder()
.AddDeviceProfile({std::nullopt, DeviceConfig::InputDeviceProfile(GetParam())})
.SetDefaultVolumeCurve(
VolumeCurve::DefaultForMinGain(VolumeCurve::kDefaultGainForMinVolume))
.Build()) {}
void SetUp() override {
ThreadingModelFixture::SetUp();
zx::channel c1, c2;
ASSERT_EQ(ZX_OK, zx::channel::create(0, &c1, &c2));
remote_driver_ = std::make_unique<testing::FakeAudioDriver>(
std::move(c1), threading_model().FidlDomain().dispatcher());
ASSERT_NE(remote_driver_, nullptr);
fidl::InterfaceHandle<fuchsia::hardware::audio::StreamConfig> stream_config = {};
stream_config.set_channel(std::move(c2));
input_ = AudioInput::Create("", std::move(stream_config), &threading_model(),
&context().device_manager(), &context().link_matrix(),
context().clock_manager());
ASSERT_NE(input_, nullptr);
ring_buffer_mapper_ = remote_driver_->CreateRingBuffer(kRingBufferSizeBytes);
ASSERT_NE(ring_buffer_mapper_.start(), nullptr);
}
std::unique_ptr<testing::FakeAudioDriver> remote_driver_;
std::shared_ptr<AudioInput> input_;
fzl::VmoMapper ring_buffer_mapper_;
};
TEST_P(AudioInputTestDriver, RequestHardwareRateInConfigIfSupported) {
// Publish a format that has a matching sample rate, and also formats with double and half the
// requested rate.
fuchsia::hardware::audio::PcmSupportedFormats formats = {};
formats.number_of_channels.push_back(1);
formats.sample_formats.push_back(fuchsia::hardware::audio::SampleFormat::PCM_SIGNED);
formats.bytes_per_sample.push_back(2);
formats.valid_bits_per_sample.push_back(16);
formats.frame_rates.push_back(GetParam());
formats.frame_rates.push_back(2 * GetParam());
formats.frame_rates.push_back(GetParam() / 2);
remote_driver_->set_formats(std::move(formats));
remote_driver_->Start();
threading_model().FidlDomain().ScheduleTask(input_->Startup());
RunLoopUntilIdle();
auto format = input_->driver()->GetFormat();
ASSERT_TRUE(format);
ASSERT_EQ(format->frames_per_second(), GetParam());
}
TEST_P(AudioInputTestDriver, FallBackToAlternativeRateIfPreferredRateIsNotSupported) {
ASSERT_NE(GetParam(), 0); // Invalid frame rate passed as test parameter.
const int32_t kSupportedRate = GetParam() * 2;
fuchsia::hardware::audio::PcmSupportedFormats formats = {};
formats.number_of_channels.push_back(1);
formats.sample_formats.push_back(fuchsia::hardware::audio::SampleFormat::PCM_SIGNED);
formats.bytes_per_sample.push_back(2);
formats.valid_bits_per_sample.push_back(16);
formats.frame_rates.push_back(kSupportedRate);
remote_driver_->set_formats(std::move(formats));
remote_driver_->Start();
threading_model().FidlDomain().ScheduleTask(input_->Startup());
RunLoopUntilIdle();
auto format = input_->driver()->GetFormat();
ASSERT_TRUE(format);
ASSERT_EQ(format->frames_per_second(), kSupportedRate);
}
INSTANTIATE_TEST_SUITE_P(AudioInputTestDriverInstance, AudioInputTestDriver,
::testing::Values(24000, 48000, 96000));
} // namespace
} // namespace media::audio