Skip to content
This repository has been archived by the owner on Mar 5, 2024. It is now read-only.

Commit

Permalink
tests: Port Merry's audio tests
Browse files Browse the repository at this point in the history
  • Loading branch information
SachinVin committed Jan 14, 2024
1 parent cca8c08 commit f83d01b
Show file tree
Hide file tree
Showing 8 changed files with 690 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/core/hle/service/dsp/dsp_dsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ void DSP_DSP::UnloadComponent(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(ResultSuccess);

LOG_INFO(Service_DSP, "(STUBBED)");
LOG_INFO(Service_DSP, "called");
}

void DSP_DSP::FlushDataCache(Kernel::HLERequestContext& ctx) {
Expand Down
5 changes: 5 additions & 0 deletions src/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ add_executable(tests
audio_core/audio_fixures.h
audio_core/decoder_tests.cpp
video_core/shader/shader_jit_compiler.cpp
audio_core/merryhime_3ds_audio/merry_audio/merry_audio.cpp
audio_core/merryhime_3ds_audio/merry_audio/merry_audio.h
audio_core/merryhime_3ds_audio/merry_audio/service_fixture.cpp
audio_core/merryhime_3ds_audio/merry_audio/service_fixture.h
audio_core/merryhime_3ds_audio/audio_test_biquad_filter.cpp
)

create_target_directory_groups(tests)
Expand Down
1 change: 1 addition & 0 deletions src/tests/audio_core/merryhime_3ds_audio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Port of HW tests from https://github.com/merryhime/3ds-audio
153 changes: 153 additions & 0 deletions src/tests/audio_core/merryhime_3ds_audio/audio_test_biquad_filter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <catch2/catch_template_test_macros.hpp>
#include "audio_core/hle/hle.h"
#include "audio_core/hle/shared_memory.h"
#include "audio_core/lle/lle.h"
#include "common/file_util.h"
#include "common/logging/backend.h"
#include "common/settings.h"
#include "core/memory.h"
#include "merry_audio/merry_audio.h"

TEST_CASE_METHOD(MerryAudio::MerryAudioFixture, "AudioTest-BiquadFilter",
"[audio_core][merryhime_3ds_audio]") {
// High frequency square wave, PCM16
auto fillBuffer = [this](u32* audio_buffer, size_t size) {
for (size_t i = 0; i < size; i++) {
u32 data = (i % 2 == 0 ? 0x1000 : 0x2000);
audio_buffer[i] = (data << 16) | (data & 0xFFFF);
}

DSP_FlushDataCache(audio_buffer, size);
};

constexpr size_t NUM_SAMPLES = 160 * 200;
u32* audio_buffer = (u32*)linearAlloc(NUM_SAMPLES * sizeof(u32));
fillBuffer(audio_buffer, NUM_SAMPLES);

MerryAudio::AudioState state;
{
// The test case assumes HLE AudioCore doesn't require a valid firmware
// Uncomment the below line if the test is using LLE audio
// auto dspfirm = loadDspFirmFromFile();
std::vector<u8> dspfirm = {0};
if (!dspfirm.size()) {
SKIP("Couldn't load firmware\n");
goto end;
}
auto ret = audioInit(dspfirm);
if (!ret) {
INFO("Couldn't init audio\n");
goto end;
}
state = *ret;
}

{
/*
const s16 b0 = 0.057200221035302035 * (1 << 14);
const s16 b1 = 0.11440044207060407 * (1 << 14);
const s16 b2 = 0.0238274928983472 * (1 << 14);
const s16 a1 = -1.2188761083637 * (1 << 14);
const s16 a2 = 0.44767699250490806 * (1 << 14);
*/
srand((u32)time(nullptr));
const s16 b0 = rand();
const s16 b1 = rand();
const s16 b2 = rand();
const s16 a1 = rand();
const s16 a2 = rand();

std::array<s32, 160> expected_output;
{
s32 x1 = 0;
s32 x2 = 0;
s32 y1 = 0;
s32 y2 = 0;
for (int i = 0; i < 160; i++) {
const s32 x0 = (i % 4 == 0 || i % 4 == 1 ? 0x1000 : 0x2000);
s32 y0 = ((s32)x0 * (s32)b0 + (s32)x1 * b1 + (s32)x2 * b2 + (s32)a1 * y1 +
(s32)a2 * y2) >>
14;

y0 = std::clamp(y0, -32768, 32767);
expected_output[i] = y2;

x2 = x1;
x1 = x0;
y2 = y1;
y1 = y0;
}
}

state.waitForSync();
initSharedMem(state);
state.write().dsp_configuration->aux_bus_enable_0_dirty.Assign(true);
state.write().dsp_configuration->aux_bus_enable[0] = true;
state.write().source_configurations->config[0].gain[1][0] = 1.0;
state.write().source_configurations->config[0].gain_1_dirty.Assign(true);
state.notifyDsp();
state.waitForSync();

{
u16 buffer_id = 0;

state.write().source_configurations->config[0].play_position = 0;
state.write().source_configurations->config[0].physical_address =
osConvertVirtToPhys(audio_buffer);
state.write().source_configurations->config[0].length = NUM_SAMPLES;
state.write().source_configurations->config[0].mono_or_stereo.Assign(
AudioCore::HLE::SourceConfiguration::Configuration::MonoOrStereo::Mono);
state.write().source_configurations->config[0].format.Assign(
AudioCore::HLE::SourceConfiguration::Configuration::Format::PCM16);
state.write().source_configurations->config[0].fade_in.Assign(false);
state.write().source_configurations->config[0].adpcm_dirty.Assign(false);
state.write().source_configurations->config[0].is_looping.Assign(false);
state.write().source_configurations->config[0].buffer_id = ++buffer_id;
state.write().source_configurations->config[0].partial_reset_flag.Assign(true);
state.write().source_configurations->config[0].play_position_dirty.Assign(true);
state.write().source_configurations->config[0].embedded_buffer_dirty.Assign(true);

state.write().source_configurations->config[0].enable = true;
state.write().source_configurations->config[0].enable_dirty.Assign(true);

state.write().source_configurations->config[0].simple_filter.b0 = 0;
state.write().source_configurations->config[0].simple_filter.a1 = 0;
state.write().source_configurations->config[0].simple_filter_enabled.Assign(false);
state.write().source_configurations->config[0].biquad_filter_enabled.Assign(true);
state.write().source_configurations->config[0].biquad_filter.b0 = b0;
state.write().source_configurations->config[0].biquad_filter.b1 = b1;
state.write().source_configurations->config[0].biquad_filter.b2 = b2;
state.write().source_configurations->config[0].biquad_filter.a1 = a1;
state.write().source_configurations->config[0].biquad_filter.a2 = a2;
state.write().source_configurations->config[0].filters_enabled_dirty.Assign(true);
state.write().source_configurations->config[0].biquad_filter_dirty.Assign(true);
state.write().source_configurations->config[0].simple_filter_dirty.Assign(true);
state.notifyDsp();

bool continue_reading = true;
for (size_t frame_count = 0; continue_reading && frame_count < 10; frame_count++) {
state.waitForSync();

for (size_t i = 0; i < 160; i++) {
if (state.read().intermediate_mix_samples->mix1.pcm32[0][i]) {
for (size_t j = 0; j < 60; j++) {
REQUIRE(state.read().intermediate_mix_samples->mix1.pcm32[0][j] ==
expected_output[j]);
}
continue_reading = false;
break;
}
}

state.notifyDsp();
}
REQUIRE(continue_reading == false);
}
}

end:
audioExit(state);
}
Loading

0 comments on commit f83d01b

Please sign in to comment.