Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <type_traits>
#include "Common/Cpp/Exceptions.h"
#include "Common/Cpp/Containers/AlignedVector.tpp"
#include "Common/Cpp/PrettyPrint.h"
#include "Kernels_AudioPipeline_RoundTrip_TestInfra.h"
#include "Kernels_RawAudio2WorkingAudio.h"
#include "Kernels_WorkingAudio2RawAudio.h"
Expand Down Expand Up @@ -70,7 +71,7 @@ std::string sample_typestr(SampleFormat sample_type){


template <typename Type>
UnitTestResult run_round_trip(SampleFormat sample_type, size_t channels, size_t samples){
UnitTestResult run_round_trip(SampleFormat sample_type, size_t channels, size_t samples, float from_multiplier){
// Generate random input.
AlignedVector<Type> input(samples * channels);
std::mt19937 generator(42);
Expand Down Expand Up @@ -98,8 +99,14 @@ UnitTestResult run_round_trip(SampleFormat sample_type, size_t channels, size_t

// Small buffer so the sample-size sweep hits multiple chunks.
const size_t buffer_size = 256;
RawAudio2WorkingAudio raw2working(sample_type, sample_rate, channels, buffer_size);
WorkingAudio2RawAudio working2raw(sample_type, sample_rate, channels, 1.0f, buffer_size);
RawAudio2WorkingAudio raw2working(
sample_type, sample_rate, channels,
from_multiplier, buffer_size
);
WorkingAudio2RawAudio working2raw(
sample_type, sample_rate, channels,
1.0f / from_multiplier, buffer_size
);
RecordingRawAudioListener<Type> output(sample_type, sample_rate, channels, samples * channels);
raw2working.add_listener(working2raw);
working2raw.add_listener(output);
Expand Down Expand Up @@ -132,26 +139,39 @@ UnitTestResult run_round_trip(SampleFormat sample_type, size_t channels, size_t
RoundTripTest::RoundTripTest(
SampleFormat sample_type,
size_t channels,
size_t samples
size_t samples,
float from_multiplier
)
: UnitTest(
"Kernels::AudioPipeline - RoundTrip_" + sample_typestr(sample_type) +
"(" + std::to_string(channels) + "ch x " + std::to_string(samples) + ")"
)
: UnitTest(make_name(sample_type, channels, samples, from_multiplier))
, m_sample_type(sample_type)
, m_channels(channels)
, m_samples(samples)
, m_from_multiplier(from_multiplier)
{}
std::string RoundTripTest::make_name(
SampleFormat sample_type,
size_t channels,
size_t samples,
float from_multiplier
){
std::string name = "Kernels::AudioPipeline - RoundTrip_" + sample_typestr(sample_type) +
"(" + std::to_string(channels) + "ch x " + std::to_string(samples) + ")";
if (from_multiplier != 1.0f){
name += " [from " + tostr_default(from_multiplier) +
" / to " + tostr_default(1.0f / from_multiplier) + "]";
}
return name;
}
UnitTestResult RoundTripTest::run(Logger& logger, CancellableScope& scope) const{
switch (m_sample_type){
case SampleFormat::UINT8:
return run_round_trip<uint8_t>(m_sample_type, m_channels, m_samples);
return run_round_trip<uint8_t>(m_sample_type, m_channels, m_samples, m_from_multiplier);
case SampleFormat::SINT16:
return run_round_trip<int16_t>(m_sample_type, m_channels, m_samples);
return run_round_trip<int16_t>(m_sample_type, m_channels, m_samples, m_from_multiplier);
case SampleFormat::SINT32:
return run_round_trip<int32_t>(m_sample_type, m_channels, m_samples);
return run_round_trip<int32_t>(m_sample_type, m_channels, m_samples, m_from_multiplier);
case SampleFormat::FLOAT32:
return run_round_trip<float>(m_sample_type, m_channels, m_samples);
return run_round_trip<float>(m_sample_type, m_channels, m_samples, m_from_multiplier);
default:
throw InternalProgramError(&logger, PA_CURRENT_FUNCTION, "Unknown sample type.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,34 @@ namespace AudioPipeline{

//
// Pushes random samples through a RawAudio2WorkingAudio node and a
// WorkingAudio2RawAudio node (with a 1.0f multiplier), then compares the
// resulting raw samples to the input.
// WorkingAudio2RawAudio node (with reciprocal multipliers, so the
// round trip is lossless), then compares the resulting raw samples
// to the input.
//
class RoundTripTest : public UnitTest{
public:
RoundTripTest(
SampleFormat sample_type,
size_t channels,
size_t samples
size_t samples,
float from_multiplier = 1.0f
);

virtual UnitTestResult run(Logger& logger, CancellableScope& scope) const override;


private:
static std::string make_name(
SampleFormat sample_type,
size_t channels,
size_t samples,
float from_multiplier
);

const SampleFormat m_sample_type;
const size_t m_channels;
const size_t m_samples;
const float m_from_multiplier;
};


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@ namespace AudioPipeline{




void add_tests(UnitTestDatabase& database){
// Raw -> Working -> Raw round-trip.
// Raw -> Working -> Raw round-trip, with reciprocal multipliers on
// the two nodes (exact in binary) to exercise the gain path.
const float from_multipliers[] = { 1.0f, 0.5f };
for (size_t channels = 1; channels <= 4; channels++){
for (size_t samples = 2; samples < 1000; samples = (size_t)(samples * 1.1) + 1){
database.add<RoundTripTest>(SampleFormat::UINT8, channels, samples);
database.add<RoundTripTest>(SampleFormat::SINT16, channels, samples);
database.add<RoundTripTest>(SampleFormat::SINT32, channels, samples);
database.add<RoundTripTest>(SampleFormat::FLOAT32, channels, samples);
for (float from_multiplier : from_multipliers){
database.add<RoundTripTest>(SampleFormat::UINT8, channels, samples, from_multiplier);
database.add<RoundTripTest>(SampleFormat::SINT16, channels, samples, from_multiplier);
database.add<RoundTripTest>(SampleFormat::SINT32, channels, samples, from_multiplier);
database.add<RoundTripTest>(SampleFormat::FLOAT32, channels, samples, from_multiplier);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ template <typename Type>
void RawAudio2WorkingAudio::set_converter(){
m_convert = [this](const void* data, size_t samples){
Kernels::AudioStreamConverter::convert_from<Type>(
m_interleaved_floats.data(), (const Type*)data, samples
m_interleaved_floats.data(), (const Type*)data, samples,
m_multiplier.load(std::memory_order_acquire)
);
};
}
Expand All @@ -49,9 +50,11 @@ RawAudio2WorkingAudio::RawAudio2WorkingAudio(
SampleFormat sample_type,
size_t sample_rate,
size_t channels,
float multiplier,
size_t buffer_size
)
: RawAudioStreamListener(sample_type, sample_rate, channels)
, m_multiplier(multiplier)
, m_buffer_size(buffer_size)
{
// Single-channel float is pass-through.
Expand Down Expand Up @@ -95,6 +98,9 @@ void RawAudio2WorkingAudio::add_listener(WorkingAudioStreamListener& listener){
void RawAudio2WorkingAudio::remove_listener(WorkingAudioStreamListener& listener){
m_listeners.remove(listener);
}
void RawAudio2WorkingAudio::set_multiplier(float multiplier){
m_multiplier.store(multiplier, std::memory_order_release);
}

void RawAudio2WorkingAudio::push_samples(size_t frames, const void* data){
// Single-channel float pass-through.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef PokemonAutomation_Kernels_AudioPipeline_RawAudio2WorkingAudio_H
#define PokemonAutomation_Kernels_AudioPipeline_RawAudio2WorkingAudio_H

#include <atomic>
#include <functional>
#include "Common/Cpp/ListenerSet.h"
#include "Common/Cpp/Containers/AlignedVector.h"
Expand All @@ -25,12 +26,15 @@ class RawAudio2WorkingAudio : public RawAudioStreamListener{
SampleFormat sample_type,
size_t sample_rate,
size_t channels,
float multiplier,
size_t buffer_size = 4096 + 256 // 4k + break super-alignment
);

void add_listener(WorkingAudioStreamListener& listener);
void remove_listener(WorkingAudioStreamListener& listener);

void set_multiplier(float multiplier);

virtual void push_samples(size_t frames, const void* data) override;


Expand All @@ -40,6 +44,7 @@ class RawAudio2WorkingAudio : public RawAudioStreamListener{


private:
std::atomic<float> m_multiplier;
size_t m_buffer_size;
std::function<void(const void* data, size_t frames)> m_convert = nullptr;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,39 @@ namespace AudioStreamConverter{


template <typename ExternalType>
void convert_from_Default(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples);
void convert_from_Default(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples, float multiplier);
template <typename ExternalType>
void convert_to_Default(c_ptr<float> native, r_ptr<ExternalType> ext, size_t samples, float multiplier);
void add_tests_Default(UnitTestDatabase& database);



template <typename ExternalType>
void convert_from_x64_SSE41(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples);
void convert_from_x64_SSE41(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples, float multiplier);
template <typename ExternalType>
void convert_to_x64_SSE41(c_ptr<float> native, r_ptr<ExternalType> ext, size_t samples, float multiplier);
void add_tests_x64_SSE41(UnitTestDatabase& database);



template <typename ExternalType>
void convert_from_x64_AVX2(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples);
void convert_from_x64_AVX2(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples, float multiplier);
template <typename ExternalType>
void convert_to_x64_AVX2(c_ptr<float> native, r_ptr<ExternalType> ext, size_t samples, float multiplier);
void add_tests_x64_AVX2(UnitTestDatabase& database);



template <typename ExternalType>
void convert_from_x64_AVX512(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples);
void convert_from_x64_AVX512(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples, float multiplier);
template <typename ExternalType>
void convert_to_x64_AVX512(c_ptr<float> native, r_ptr<ExternalType> ext, size_t samples, float multiplier);
void add_tests_x64_AVX512(UnitTestDatabase& database);



template <typename ExternalType>
void convert_from_ARM64_NEON(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples);
void convert_from_ARM64_NEON(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples, float multiplier);
template <typename ExternalType>
void convert_to_ARM64_NEON(c_ptr<float> native, r_ptr<ExternalType> ext, size_t samples, float multiplier);
void add_tests_ARM64_NEON(UnitTestDatabase& database);
Expand All @@ -57,32 +57,32 @@ void add_tests_ARM64_NEON(UnitTestDatabase& database);


template <typename ExternalType>
void convert_from(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples){
void convert_from(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples, float multiplier){
#ifdef PA_AutoDispatch_x64_17_Skylake
if (CPU_CAPABILITY_CURRENT.OK_17_Skylake){
convert_from_x64_AVX512(native, ext, samples);
convert_from_x64_AVX512(native, ext, samples, multiplier);
return;
}
#endif
#ifdef PA_AutoDispatch_x64_13_Haswell
if (CPU_CAPABILITY_CURRENT.OK_13_Haswell){
convert_from_x64_AVX2(native, ext, samples);
convert_from_x64_AVX2(native, ext, samples, multiplier);
return;
}
#endif
#ifdef PA_AutoDispatch_x64_08_Nehalem
if (CPU_CAPABILITY_CURRENT.OK_08_Nehalem){
convert_from_x64_SSE41(native, ext, samples);
convert_from_x64_SSE41(native, ext, samples, multiplier);
return;
}
#endif
#ifdef PA_AutoDispatch_arm64_20_M1
if (CPU_CAPABILITY_CURRENT.OK_M1){
convert_from_ARM64_NEON(native, ext, samples);
convert_from_ARM64_NEON(native, ext, samples, multiplier);
return;
}
#endif
convert_from_Default(native, ext, samples);
convert_from_Default(native, ext, samples, multiplier);
return;
}
template <typename ExternalType>
Expand Down Expand Up @@ -117,9 +117,9 @@ void convert_to(c_ptr<float> native, r_ptr<ExternalType> ext, size_t samples, fl



template void convert_from<uint8_t>(r_ptr<float> native, c_ptr<uint8_t> ext, size_t samples);
template void convert_from<int16_t>(r_ptr<float> native, c_ptr<int16_t> ext, size_t samples);
template void convert_from<int32_t>(r_ptr<float> native, c_ptr<int32_t> ext, size_t samples);
template void convert_from<uint8_t>(r_ptr<float> native, c_ptr<uint8_t> ext, size_t samples, float multiplier);
template void convert_from<int16_t>(r_ptr<float> native, c_ptr<int16_t> ext, size_t samples, float multiplier);
template void convert_from<int32_t>(r_ptr<float> native, c_ptr<int32_t> ext, size_t samples, float multiplier);
template void convert_to<uint8_t>(c_ptr<float> native, r_ptr<uint8_t> ext, size_t samples, float multiplier);
template void convert_to<int16_t>(c_ptr<float> native, r_ptr<int16_t> ext, size_t samples, float multiplier);
template void convert_to<int32_t>(c_ptr<float> native, r_ptr<int32_t> ext, size_t samples, float multiplier);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace AudioStreamConverter{


template <typename ExternalType>
void convert_from(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples);
void convert_from(r_ptr<float> native, c_ptr<ExternalType> ext, size_t samples, float multiplier);
template <typename ExternalType>
void convert_to(c_ptr<float> native, r_ptr<ExternalType> ext, size_t samples, float multiplier);

Expand Down
Loading
Loading