blob: 551abff5e9c3687b5038a1a60060123bd9552bd3 [file] [log] [blame]
// Copyright 2019 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.
#ifndef SRC_MEDIA_AUDIO_AUDIO_CORE_TEST_PIPELINE_AUDIO_PIPELINE_TEST_H_
#define SRC_MEDIA_AUDIO_AUDIO_CORE_TEST_PIPELINE_AUDIO_PIPELINE_TEST_H_
#include <fuchsia/media/cpp/fidl.h>
#include <fuchsia/virtualaudio/cpp/fidl.h>
#include <lib/fzl/vmo-mapper.h>
#include <lib/zx/vmo.h>
#include <unordered_set>
#include "src/media/audio/lib/test/hermetic_audio_test.h"
namespace media::audio::test {
// VAD default format values
constexpr uint32_t kDefaultFrameRate = 48000;
constexpr uint32_t kDefaultSampleFormat = 4; // 16-bit LPCM
constexpr fuchsia::media::AudioSampleFormat kDefaultAudioFormat =
fuchsia::media::AudioSampleFormat::SIGNED_16;
constexpr uint32_t kDefaultSampleSize = 2;
constexpr uint32_t kDefaultNumChannels = 2;
constexpr zx_duration_t kDefaultExternalDelayNs = 0;
constexpr uint32_t kDefaultFrameSize = kDefaultSampleSize * kDefaultNumChannels;
// Test-specific values
// For our shared buffer to the renderer, use 50 pkts of 10 ms each
constexpr uint32_t kPacketMs = 10;
constexpr uint32_t kNumPayloads = 50;
constexpr uint32_t kPacketFrames = kDefaultFrameRate / 1000 * kPacketMs;
constexpr uint32_t kPacketBytes = kDefaultFrameSize * kPacketFrames;
constexpr uint32_t kRendererFrames = kPacketFrames * kNumPayloads;
constexpr uint32_t kRendererBytes = kDefaultFrameSize * kRendererFrames;
// Set VAD ring buffer to 1000 ms, with notifs every 10ms
constexpr uint32_t kSectionMs = 10;
constexpr uint32_t kNumRingSections = 100;
constexpr uint32_t kSectionFrames = kDefaultFrameRate / 1000 * kSectionMs;
constexpr uint32_t kSectionBytes = kDefaultFrameSize * kSectionFrames;
constexpr uint32_t kRingFrames = kNumRingSections * kSectionFrames;
constexpr uint32_t kRingBytes = kDefaultFrameSize * kRingFrames;
class AudioPipelineTest : public HermeticAudioCoreTest {
protected:
static void SetUpTestSuite();
static void TearDownTestSuite();
void SetUp() override;
void TearDown() override;
void AddVirtualOutput();
void SetVirtualAudioEvents();
void ResetVirtualAudioEvents();
void WaitForVirtualDeviceDepartures();
void SetAudioDeviceEvents();
void ResetAudioDeviceEvents();
void SetUpRenderer();
void SetAudioRendererEvents();
void ResetAudioRendererEvents();
void SetUpBuffers();
uint64_t RingBufferSize() const { return kDefaultFrameSize * num_rb_frames_; }
uint8_t* RingBufferStart() const { return reinterpret_cast<uint8_t*>(ring_buffer_.start()); }
// Make a copy of the virtual audio device's ring buffer, into our "snapshot" buffer.
void CreateSnapshotOfRingBuffer();
// Starting at the frame specified, return the next subsequent frame number that is zero/non-zero.
// This is used in determining whether the audio system behaved as expected.
uint32_t NextContiguousSnapshotFrame(bool look_for_nonzero, uint32_t start_frame);
// Upon failure, we display portions of the snapshot buffer, for debugging purposes.
void DisplaySnapshotSection(uint32_t section);
void DisplaySnapshotSectionsForFrames(uint32_t first = 0, uint32_t second = 0, uint32_t third = 0,
uint32_t fourth = 0, uint32_t fifth = 0);
void MapAndAddRendererBuffer(uint32_t buffer_id);
// Submit timestamped packets (also with ID-tag starting with 0). Payload data vals increase by 1
// per sample. By default, val of first payload sample is 1, and first packet PTS is 0.
void CreateAndSendPackets(uint32_t num_packets, int16_t initial_data_value = 1,
int64_t initial_pts = 0);
// Wait for packet with the given ID to complete.
void WaitForPacket(uint32_t packet_num);
// Call Play(), perfectly aligned with the VAD ring buffer rollover.
void SynchronizedPlay();
//
// virtualaudio-related members
static fuchsia::virtualaudio::ControlSyncPtr control_sync_;
fuchsia::virtualaudio::OutputPtr output_;
fuchsia::virtualaudio::InputPtr input_;
std::unordered_set<uint64_t> virtual_device_tokens_;
bool received_set_format_ = false;
bool received_set_gain_ = false;
float gain_db_ = fuchsia::media::audio::MUTED_GAIN_DB;
bool received_ring_buffer_ = false;
zx::vmo rb_vmo_;
uint32_t num_rb_frames_ = 0;
fzl::VmoMapper ring_buffer_;
bool received_start_ = false;
zx_time_t start_time_ = 0;
bool received_stop_ = false;
zx_time_t stop_time_ = 0;
uint32_t stop_pos_ = 0;
bool received_discard_all_ = false;
uint32_t ring_pos_ = 0;
uint64_t running_ring_pos_ = 0;
zx_time_t latest_pos_notify_time_ = 0;
// Snapshot of ring buffer, for comparison
std::unique_ptr<uint8_t[]> compare_buff_;
//
// AudioDeviceEnum-related members
fuchsia::media::AudioDeviceEnumeratorPtr audio_dev_enum_;
bool received_add_device_ = false;
uint64_t received_add_device_token_ = 0;
float received_gain_db_ = fuchsia::media::audio::MUTED_GAIN_DB;
bool received_mute_ = true;
bool received_remove_device_ = false;
bool received_gain_changed_ = false;
bool received_default_device_changed_ = false;
uint64_t received_default_device_token_ = 0;
//
// AudioRenderer-related members
fuchsia::media::AudioRendererPtr audio_renderer_;
bool received_min_lead_time_ = false;
int64_t min_lead_time_ = -1;
fzl::VmoMapper payload_buffer_;
bool received_play_ = false;
int64_t received_play_ref_time = 0;
int64_t received_play_media_time_ = -1;
bool received_pause_ = false;
int64_t received_pause_ref_time_ = 0;
int64_t received_pause_media_time_ = -1;
bool received_packet_completion_ = false;
uint32_t received_packet_num_ = 0;
};
} // namespace media::audio::test
#endif // SRC_MEDIA_AUDIO_AUDIO_CORE_TEST_PIPELINE_AUDIO_PIPELINE_TEST_H_