From b924c71822225b6de396b687debb93c1af59e2d6 Mon Sep 17 00:00:00 2001 From: David Marcec Date: Sat, 25 Jul 2020 12:32:05 +1000 Subject: [PATCH] Address issues --- src/audio_core/behavior_info.cpp | 2 +- src/audio_core/command_generator.cpp | 155 +++++++++++++-------------- src/audio_core/command_generator.h | 2 + src/audio_core/effect_context.cpp | 11 +- src/audio_core/effect_context.h | 1 + src/audio_core/mix_context.cpp | 1 + src/audio_core/splitter_context.cpp | 10 +- src/audio_core/voice_context.cpp | 23 ++-- 8 files changed, 104 insertions(+), 101 deletions(-) diff --git a/src/audio_core/behavior_info.cpp b/src/audio_core/behavior_info.cpp index b7cd8f17d8..5d62adb0b1 100644 --- a/src/audio_core/behavior_info.cpp +++ b/src/audio_core/behavior_info.cpp @@ -99,7 +99,7 @@ bool BehaviorInfo::IsSplitterBugFixed() const { void BehaviorInfo::CopyErrorInfo(BehaviorInfo::OutParams& dst) { dst.error_count = static_cast(error_count); - std::memcpy(dst.errors.data(), errors.data(), sizeof(ErrorInfo) * dst.errors.size()); + std::copy(errors.begin(), errors.begin() + error_count, dst.errors.begin()); } } // namespace AudioCore diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp index 722f9b6c5e..440bfc1406 100644 --- a/src/audio_core/command_generator.cpp +++ b/src/audio_core/command_generator.cpp @@ -10,12 +10,12 @@ namespace AudioCore { namespace { -static constexpr std::size_t MIX_BUFFER_SIZE = 0x3f00; -static constexpr std::size_t SCALED_MIX_BUFFER_SIZE = MIX_BUFFER_SIZE << 15ULL; +constexpr std::size_t MIX_BUFFER_SIZE = 0x3f00; +constexpr std::size_t SCALED_MIX_BUFFER_SIZE = MIX_BUFFER_SIZE << 15ULL; template void ApplyMix(s32* output, const s32* input, s32 gain, s32 sample_count) { - for (s32 i = 0; i < sample_count; i += N) { + for (std::size_t i = 0; i < static_cast(sample_count); i += N) { for (std::size_t j = 0; j < N; j++) { output[i + j] += static_cast((static_cast(input[i + j]) * gain + 0x4000) >> 15); @@ -59,13 +59,13 @@ CommandGenerator::CommandGenerator(AudioCommon::AudioRendererParameter& worker_p CommandGenerator::~CommandGenerator() = default; void CommandGenerator::ClearMixBuffers() { - std::memset(mix_buffer.data(), 0, mix_buffer.size() * sizeof(s32)); - std::memset(sample_buffer.data(), 0, sample_buffer.size() * sizeof(s32)); + std::fill(mix_buffer.begin(), mix_buffer.end(), 0); + std::fill(sample_buffer.begin(), sample_buffer.end(), 0); } void CommandGenerator::GenerateVoiceCommands() { if (dumping_frame) { - LOG_CRITICAL(Audio, "(DSP_TRACE) GenerateVoiceCommands"); + LOG_DEBUG(Audio, "(DSP_TRACE) GenerateVoiceCommands"); } // Grab all our voices const auto voice_count = voice_context.GetVoiceCount(); @@ -168,24 +168,26 @@ void CommandGenerator::GenerateFinalMixCommands() { } void CommandGenerator::PreCommand() { - if (dumping_frame) { - for (std::size_t i = 0; i < splitter_context.GetInfoCount(); i++) { - const auto& base = splitter_context.GetInfo(i); - std::string graph = fmt::format("b[{}]", i); - auto* head = base.GetHead(); - while (head != nullptr) { - graph += fmt::format("->{}", head->GetMixId()); - head = head->GetNextDestination(); - } - LOG_CRITICAL(Audio, "(DSP_TRACE) SplitterGraph splitter_info={}, {}", i, graph); + if (!dumping_frame) { + return; + } + for (std::size_t i = 0; i < splitter_context.GetInfoCount(); i++) { + const auto& base = splitter_context.GetInfo(i); + std::string graph = fmt::format("b[{}]", i); + auto* head = base.GetHead(); + while (head != nullptr) { + graph += fmt::format("->{}", head->GetMixId()); + head = head->GetNextDestination(); } + LOG_DEBUG(Audio, "(DSP_TRACE) SplitterGraph splitter_info={}, {}", i, graph); } } void CommandGenerator::PostCommand() { - if (dumping_frame) { - dumping_frame = false; + if (!dumping_frame) { + return; } + dumping_frame = false; } void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, VoiceState& dsp_state, @@ -194,29 +196,31 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo const auto depop = in_params.should_depop; if (in_params.mix_id != AudioCommon::NO_MIX) { - auto& mix_info = mix_context.GetInfo(in_params.mix_id); + [[maybe_unused]] auto& mix_info = mix_context.GetInfo(in_params.mix_id); // mix_info. // TODO(ogniK): Depop to destination mix } else if (in_params.splitter_info_id != AudioCommon::NO_SPLITTER) { // TODO(ogniK): Depop to splitter } - if (!depop) { - switch (in_params.sample_format) { - case SampleFormat::Pcm16: - DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(channel), dsp_state, channel, - worker_params.sample_rate, worker_params.sample_count, - in_params.node_id); - break; - case SampleFormat::Adpcm: - ASSERT(channel == 0 && in_params.channel_count == 1); - DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(0), dsp_state, 0, - worker_params.sample_rate, worker_params.sample_count, - in_params.node_id); - break; - default: - UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format); - } + if (depop) { + return; + } + + switch (in_params.sample_format) { + case SampleFormat::Pcm16: + DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(channel), dsp_state, channel, + worker_params.sample_rate, worker_params.sample_count, + in_params.node_id); + break; + case SampleFormat::Adpcm: + ASSERT(channel == 0 && in_params.channel_count == 1); + DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(0), dsp_state, 0, + worker_params.sample_rate, worker_params.sample_count, + in_params.node_id); + break; + default: + UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format); } } @@ -233,8 +237,7 @@ void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voic // Reinitialize our biquad filter state if it was enabled previously if (!in_params.was_biquad_filter_enabled[i]) { - std::memset(dsp_state.biquad_filter_state.data(), 0, - dsp_state.biquad_filter_state.size() * sizeof(s64)); + dsp_state.biquad_filter_state.fill(0); } // Generate biquad filter @@ -248,39 +251,34 @@ void AudioCore::CommandGenerator::GenerateBiquadFilterCommand( s32 mix_buffer, const BiquadFilterParameter& params, std::array& state, std::size_t input_offset, std::size_t output_offset, s32 sample_count, s32 node_id) { if (dumping_frame) { - LOG_CRITICAL(Audio, - "(DSP_TRACE) GenerateBiquadFilterCommand node_id={}, " - "input_mix_buffer={}, output_mix_buffer={}", - node_id, input_offset, output_offset); + LOG_DEBUG(Audio, + "(DSP_TRACE) GenerateBiquadFilterCommand node_id={}, " + "input_mix_buffer={}, output_mix_buffer={}", + node_id, input_offset, output_offset); } const auto* input = GetMixBuffer(input_offset); auto* output = GetMixBuffer(output_offset); // Biquad filter parameters - const auto n0 = params.numerator[0]; - const auto n1 = params.numerator[1]; - const auto n2 = params.numerator[2]; - const auto d0 = params.denominator[0]; - const auto d1 = params.denominator[1]; + const auto [n0, n1, n2] = params.numerator; + const auto [d0, d1] = params.denominator; // Biquad filter states - auto s0 = state[0]; - auto s1 = state[1]; + auto [s0, s1] = state; - constexpr s64 MIN = std::numeric_limits::min(); - constexpr s64 MAX = std::numeric_limits::max(); + constexpr s64 int32_min = std::numeric_limits::min(); + constexpr s64 int32_max = std::numeric_limits::max(); for (int i = 0; i < sample_count; ++i) { - const auto sample = static_cast(input[i]); + const auto sample = static_cast(input[i]); const auto f = (sample * n0 + s0 + 0x4000) >> 15; - const auto y = std::clamp(f, MIN, MAX); + const auto y = std::clamp(f, int32_min, int32_max); s0 = sample * n1 + y * d0 + s1; s1 = sample * n2 + y * d1; output[i] = static_cast(y); } - state[0] = s0; - state[1] = s1; + state = {s0, s1}; } ServerSplitterDestinationData* CommandGenerator::GetDestinationData(s32 splitter_id, s32 index) { @@ -298,11 +296,11 @@ void CommandGenerator::GenerateVolumeRampCommand(float last_volume, float curren static_cast(worker_params.sample_count)); if (dumping_frame) { - LOG_CRITICAL(Audio, - "(DSP_TRACE) GenerateVolumeRampCommand node_id={}, input={}, output={}, " - "last_volume={}, current_volume={}", - node_id, GetMixChannelBufferOffset(channel), - GetMixChannelBufferOffset(channel), last_volume, current_volume); + LOG_DEBUG(Audio, + "(DSP_TRACE) GenerateVolumeRampCommand node_id={}, input={}, output={}, " + "last_volume={}, current_volume={}", + node_id, GetMixChannelBufferOffset(channel), GetMixChannelBufferOffset(channel), + last_volume, current_volume); } // Apply generic gain on samples ApplyGain(GetChannelMixBuffer(channel), GetChannelMixBuffer(channel), last, delta, @@ -320,11 +318,11 @@ void CommandGenerator::GenerateVoiceMixCommand(const MixVolumeBuffer& mix_volume static_cast(worker_params.sample_count); if (dumping_frame) { - LOG_CRITICAL(Audio, - "(DSP_TRACE) GenerateVoiceMixCommand node_id={}, input={}, " - "output={}, last_volume={}, current_volume={}", - node_id, voice_index, mix_buffer_offset + i, last_mix_volumes[i], - mix_volumes[i]); + LOG_DEBUG(Audio, + "(DSP_TRACE) GenerateVoiceMixCommand node_id={}, input={}, " + "output={}, last_volume={}, current_volume={}", + node_id, voice_index, mix_buffer_offset + i, last_mix_volumes[i], + mix_volumes[i]); } dsp_state.previous_samples[i] = @@ -338,7 +336,7 @@ void CommandGenerator::GenerateVoiceMixCommand(const MixVolumeBuffer& mix_volume void CommandGenerator::GenerateSubMixCommand(ServerMixInfo& mix_info) { if (dumping_frame) { - LOG_CRITICAL(Audio, "(DSP_TRACE) GenerateSubMixCommand"); + LOG_DEBUG(Audio, "(DSP_TRACE) GenerateSubMixCommand"); } // TODO(ogniK): Depop // TODO(ogniK): Effects @@ -391,9 +389,9 @@ void CommandGenerator::GenerateMixCommand(std::size_t output_offset, std::size_t float volume, s32 node_id) { if (dumping_frame) { - LOG_CRITICAL(Audio, - "(DSP_TRACE) GenerateMixCommand node_id={}, input={}, output={}, volume={}", - node_id, input_offset, output_offset, volume); + LOG_DEBUG(Audio, + "(DSP_TRACE) GenerateMixCommand node_id={}, input={}, output={}, volume={}", + node_id, input_offset, output_offset, volume); } auto* output = GetMixBuffer(output_offset); @@ -412,7 +410,7 @@ void CommandGenerator::GenerateMixCommand(std::size_t output_offset, std::size_t void CommandGenerator::GenerateFinalMixCommand() { if (dumping_frame) { - LOG_CRITICAL(Audio, "(DSP_TRACE) GenerateFinalMixCommand"); + LOG_DEBUG(Audio, "(DSP_TRACE) GenerateFinalMixCommand"); } // TODO(ogniK): Depop // TODO(ogniK): Effects @@ -421,7 +419,7 @@ void CommandGenerator::GenerateFinalMixCommand() { for (s32 i = 0; i < in_params.buffer_count; i++) { const s32 gain = static_cast(in_params.volume * 32768.0f); if (dumping_frame) { - LOG_CRITICAL( + LOG_DEBUG( Audio, "(DSP_TRACE) ApplyGainWithoutDelta node_id={}, input={}, output={}, volume={}", in_params.node_id, in_params.buffer_offset + i, in_params.buffer_offset + i, @@ -544,11 +542,11 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o s32 node_id) { auto& in_params = voice_info.GetInParams(); if (dumping_frame) { - LOG_CRITICAL(Audio, - "(DSP_TRACE) DecodeFromWaveBuffers, node_id={}, channel={}, " - "format={}, sample_count={}, sample_rate={}, mix_id={}, splitter_id={}", - node_id, channel, in_params.sample_format, sample_count, in_params.sample_rate, - in_params.mix_id, in_params.splitter_info_id); + LOG_DEBUG(Audio, + "(DSP_TRACE) DecodeFromWaveBuffers, node_id={}, channel={}, " + "format={}, sample_count={}, sample_rate={}, mix_id={}, splitter_id={}", + node_id, channel, in_params.sample_format, sample_count, in_params.sample_rate, + in_params.mix_id, in_params.splitter_info_id); } ASSERT_OR_EXECUTE(output != nullptr, { return; }); @@ -649,10 +647,11 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o if (in_params.behavior_flags.is_pitch_and_src_skipped.Value()) { // No need to resample - memcpy(output, sample_buffer.data(), samples_read * sizeof(s32)); + std::memcpy(output, sample_buffer.data(), samples_read * sizeof(s32)); } else { - std::memset(sample_buffer.data() + temp_mix_offset, 0, - sizeof(s32) * (samples_to_read - samples_read)); + std::fill(sample_buffer.begin() + temp_mix_offset, + sample_buffer.begin() + temp_mix_offset + (samples_to_read - samples_read), + 0); AudioCore::Resample(output, sample_buffer.data(), resample_rate, dsp_state.fraction, samples_to_output); // Resample diff --git a/src/audio_core/command_generator.h b/src/audio_core/command_generator.h index e0d7510fc1..3ad8973b5b 100644 --- a/src/audio_core/command_generator.h +++ b/src/audio_core/command_generator.h @@ -19,7 +19,9 @@ class MixContext; class SplitterContext; class ServerSplitterDestinationData; class ServerMixInfo; + using MixVolumeBuffer = std::array; + class CommandGenerator { public: explicit CommandGenerator(AudioCommon::AudioRendererParameter& worker_params, diff --git a/src/audio_core/effect_context.cpp b/src/audio_core/effect_context.cpp index c42e71c1c7..2497d2f323 100644 --- a/src/audio_core/effect_context.cpp +++ b/src/audio_core/effect_context.cpp @@ -2,13 +2,14 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include "audio_core/effect_context.h" namespace AudioCore { EffectContext::EffectContext(std::size_t effect_count) : effect_count(effect_count) { - for (std::size_t i = 0; i < effect_count; i++) { - effects.push_back(std::make_unique()); - } + effects.reserve(effect_count); + std::generate_n(std::back_inserter(effects), effect_count, + [] { return std::make_unique(); }); } EffectContext::~EffectContext() = default; @@ -20,6 +21,10 @@ EffectBase* EffectContext::GetInfo(std::size_t i) { return effects.at(i).get(); } +const EffectBase* EffectContext::GetInfo(std::size_t i) const { + return effects.at(i).get(); +} + EffectStubbed::EffectStubbed() : EffectBase::EffectBase() {} EffectStubbed::~EffectStubbed() = default; diff --git a/src/audio_core/effect_context.h b/src/audio_core/effect_context.h index 09aedf385a..e3c3672966 100644 --- a/src/audio_core/effect_context.h +++ b/src/audio_core/effect_context.h @@ -106,6 +106,7 @@ public: std::size_t GetCount() const; EffectBase* GetInfo(std::size_t i); + const EffectBase* GetInfo(std::size_t i) const; private: std::size_t effect_count{}; diff --git a/src/audio_core/mix_context.cpp b/src/audio_core/mix_context.cpp index 8e150db03b..f6f119a113 100644 --- a/src/audio_core/mix_context.cpp +++ b/src/audio_core/mix_context.cpp @@ -16,6 +16,7 @@ void MixContext::Initialize(const BehaviorInfo& behavior_info, std::size_t mix_c infos.resize(info_count); auto& final_mix = GetInfo(AudioCommon::FINAL_MIX); final_mix.GetInParams().mix_id = AudioCommon::FINAL_MIX; + sorted_info.reserve(infos.size()); for (auto& info : infos) { sorted_info.push_back(&info); } diff --git a/src/audio_core/splitter_context.cpp b/src/audio_core/splitter_context.cpp index c0be26be12..79bb2f516d 100644 --- a/src/audio_core/splitter_context.cpp +++ b/src/audio_core/splitter_context.cpp @@ -173,7 +173,7 @@ void SplitterContext::Initialize(BehaviorInfo& behavior_info, std::size_t _info_ bool SplitterContext::Update(const std::vector& input, std::size_t& input_offset, std::size_t& bytes_read) { - auto UpdateOffsets = [&](std::size_t read) { + const auto UpdateOffsets = [&](std::size_t read) { input_offset += read; bytes_read += read; }; @@ -286,7 +286,7 @@ void SplitterContext::Setup(std::size_t _info_count, std::size_t _data_count, bool SplitterContext::UpdateInfo(const std::vector& input, std::size_t& input_offset, std::size_t& bytes_read, s32 in_splitter_count) { - auto UpdateOffsets = [&](std::size_t read) { + const auto UpdateOffsets = [&](std::size_t read) { input_offset += read; bytes_read += read; }; @@ -326,7 +326,7 @@ bool SplitterContext::UpdateInfo(const std::vector& input, std::size_t& inpu bool SplitterContext::UpdateData(const std::vector& input, std::size_t& input_offset, std::size_t& bytes_read, s32 in_data_count) { - auto UpdateOffsets = [&](std::size_t read) { + const auto UpdateOffsets = [&](std::size_t read) { input_offset += read; bytes_read += read; }; @@ -412,9 +412,9 @@ bool SplitterContext::RecomposeDestination(ServerSplitterInfo& info, NodeStates::NodeStates() = default; NodeStates::~NodeStates() = default; -void NodeStates::Initialize(std::size_t _node_count) { +void NodeStates::Initialize(std::size_t node_count_) { // Setup our work parameters - node_count = _node_count; + node_count = node_count_; was_node_found.resize(node_count); was_node_completed.resize(node_count); index_list.resize(node_count); diff --git a/src/audio_core/voice_context.cpp b/src/audio_core/voice_context.cpp index 038595ae04..1d8f69844f 100644 --- a/src/audio_core/voice_context.cpp +++ b/src/audio_core/voice_context.cpp @@ -29,12 +29,12 @@ void ServerVoiceChannelResource::Update(VoiceChannelResource::InParams& in_param in_use = in_params.in_use; // Update our mix volumes only if it's in use if (in_params.in_use) { - std::copy(in_params.mix_volume.begin(), in_params.mix_volume.end(), mix_volume.begin()); + mix_volume = in_params.mix_volume; } } void ServerVoiceChannelResource::UpdateLastMixVolumes() { - std::copy(mix_volume.begin(), mix_volume.end(), last_mix_volume.begin()); + last_mix_volume = mix_volume; } const std::array& @@ -64,8 +64,7 @@ void ServerVoiceInfo::Initialize() { in_params.pitch = 0.0f; in_params.volume = 0.0f; in_params.last_volume = 0.0f; - std::memset(in_params.biquad_filter.data(), 0, - sizeof(BiquadFilterParameter) * in_params.biquad_filter.size()); + in_params.biquad_filter.fill({}); in_params.wave_buffer_count = 0; in_params.wave_bufffer_head = 0; in_params.mix_id = AudioCommon::NO_MIX; @@ -78,8 +77,7 @@ void ServerVoiceInfo::Initialize() { in_params.voice_drop_flag = false; in_params.buffer_mapped = false; in_params.wave_buffer_flush_request_count = 0; - std::fill(in_params.was_biquad_filter_enabled.begin(), - in_params.was_biquad_filter_enabled.end(), false); + in_params.was_biquad_filter_enabled.fill(false); for (auto& wave_buffer : in_params.wave_buffer) { wave_buffer.start_sample_offset = 0; @@ -126,8 +124,7 @@ void ServerVoiceInfo::UpdateParameters(const VoiceInfo::InParams& voice_in, in_params.channel_count = voice_in.channel_count; in_params.pitch = voice_in.pitch; in_params.volume = voice_in.volume; - std::memcpy(in_params.biquad_filter.data(), voice_in.biquad_filter.data(), - sizeof(BiquadFilterParameter) * voice_in.biquad_filter.size()); + in_params.biquad_filter = voice_in.biquad_filter; in_params.wave_buffer_count = voice_in.wave_buffer_count; in_params.wave_bufffer_head = voice_in.wave_buffer_head; if (behavior_info.IsFlushVoiceWaveBuffersSupported()) { @@ -308,7 +305,7 @@ void ServerVoiceInfo::ResetResources(VoiceContext& voice_context) { const auto channel_resource = in_params.voice_channel_resource_id[i]; auto& dsp_state = voice_context.GetDspSharedState(static_cast(channel_resource)); - std::memset(&dsp_state, 0, sizeof(VoiceState)); + dsp_state = {}; voice_context.GetChannelResource(static_cast(channel_resource)) .UpdateLastMixVolumes(); } @@ -362,9 +359,8 @@ bool ServerVoiceInfo::UpdateParametersForCommandGeneration( dsp_state->offset = 0; dsp_state->played_sample_count = 0; dsp_state->fraction = 0; - std::memset(dsp_state->sample_history.data(), 0, - sizeof(s32) * dsp_state->sample_history.size()); - std::memset(&dsp_state->context, 0, sizeof(dsp_state->context)); + dsp_state->sample_history.fill(0); + dsp_state->context = {}; } in_params.current_playstate = ServerPlayState::Stop; @@ -524,8 +520,7 @@ void VoiceContext::SortInfo() { } void VoiceContext::UpdateStateByDspShared() { - std::memcpy(voice_states.data(), dsp_voice_states.data(), - sizeof(VoiceState) * dsp_voice_states.size()); + voice_states = dsp_voice_states; } } // namespace AudioCore