blob: 96b9dcc68d79841f6bf0d1077f7f4e6379479340 [file] [log] [blame]
// Copyright 2021 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/lib/effects_loader/effects_loader_v2.h"
#include <lib/fzl/vmo-mapper.h>
#include <lib/syslog/cpp/macros.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "src/media/audio/effects/test_effects/test_effects_v2.h"
namespace media::audio {
namespace {
zx_status_t AddOne(uint64_t num_frames, float* input, float* output,
float total_applied_gain_for_input,
std::vector<fuchsia_audio_effects::wire::ProcessMetrics>& metrics) {
for (uint64_t k = 0; k < num_frames; k++) {
output[k] = input[k] + 1;
}
return ZX_OK;
}
float* MapBufferOrDie(fzl::VmoMapper& mapper, const fuchsia_mem::wire::Range& range) {
if (auto status = mapper.Map(range.vmo, range.offset, range.size); status != ZX_OK) {
FX_PLOGS(FATAL, status) << "failed to map buffer with offset,size = " << range.offset << ","
<< range.size;
}
return reinterpret_cast<float*>(reinterpret_cast<char*>(mapper.start()) + range.offset);
}
class EffectsLoaderV2Test : public ::testing::Test {
protected:
TestEffectsV2 server_;
};
TEST_F(EffectsLoaderV2Test, CreateEffect) {
auto loader_result = EffectsLoaderV2::CreateFromChannel(server_.NewClient());
ASSERT_TRUE(loader_result.is_ok());
// Add a simple effect.
constexpr size_t kNumFrames = 10;
server_.AddEffect({
.name = "AddOne",
.process = &AddOne,
.process_in_place = true,
.max_frames_per_call = kNumFrames,
.frames_per_second = 48000,
.input_channels = 1,
.output_channels = 1,
});
// Verify the effect is available.
auto loader = loader_result.take_value();
auto config_result = loader->GetProcessorConfiguration("AddOne");
ASSERT_TRUE(config_result.ok());
// Check a few fields to make sure the config matches expectations.
auto& config = config_result->value()->processor_configuration;
ASSERT_TRUE(config.has_inputs());
ASSERT_TRUE(config.has_outputs());
EXPECT_EQ(config.inputs().size(), 1u);
EXPECT_EQ(config.outputs().size(), 1u);
EXPECT_EQ(config.inputs()[0].format().channel_count, 1u);
EXPECT_EQ(config.outputs()[0].format().channel_count, 1u);
EXPECT_EQ(config.outputs()[0].latency_frames(), 0u);
EXPECT_EQ(config.max_frames_per_call(), kNumFrames);
// Load the VMOs into our address space.
fzl::VmoMapper input_mapper;
fzl::VmoMapper output_mapper;
float* input = MapBufferOrDie(input_mapper, config.inputs()[0].buffer());
float* output = MapBufferOrDie(output_mapper, config.outputs()[0].buffer());
memset(input, 0, kNumFrames * sizeof(float));
memset(output, 0, kNumFrames * sizeof(float));
// Verify the effect works.
fidl::Arena arena;
fidl::WireSyncClient processor{std::move(config.processor())};
auto result = processor->Process(
kNumFrames, fuchsia_audio_effects::wire::ProcessOptions::Builder(arena).Build());
EXPECT_EQ(result.status(), ZX_OK);
EXPECT_FALSE(result->is_error()) << "unexpected failure: " << result->error_value();
EXPECT_THAT((reinterpret_cast<std::array<float, kNumFrames>&>(output[0])),
::testing::Each(::testing::FloatEq(1.0f)));
}
TEST_F(EffectsLoaderV2Test, EffectDoesNotExist) {
auto loader_result = EffectsLoaderV2::CreateFromChannel(server_.NewClient());
ASSERT_TRUE(loader_result.is_ok());
auto loader = loader_result.take_value();
auto result = loader->GetProcessorConfiguration("DoesNotExist");
ASSERT_TRUE(result.ok());
EXPECT_TRUE(result->is_error());
}
} // namespace
} // namespace media::audio