blob: 805f22755368eef6a2791c282da479148f59a628 [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.
#ifndef SRC_MEDIA_AUDIO_LIB_TEST_HERMETIC_PIPELINE_TEST_H_
#define SRC_MEDIA_AUDIO_LIB_TEST_HERMETIC_PIPELINE_TEST_H_
#include <optional>
#include <string>
#include <vector>
#include "src/media/audio/lib/test/hermetic_audio_test.h"
namespace media::audio::test {
// This class defines a framework for standard tests of an output pipeline. After feeding an
// arbitrary input signal through the pipeline and capturing the output, this framework can ensure
// that the output meets specific criteria -- for example, meets an expected frequency profile.
class HermeticPipelineTest : public HermeticAudioTest {
public:
void TearDown() override {
if constexpr (kEnableAllOverflowAndUnderflowChecksInRealtimeTests) {
// None of these tests should have overflows or underflows.
ExpectNoOverflowsOrUnderflows();
}
HermeticAudioTest::TearDown();
}
struct PipelineConstants {
// The pipeline's transition widths, in units of source frames.
// These correspond to the sum of widths for all output (or input) pipeline components.
//
// The first two durations encompass the "fade-in" observed in an output, when the input signal
// transitions from silence to signal. This transition is divided into the pre-transition
// "ramp-in" and the post-transition "stabilization".
//
// The next two durations encompass the "fade-out" observed in an output, when the input signal
// transitions from signal to silence. This transition is divided into the pre-transition
// "destabilization" and the post-transition "decay".
//
// For an Input signal extending from frame X to frame Y, we expect the following in the Output:
// - silence for positions corresponding to source positions before X-ramp_in_width;
// - transitional values corresponding to source range [X-ramp_in_width, X+stabilization_width];
// - pure "signal" values ONLY for output positions corresponding to source position range
// [X+stabilization_width, Y-destabilization_width];
// - transitional values corresponding to source range [Y-destabilization_width, Y+decay_width];
// - silence for positions corresponding to source positions after Y+decay_width.
//
// Restated, producing Output that corresponds to source frame range [X, Y] will actually depend
// on the content of Input frames [X-decay_width, Y+ramp_in_width].
//
// These should be upper-bounds; they don't need to be exact.
size_t ramp_in_width = 0;
size_t stabilization_width = 0;
size_t destabilization_width = 0;
size_t decay_width = 0;
// These fields are present for legacy reasons; they will be removed.
size_t pos_filter_width = 0;
size_t neg_filter_width = 0;
// Gain of the pipeline's output device.
// The test will assert that the output device is created with device gain set to this value.
float output_device_gain_db = 0;
};
// Each test can compute a precise number of expected output frames given the number of
// input frames. Our device ring buffer includes more frames than necessary so that, in
// case we write too many output frames due to a bug, we'll have plenty of space without
// wrapping around. This helps more easily detect such bugs.
static inline size_t AddSlackToOutputFrames(size_t expected_output_frames) {
return static_cast<size_t>(static_cast<double>(expected_output_frames) * 1.5);
}
template <fuchsia::media::AudioSampleFormat SampleFormat>
static void WriteWavFile(const std::string& test_name, const std::string& file_name_suffix,
AudioBufferSlice<SampleFormat> slice);
static bool save_input_and_output_files_;
};
} // namespace media::audio::test
#endif // SRC_MEDIA_AUDIO_LIB_TEST_HERMETIC_PIPELINE_TEST_H_