diff options
Diffstat (limited to 'src/audio_core')
33 files changed, 431 insertions, 313 deletions
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index cb00ef60e..d1d177b51 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -44,6 +44,24 @@ add_library(audio_core STATIC create_target_directory_groups(audio_core) +if (NOT MSVC) + target_compile_options(audio_core PRIVATE + -Werror=conversion + -Werror=ignored-qualifiers + -Werror=implicit-fallthrough + -Werror=reorder + -Werror=sign-compare + -Werror=shadow + -Werror=unused-parameter + -Werror=unused-variable + + $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> + $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> + + -Wno-sign-conversion + ) +endif() + target_link_libraries(audio_core PUBLIC common core) target_link_libraries(audio_core PRIVATE SoundTouch) diff --git a/src/audio_core/algorithm/filter.cpp b/src/audio_core/algorithm/filter.cpp index f65bf64f7..01b8dff6b 100644 --- a/src/audio_core/algorithm/filter.cpp +++ b/src/audio_core/algorithm/filter.cpp @@ -31,8 +31,8 @@ Filter Filter::LowPass(double cutoff, double Q) { Filter::Filter() : Filter(1.0, 0.0, 0.0, 1.0, 0.0, 0.0) {} -Filter::Filter(double a0, double a1, double a2, double b0, double b1, double b2) - : a1(a1 / a0), a2(a2 / a0), b0(b0 / a0), b1(b1 / a0), b2(b2 / a0) {} +Filter::Filter(double a0_, double a1_, double a2_, double b0_, double b1_, double b2_) + : a1(a1_ / a0_), a2(a2_ / a0_), b0(b0_ / a0_), b1(b1_ / a0_), b2(b2_ / a0_) {} void Filter::Process(std::vector<s16>& signal) { const std::size_t num_frames = signal.size() / 2; @@ -55,7 +55,8 @@ void Filter::Process(std::vector<s16>& signal) { /// @param total_count The total number of biquads to be cascaded. /// @param index 0-index of the biquad to calculate the Q value for. static double CascadingBiquadQ(std::size_t total_count, std::size_t index) { - const double pole = M_PI * (2 * index + 1) / (4.0 * total_count); + const auto pole = + M_PI * static_cast<double>(2 * index + 1) / (4.0 * static_cast<double>(total_count)); return 1.0 / (2.0 * std::cos(pole)); } @@ -68,7 +69,7 @@ CascadingFilter CascadingFilter::LowPass(double cutoff, std::size_t cascade_size } CascadingFilter::CascadingFilter() = default; -CascadingFilter::CascadingFilter(std::vector<Filter> filters) : filters(std::move(filters)) {} +CascadingFilter::CascadingFilter(std::vector<Filter> filters_) : filters(std::move(filters_)) {} void CascadingFilter::Process(std::vector<s16>& signal) { for (auto& filter : filters) { diff --git a/src/audio_core/algorithm/filter.h b/src/audio_core/algorithm/filter.h index 3546d149b..a291fe79b 100644 --- a/src/audio_core/algorithm/filter.h +++ b/src/audio_core/algorithm/filter.h @@ -25,7 +25,7 @@ public: /// Passthrough filter. Filter(); - Filter(double a0, double a1, double a2, double b0, double b1, double b2); + Filter(double a0_, double a1_, double a2_, double b0_, double b1_, double b2_); void Process(std::vector<s16>& signal); @@ -51,7 +51,7 @@ public: /// Passthrough. CascadingFilter(); - explicit CascadingFilter(std::vector<Filter> filters); + explicit CascadingFilter(std::vector<Filter> filters_); void Process(std::vector<s16>& signal); diff --git a/src/audio_core/algorithm/interpolate.cpp b/src/audio_core/algorithm/interpolate.cpp index 689a54508..3b4144e21 100644 --- a/src/audio_core/algorithm/interpolate.cpp +++ b/src/audio_core/algorithm/interpolate.cpp @@ -146,7 +146,7 @@ std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input, return {}; if (ratio <= 0) { - LOG_CRITICAL(Audio, "Nonsensical interpolation ratio {}", ratio); + LOG_ERROR(Audio, "Nonsensical interpolation ratio {}", ratio); return input; } @@ -164,7 +164,8 @@ std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input, const std::size_t num_frames{input.size() / 2}; std::vector<s16> output; - output.reserve(static_cast<std::size_t>(input.size() / ratio + InterpolationState::taps)); + output.reserve(static_cast<std::size_t>(static_cast<double>(input.size()) / ratio + + InterpolationState::taps)); for (std::size_t frame{}; frame < num_frames; ++frame) { const std::size_t lut_index{(state.fraction >> 8) * InterpolationState::taps}; @@ -217,7 +218,7 @@ void Resample(s32* output, const s32* input, s32 pitch, s32& fraction, std::size const auto l2 = lut[lut_index + 2]; const auto l3 = lut[lut_index + 3]; - const auto s0 = static_cast<s32>(input[index]); + const auto s0 = static_cast<s32>(input[index + 0]); const auto s1 = static_cast<s32>(input[index + 1]); const auto s2 = static_cast<s32>(input[index + 2]); const auto s3 = static_cast<s32>(input[index + 3]); diff --git a/src/audio_core/audio_out.cpp b/src/audio_core/audio_out.cpp index 8619a3f03..fe3a898ad 100644 --- a/src/audio_core/audio_out.cpp +++ b/src/audio_core/audio_out.cpp @@ -43,6 +43,10 @@ std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream, return stream->GetTagsAndReleaseBuffers(max_count); } +std::vector<Buffer::Tag> AudioOut::GetTagsAndReleaseBuffers(StreamPtr stream) { + return stream->GetTagsAndReleaseBuffers(); +} + void AudioOut::StartStream(StreamPtr stream) { stream->Play(); } diff --git a/src/audio_core/audio_out.h b/src/audio_core/audio_out.h index b07588287..6ce08cd0d 100644 --- a/src/audio_core/audio_out.h +++ b/src/audio_core/audio_out.h @@ -31,6 +31,9 @@ public: /// Returns a vector of recently released buffers specified by tag for the specified stream std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(StreamPtr stream, std::size_t max_count); + /// Returns a vector of all recently released buffers specified by tag for the specified stream + std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(StreamPtr stream); + /// Starts an audio stream for playback void StartStream(StreamPtr stream); diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 56dc892b1..d2ce8c814 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp @@ -2,43 +2,90 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <limits> #include <vector> -#include "audio_core/algorithm/interpolate.h" + #include "audio_core/audio_out.h" #include "audio_core/audio_renderer.h" -#include "audio_core/codec.h" #include "audio_core/common.h" #include "audio_core/info_updater.h" #include "audio_core/voice_context.h" -#include "common/assert.h" #include "common/logging/log.h" -#include "core/core.h" -#include "core/hle/kernel/writable_event.h" #include "core/memory.h" #include "core/settings.h" +namespace { +[[nodiscard]] static constexpr s16 ClampToS16(s32 value) { + return static_cast<s16>(std::clamp(value, s32{std::numeric_limits<s16>::min()}, + s32{std::numeric_limits<s16>::max()})); +} + +[[nodiscard]] static constexpr s16 Mix2To1(s16 l_channel, s16 r_channel) { + // Mix 50% from left and 50% from right channel + constexpr float l_mix_amount = 50.0f / 100.0f; + constexpr float r_mix_amount = 50.0f / 100.0f; + return ClampToS16(static_cast<s32>((static_cast<float>(l_channel) * l_mix_amount) + + (static_cast<float>(r_channel) * r_mix_amount))); +} + +[[nodiscard]] static constexpr std::tuple<s16, s16> Mix6To2(s16 fl_channel, s16 fr_channel, + s16 fc_channel, + [[maybe_unused]] s16 lf_channel, + s16 bl_channel, s16 br_channel) { + // Front channels are mixed 36.94%, Center channels are mixed to be 26.12% & the back channels + // are mixed to be 36.94% + + constexpr float front_mix_amount = 36.94f / 100.0f; + constexpr float center_mix_amount = 26.12f / 100.0f; + constexpr float back_mix_amount = 36.94f / 100.0f; + + // Mix 50% from left and 50% from right channel + const auto left = front_mix_amount * static_cast<float>(fl_channel) + + center_mix_amount * static_cast<float>(fc_channel) + + back_mix_amount * static_cast<float>(bl_channel); + + const auto right = front_mix_amount * static_cast<float>(fr_channel) + + center_mix_amount * static_cast<float>(fc_channel) + + back_mix_amount * static_cast<float>(br_channel); + + return {ClampToS16(static_cast<s32>(left)), ClampToS16(static_cast<s32>(right))}; +} + +[[nodiscard]] static constexpr std::tuple<s16, s16> Mix6To2WithCoefficients( + s16 fl_channel, s16 fr_channel, s16 fc_channel, s16 lf_channel, s16 bl_channel, s16 br_channel, + const std::array<float_le, 4>& coeff) { + const auto left = + static_cast<float>(fl_channel) * coeff[0] + static_cast<float>(fc_channel) * coeff[1] + + static_cast<float>(lf_channel) * coeff[2] + static_cast<float>(bl_channel) * coeff[0]; + + const auto right = + static_cast<float>(fr_channel) * coeff[0] + static_cast<float>(fc_channel) * coeff[1] + + static_cast<float>(lf_channel) * coeff[2] + static_cast<float>(br_channel) * coeff[0]; + + return {ClampToS16(static_cast<s32>(left)), ClampToS16(static_cast<s32>(right))}; +} + +} // namespace + namespace AudioCore { AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_, AudioCommon::AudioRendererParameter params, - std::shared_ptr<Kernel::WritableEvent> buffer_event, + Stream::ReleaseCallback&& release_callback, std::size_t instance_number) - : worker_params{params}, buffer_event{buffer_event}, - memory_pool_info(params.effect_count + params.voice_count * 4), + : worker_params{params}, memory_pool_info(params.effect_count + params.voice_count * 4), voice_context(params.voice_count), effect_context(params.effect_count), mix_context(), sink_context(params.sink_count), splitter_context(), voices(params.voice_count), memory{memory_}, command_generator(worker_params, voice_context, mix_context, splitter_context, effect_context, - memory), - temp_mix_buffer(AudioCommon::TOTAL_TEMP_MIX_SIZE) { + memory) { behavior_info.SetUserRevision(params.revision); splitter_context.Initialize(behavior_info, params.splitter_count, params.num_splitter_send_channels); mix_context.Initialize(behavior_info, params.submix_count + 1, params.effect_count); audio_out = std::make_unique<AudioCore::AudioOut>(); - stream = - audio_out->OpenStream(core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS, - fmt::format("AudioRenderer-Instance{}", instance_number), - [=]() { buffer_event->Signal(); }); + stream = audio_out->OpenStream( + core_timing, params.sample_rate, AudioCommon::STREAM_NUM_CHANNELS, + fmt::format("AudioRenderer-Instance{}", instance_number), std::move(release_callback)); audio_out->StartStream(stream); QueueMixedBuffer(0); @@ -65,10 +112,6 @@ Stream::State AudioRenderer::GetStreamState() const { return stream->GetState(); } -static constexpr s16 ClampToS16(s32 value) { - return static_cast<s16>(std::clamp(value, -32768, 32767)); -} - ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_params, std::vector<u8>& output_params) { @@ -107,8 +150,8 @@ ResultCode AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_param } } - auto mix_result = info_updater.UpdateMixes(mix_context, worker_params.mix_buffer_count, - splitter_context, effect_context); + const auto mix_result = info_updater.UpdateMixes(mix_context, worker_params.mix_buffer_count, + splitter_context, effect_context); if (mix_result.IsError()) { LOG_ERROR(Audio, "Failed to update mix parameters"); @@ -197,20 +240,22 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { for (std::size_t i = 0; i < BUFFER_SIZE; i++) { if (channel_count == 1) { const auto sample = ClampToS16(mix_buffers[0][i]); - buffer[i * stream_channel_count + 0] = sample; - if (stream_channel_count > 1) { - buffer[i * stream_channel_count + 1] = sample; + + // Place sample in all channels + for (u32 channel = 0; channel < stream_channel_count; channel++) { + buffer[i * stream_channel_count + channel] = sample; } + if (stream_channel_count == 6) { - buffer[i * stream_channel_count + 2] = sample; - buffer[i * stream_channel_count + 4] = sample; - buffer[i * stream_channel_count + 5] = sample; + // Output stream has a LF channel, mute it! + buffer[i * stream_channel_count + 3] = 0; } + } else if (channel_count == 2) { const auto l_sample = ClampToS16(mix_buffers[0][i]); const auto r_sample = ClampToS16(mix_buffers[1][i]); if (stream_channel_count == 1) { - buffer[i * stream_channel_count + 0] = l_sample; + buffer[i * stream_channel_count + 0] = Mix2To1(l_sample, r_sample); } else if (stream_channel_count == 2) { buffer[i * stream_channel_count + 0] = l_sample; buffer[i * stream_channel_count + 1] = r_sample; @@ -218,8 +263,8 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { buffer[i * stream_channel_count + 0] = l_sample; buffer[i * stream_channel_count + 1] = r_sample; - buffer[i * stream_channel_count + 2] = - ClampToS16((static_cast<s32>(l_sample) + static_cast<s32>(r_sample)) / 2); + // Combine both left and right channels to the center channel + buffer[i * stream_channel_count + 2] = Mix2To1(l_sample, r_sample); buffer[i * stream_channel_count + 4] = l_sample; buffer[i * stream_channel_count + 5] = r_sample; @@ -234,17 +279,25 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { const auto br_sample = ClampToS16(mix_buffers[5][i]); if (stream_channel_count == 1) { - buffer[i * stream_channel_count + 0] = fc_sample; + // Games seem to ignore the center channel half the time, we use the front left + // and right channel for mixing as that's where majority of the audio goes + buffer[i * stream_channel_count + 0] = Mix2To1(fl_sample, fr_sample); } else if (stream_channel_count == 2) { - buffer[i * stream_channel_count + 0] = - static_cast<s16>(0.3694f * static_cast<float>(fl_sample) + - 0.2612f * static_cast<float>(fc_sample) + - 0.3694f * static_cast<float>(bl_sample)); - buffer[i * stream_channel_count + 1] = - static_cast<s16>(0.3694f * static_cast<float>(fr_sample) + - 0.2612f * static_cast<float>(fc_sample) + - 0.3694f * static_cast<float>(br_sample)); + // Mix all channels into 2 channels + if (sink_context.HasDownMixingCoefficients()) { + const auto [left, right] = Mix6To2WithCoefficients( + fl_sample, fr_sample, fc_sample, lf_sample, bl_sample, br_sample, + sink_context.GetDownmixCoefficients()); + buffer[i * stream_channel_count + 0] = left; + buffer[i * stream_channel_count + 1] = right; + } else { + const auto [left, right] = Mix6To2(fl_sample, fr_sample, fc_sample, + lf_sample, bl_sample, br_sample); + buffer[i * stream_channel_count + 0] = left; + buffer[i * stream_channel_count + 1] = right; + } } else if (stream_channel_count == 6) { + // Pass through buffer[i * stream_channel_count + 0] = fl_sample; buffer[i * stream_channel_count + 1] = fr_sample; buffer[i * stream_channel_count + 2] = fc_sample; @@ -262,7 +315,7 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) { } void AudioRenderer::ReleaseAndQueueBuffers() { - const auto released_buffers{audio_out->GetTagsAndReleaseBuffers(stream, 2)}; + const auto released_buffers{audio_out->GetTagsAndReleaseBuffers(stream)}; for (const auto& tag : released_buffers) { QueueMixedBuffer(tag); } diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h index 2bca795ba..18567f618 100644 --- a/src/audio_core/audio_renderer.h +++ b/src/audio_core/audio_renderer.h @@ -21,53 +21,41 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" -#include "core/hle/kernel/object.h" #include "core/hle/result.h" namespace Core::Timing { class CoreTiming; } -namespace Kernel { -class WritableEvent; -} - namespace Core::Memory { class Memory; } namespace AudioCore { -using DSPStateHolder = std::array<VoiceState*, 6>; +using DSPStateHolder = std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT>; class AudioOut; -struct RendererInfo { - u64_le elasped_frame_count{}; - INSERT_PADDING_WORDS(2); -}; -static_assert(sizeof(RendererInfo) == 0x10, "RendererInfo is an invalid size"); - class AudioRenderer { public: AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_, AudioCommon::AudioRendererParameter params, - std::shared_ptr<Kernel::WritableEvent> buffer_event, std::size_t instance_number); + Stream::ReleaseCallback&& release_callback, std::size_t instance_number); ~AudioRenderer(); - ResultCode UpdateAudioRenderer(const std::vector<u8>& input_params, - std::vector<u8>& output_params); + [[nodiscard]] ResultCode UpdateAudioRenderer(const std::vector<u8>& input_params, + std::vector<u8>& output_params); void QueueMixedBuffer(Buffer::Tag tag); void ReleaseAndQueueBuffers(); - u32 GetSampleRate() const; - u32 GetSampleCount() const; - u32 GetMixBufferCount() const; - Stream::State GetStreamState() const; + [[nodiscard]] u32 GetSampleRate() const; + [[nodiscard]] u32 GetSampleCount() const; + [[nodiscard]] u32 GetMixBufferCount() const; + [[nodiscard]] Stream::State GetStreamState() const; private: BehaviorInfo behavior_info{}; AudioCommon::AudioRendererParameter worker_params; - std::shared_ptr<Kernel::WritableEvent> buffer_event; std::vector<ServerMemoryPoolInfo> memory_pool_info; VoiceContext voice_context; EffectContext effect_context; @@ -80,7 +68,6 @@ private: Core::Memory::Memory& memory; CommandGenerator command_generator; std::size_t elapsed_frame_count{}; - std::vector<s32> temp_mix_buffer{}; }; } // namespace AudioCore diff --git a/src/audio_core/behavior_info.cpp b/src/audio_core/behavior_info.cpp index 5d62adb0b..3c2e3e6f1 100644 --- a/src/audio_core/behavior_info.cpp +++ b/src/audio_core/behavior_info.cpp @@ -57,15 +57,15 @@ bool BehaviorInfo::IsLongSizePreDelaySupported() const { return AudioCommon::IsRevisionSupported(3, user_revision); } -bool BehaviorInfo::IsAudioRenererProcessingTimeLimit80PercentSupported() const { +bool BehaviorInfo::IsAudioRendererProcessingTimeLimit80PercentSupported() const { return AudioCommon::IsRevisionSupported(5, user_revision); } -bool BehaviorInfo::IsAudioRenererProcessingTimeLimit75PercentSupported() const { +bool BehaviorInfo::IsAudioRendererProcessingTimeLimit75PercentSupported() const { return AudioCommon::IsRevisionSupported(4, user_revision); } -bool BehaviorInfo::IsAudioRenererProcessingTimeLimit70PercentSupported() const { +bool BehaviorInfo::IsAudioRendererProcessingTimeLimit70PercentSupported() const { return AudioCommon::IsRevisionSupported(1, user_revision); } diff --git a/src/audio_core/behavior_info.h b/src/audio_core/behavior_info.h index 50948e8df..5a96bf75e 100644 --- a/src/audio_core/behavior_info.h +++ b/src/audio_core/behavior_info.h @@ -43,22 +43,22 @@ public: void ClearError(); void UpdateFlags(u64_le dest_flags); void SetUserRevision(u32_le revision); - u32_le GetUserRevision() const; - u32_le GetProcessRevision() const; + [[nodiscard]] u32_le GetUserRevision() const; + [[nodiscard]] u32_le GetProcessRevision() const; - bool IsAdpcmLoopContextBugFixed() const; - bool IsSplitterSupported() const; - bool IsLongSizePreDelaySupported() const; - bool IsAudioRenererProcessingTimeLimit80PercentSupported() const; - bool IsAudioRenererProcessingTimeLimit75PercentSupported() const; - bool IsAudioRenererProcessingTimeLimit70PercentSupported() const; - bool IsElapsedFrameCountSupported() const; - bool IsMemoryPoolForceMappingEnabled() const; - bool IsFlushVoiceWaveBuffersSupported() const; - bool IsVoicePlayedSampleCountResetAtLoopPointSupported() const; - bool IsVoicePitchAndSrcSkippedSupported() const; - bool IsMixInParameterDirtyOnlyUpdateSupported() const; - bool IsSplitterBugFixed() const; + [[nodiscard]] bool IsAdpcmLoopContextBugFixed() const; + [[nodiscard]] bool IsSplitterSupported() const; + [[nodiscard]] bool IsLongSizePreDelaySupported() const; + [[nodiscard]] bool IsAudioRendererProcessingTimeLimit80PercentSupported() const; + [[nodiscard]] bool IsAudioRendererProcessingTimeLimit75PercentSupported() const; + [[nodiscard]] bool IsAudioRendererProcessingTimeLimit70PercentSupported() const; + [[nodiscard]] bool IsElapsedFrameCountSupported() const; + [[nodiscard]] bool IsMemoryPoolForceMappingEnabled() const; + [[nodiscard]] bool IsFlushVoiceWaveBuffersSupported() const; + [[nodiscard]] bool IsVoicePlayedSampleCountResetAtLoopPointSupported() const; + [[nodiscard]] bool IsVoicePitchAndSrcSkippedSupported() const; + [[nodiscard]] bool IsMixInParameterDirtyOnlyUpdateSupported() const; + [[nodiscard]] bool IsSplitterBugFixed() const; void CopyErrorInfo(OutParams& dst); private: diff --git a/src/audio_core/buffer.h b/src/audio_core/buffer.h index 5ee09e9aa..ccc46ef82 100644 --- a/src/audio_core/buffer.h +++ b/src/audio_core/buffer.h @@ -18,7 +18,7 @@ class Buffer { public: using Tag = u64; - Buffer(Tag tag, std::vector<s16>&& samples) : tag{tag}, samples{std::move(samples)} {} + Buffer(Tag tag_, std::vector<s16>&& samples_) : tag{tag_}, samples{std::move(samples_)} {} /// Returns the raw audio data for the buffer std::vector<s16>& GetSamples() { diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp index c5a0d98ce..2fb91c13a 100644 --- a/src/audio_core/codec.cpp +++ b/src/audio_core/codec.cpp @@ -16,8 +16,9 @@ std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM constexpr std::size_t FRAME_LEN = 8; constexpr std::size_t SAMPLES_PER_FRAME = 14; - constexpr std::array<int, 16> SIGNED_NIBBLES = { - {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; + static constexpr std::array<int, 16> SIGNED_NIBBLES{ + 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1, + }; const std::size_t sample_count = (size / FRAME_LEN) * SAMPLES_PER_FRAME; const std::size_t ret_size = diff --git a/src/audio_core/codec.h b/src/audio_core/codec.h index ef2ce01a8..9507abb1b 100644 --- a/src/audio_core/codec.h +++ b/src/audio_core/codec.h @@ -38,7 +38,7 @@ using ADPCM_Coeff = std::array<s16, 16>; * @param state ADPCM state, this is updated with new state * @return Decoded stereo signed PCM16 data, sample_count in length */ -std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM_Coeff& coeff, +std::vector<s16> DecodeADPCM(const u8* data, std::size_t size, const ADPCM_Coeff& coeff, ADPCMState& state); }; // namespace AudioCore::Codec diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp index 8f7da49e6..a4a9a757d 100644 --- a/src/audio_core/command_generator.cpp +++ b/src/audio_core/command_generator.cpp @@ -67,12 +67,12 @@ s32 ApplyMixDepop(s32* output, s32 first_sample, s32 delta, s32 sample_count) { } // namespace -CommandGenerator::CommandGenerator(AudioCommon::AudioRendererParameter& worker_params, - VoiceContext& voice_context, MixContext& mix_context, - SplitterContext& splitter_context, EffectContext& effect_context, - Core::Memory::Memory& memory) - : worker_params(worker_params), voice_context(voice_context), mix_context(mix_context), - splitter_context(splitter_context), effect_context(effect_context), memory(memory), +CommandGenerator::CommandGenerator(AudioCommon::AudioRendererParameter& worker_params_, + VoiceContext& voice_context_, MixContext& mix_context_, + SplitterContext& splitter_context_, + EffectContext& effect_context_, Core::Memory::Memory& memory_) + : worker_params(worker_params_), voice_context(voice_context_), mix_context(mix_context_), + splitter_context(splitter_context_), effect_context(effect_context_), memory(memory_), mix_buffer((worker_params.mix_buffer_count + AudioCommon::MAX_CHANNEL_COUNT) * worker_params.sample_count), sample_buffer(MIX_BUFFER_SIZE), @@ -152,7 +152,7 @@ void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) { if (!destination_data->IsConfigured()) { continue; } - if (destination_data->GetMixId() >= mix_context.GetCount()) { + if (destination_data->GetMixId() >= static_cast<int>(mix_context.GetCount())) { continue; } @@ -255,7 +255,8 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info, VoiceState& dsp_state, - s32 mix_buffer_count, s32 channel) { + [[maybe_unused]] s32 mix_buffer_count, + [[maybe_unused]] s32 channel) { for (std::size_t i = 0; i < AudioCommon::MAX_BIQUAD_FILTERS; i++) { const auto& in_params = voice_info.GetInParams(); auto& biquad_filter = in_params.biquad_filter[i]; @@ -278,9 +279,12 @@ void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voic } } -void AudioCore::CommandGenerator::GenerateBiquadFilterCommand( - s32 mix_buffer, const BiquadFilterParameter& params, std::array<s64, 2>& state, - std::size_t input_offset, std::size_t output_offset, s32 sample_count, s32 node_id) { +void CommandGenerator::GenerateBiquadFilterCommand([[maybe_unused]] s32 mix_buffer_id, + const BiquadFilterParameter& params, + std::array<s64, 2>& state, + std::size_t input_offset, + std::size_t output_offset, s32 sample_count, + s32 node_id) { if (dumping_frame) { LOG_DEBUG(Audio, "(DSP_TRACE) GenerateBiquadFilterCommand node_id={}, " @@ -435,7 +439,7 @@ void CommandGenerator::GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* inf GetMixBuffer(output_index), worker_params.sample_count, offset, write_count); memory.WriteBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP)); - if (samples_read != worker_params.sample_count && + if (samples_read != static_cast<int>(worker_params.sample_count) && samples_read <= params.sample_count) { std::memset(GetMixBuffer(output_index), 0, params.sample_count - samples_read); } @@ -611,7 +615,8 @@ void CommandGenerator::GenerateMixCommands(ServerMixInfo& mix_info) { const auto& dest_mix = mix_context.GetInfo(destination_data->GetMixId()); const auto& dest_in_params = dest_mix.GetInParams(); const auto mix_index = (base - 1) % in_params.buffer_count + in_params.buffer_offset; - for (std::size_t i = 0; i < dest_in_params.buffer_count; i++) { + for (std::size_t i = 0; i < static_cast<std::size_t>(dest_in_params.buffer_count); + i++) { const auto mixed_volume = in_params.volume * destination_data->GetMixVolume(i); if (mixed_volume != 0.0f) { GenerateMixCommand(dest_in_params.buffer_offset + i, mix_index, mixed_volume, @@ -704,7 +709,7 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s std::vector<s16> buffer(samples_processed * channel_count); memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); - for (std::size_t i = 0; i < samples_processed; i++) { + for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) { sample_buffer[mix_offset + i] = buffer[i * channel_count + channel]; } } @@ -713,7 +718,8 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s } s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state, - s32 sample_count, s32 channel, std::size_t mix_offset) { + s32 sample_count, [[maybe_unused]] s32 channel, + std::size_t mix_offset) { const auto& in_params = voice_info.GetInParams(); const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index]; if (wave_buffer.buffer_address == 0) { @@ -726,8 +732,9 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s return 0; } - constexpr std::array<int, 16> SIGNED_NIBBLES = { - {0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1}}; + static constexpr std::array<int, 16> SIGNED_NIBBLES{ + 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1, + }; constexpr std::size_t FRAME_LEN = 8; constexpr std::size_t NIBBLES_PER_SAMPLE = 16; @@ -789,9 +796,8 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s position_in_frame += 2; // Decode entire frame - if (remaining_samples >= SAMPLES_PER_FRAME) { + if (remaining_samples >= static_cast<int>(SAMPLES_PER_FRAME)) { for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) { - // Sample 1 const s32 s0 = SIGNED_NIBBLES[buffer[buffer_offset] >> 4]; const s32 s1 = SIGNED_NIBBLES[buffer[buffer_offset++] & 0xf]; @@ -800,7 +806,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s sample_buffer[cur_mix_offset++] = sample_1; sample_buffer[cur_mix_offset++] = sample_2; } - remaining_samples -= SAMPLES_PER_FRAME; + remaining_samples -= static_cast<int>(SAMPLES_PER_FRAME); position_in_frame += SAMPLES_PER_FRAME; continue; } @@ -866,7 +872,6 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o const auto resample_rate = static_cast<s32>( static_cast<float>(in_params.sample_rate) / static_cast<float>(target_sample_rate) * static_cast<float>(static_cast<s32>(in_params.pitch * 32768.0f))); - auto* output_base = output; if (dsp_state.fraction + sample_count * resample_rate > static_cast<s32>(SCALED_MIX_BUFFER_SIZE - 4ULL)) { return; diff --git a/src/audio_core/command_generator.h b/src/audio_core/command_generator.h index 967d24078..b937350b1 100644 --- a/src/audio_core/command_generator.h +++ b/src/audio_core/command_generator.h @@ -7,7 +7,6 @@ #include <array> #include "audio_core/common.h" #include "audio_core/voice_context.h" -#include "common/common_funcs.h" #include "common/common_types.h" namespace Core::Memory { @@ -26,10 +25,10 @@ using MixVolumeBuffer = std::array<float, AudioCommon::MAX_MIX_BUFFERS>; class CommandGenerator { public: - explicit CommandGenerator(AudioCommon::AudioRendererParameter& worker_params, - VoiceContext& voice_context, MixContext& mix_context, - SplitterContext& splitter_context, EffectContext& effect_context, - Core::Memory::Memory& memory); + explicit CommandGenerator(AudioCommon::AudioRendererParameter& worker_params_, + VoiceContext& voice_context_, MixContext& mix_context_, + SplitterContext& splitter_context_, EffectContext& effect_context_, + Core::Memory::Memory& memory_); ~CommandGenerator(); void ClearMixBuffers(); @@ -40,13 +39,13 @@ public: void PreCommand(); void PostCommand(); - s32* GetChannelMixBuffer(s32 channel); - const s32* GetChannelMixBuffer(s32 channel) const; - s32* GetMixBuffer(std::size_t index); - const s32* GetMixBuffer(std::size_t index) const; - std::size_t GetMixChannelBufferOffset(s32 channel) const; + [[nodiscard]] s32* GetChannelMixBuffer(s32 channel); + [[nodiscard]] const s32* GetChannelMixBuffer(s32 channel) const; + [[nodiscard]] s32* GetMixBuffer(std::size_t index); + [[nodiscard]] const s32* GetMixBuffer(std::size_t index) const; + [[nodiscard]] std::size_t GetMixChannelBufferOffset(s32 channel) const; - std::size_t GetTotalMixBufferCount() const; + [[nodiscard]] std::size_t GetTotalMixBufferCount() const; private: void GenerateDataSourceCommand(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 channel); @@ -74,7 +73,7 @@ private: void GenerateI3dl2ReverbEffectCommand(s32 mix_buffer_offset, EffectBase* info, bool enabled); void GenerateBiquadFilterEffectCommand(s32 mix_buffer_offset, EffectBase* info, bool enabled); void GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* info, bool enabled); - ServerSplitterDestinationData* GetDestinationData(s32 splitter_id, s32 index); + [[nodiscard]] ServerSplitterDestinationData* GetDestinationData(s32 splitter_id, s32 index); s32 WriteAuxBuffer(AuxInfoDSP& dsp_info, VAddr send_buffer, u32 max_samples, const s32* data, u32 sample_count, u32 write_offset, u32 write_count); diff --git a/src/audio_core/common.h b/src/audio_core/common.h index 72ebce221..ec59a3ba9 100644 --- a/src/audio_core/common.h +++ b/src/audio_core/common.h @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #pragma once + #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" @@ -21,7 +22,7 @@ constexpr std::size_t MAX_CHANNEL_COUNT = 6; constexpr std::size_t MAX_WAVE_BUFFERS = 4; constexpr std::size_t MAX_SAMPLE_HISTORY = 4; constexpr u32 STREAM_SAMPLE_RATE = 48000; -constexpr u32 STREAM_NUM_CHANNELS = 6; +constexpr u32 STREAM_NUM_CHANNELS = 2; constexpr s32 NO_SPLITTER = -1; constexpr s32 NO_MIX = 0x7fffffff; constexpr s32 NO_FINAL_MIX = std::numeric_limits<s32>::min(); diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index 83c06c0ed..043447eaa 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp @@ -21,15 +21,16 @@ namespace AudioCore { class CubebSinkStream final : public SinkStream { public: - CubebSinkStream(cubeb* ctx, u32 sample_rate, u32 num_channels_, cubeb_devid output_device, + CubebSinkStream(cubeb* ctx_, u32 sample_rate, u32 num_channels_, cubeb_devid output_device, const std::string& name) - : ctx{ctx}, num_channels{std::min(num_channels_, 6u)}, time_stretch{sample_rate, - num_channels} { + : ctx{ctx_}, num_channels{std::min(num_channels_, 6u)}, time_stretch{sample_rate, + num_channels} { cubeb_stream_params params{}; params.rate = sample_rate; params.channels = num_channels; params.format = CUBEB_SAMPLE_S16NE; + params.prefs = CUBEB_STREAM_PREF_PERSIST; switch (num_channels) { case 1: params.layout = CUBEB_LAYOUT_MONO; @@ -93,8 +94,10 @@ public: constexpr s32 clev{707}; // center mixing level coefficient constexpr s32 slev{707}; // surround mixing level coefficient - buf.push_back(left + (clev * center / 1000) + (slev * surround_left / 1000)); - buf.push_back(right + (clev * center / 1000) + (slev * surround_right / 1000)); + buf.push_back(static_cast<s16>(left + (clev * center / 1000) + + (slev * surround_left / 1000))); + buf.push_back(static_cast<s16>(right + (clev * center / 1000) + + (slev * surround_right / 1000))); } queue.Push(buf); return; @@ -190,10 +193,11 @@ SinkStream& CubebSink::AcquireSinkStream(u32 sample_rate, u32 num_channels, return *sink_streams.back(); } -long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const void* input_buffer, - void* output_buffer, long num_frames) { - CubebSinkStream* impl = static_cast<CubebSinkStream*>(user_data); - u8* buffer = reinterpret_cast<u8*>(output_buffer); +long CubebSinkStream::DataCallback([[maybe_unused]] cubeb_stream* stream, void* user_data, + [[maybe_unused]] const void* input_buffer, void* output_buffer, + long num_frames) { + auto* impl = static_cast<CubebSinkStream*>(user_data); + auto* buffer = static_cast<u8*>(output_buffer); if (!impl) { return {}; @@ -234,7 +238,9 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const return num_frames; } -void CubebSinkStream::StateCallback(cubeb_stream* stream, void* user_data, cubeb_state state) {} +void CubebSinkStream::StateCallback([[maybe_unused]] cubeb_stream* stream, + [[maybe_unused]] void* user_data, + [[maybe_unused]] cubeb_state state) {} std::vector<std::string> ListCubebSinkDevices() { std::vector<std::string> device_list; diff --git a/src/audio_core/effect_context.cpp b/src/audio_core/effect_context.cpp index adfec3df5..f770b9608 100644 --- a/src/audio_core/effect_context.cpp +++ b/src/audio_core/effect_context.cpp @@ -12,7 +12,7 @@ bool ValidChannelCountForEffect(s32 channel_count) { } } // namespace -EffectContext::EffectContext(std::size_t effect_count) : effect_count(effect_count) { +EffectContext::EffectContext(std::size_t effect_count_) : effect_count(effect_count_) { effects.reserve(effect_count); std::generate_n(std::back_inserter(effects), effect_count, [] { return std::make_unique<EffectStubbed>(); }); @@ -61,13 +61,13 @@ const EffectBase* EffectContext::GetInfo(std::size_t i) const { return effects.at(i).get(); } -EffectStubbed::EffectStubbed() : EffectBase::EffectBase(EffectType::Invalid) {} +EffectStubbed::EffectStubbed() : EffectBase(EffectType::Invalid) {} EffectStubbed::~EffectStubbed() = default; -void EffectStubbed::Update(EffectInfo::InParams& in_params) {} +void EffectStubbed::Update([[maybe_unused]] EffectInfo::InParams& in_params) {} void EffectStubbed::UpdateForCommandGeneration() {} -EffectBase::EffectBase(EffectType effect_type) : effect_type(effect_type) {} +EffectBase::EffectBase(EffectType effect_type_) : effect_type(effect_type_) {} EffectBase::~EffectBase() = default; UsageState EffectBase::GetUsage() const { @@ -90,32 +90,32 @@ s32 EffectBase::GetProcessingOrder() const { return processing_order; } -EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric::EffectGeneric(EffectType::I3dl2Reverb) {} +EffectI3dl2Reverb::EffectI3dl2Reverb() : EffectGeneric(EffectType::I3dl2Reverb) {} EffectI3dl2Reverb::~EffectI3dl2Reverb() = default; void EffectI3dl2Reverb::Update(EffectInfo::InParams& in_params) { - auto& internal_params = GetParams(); + auto& params = GetParams(); const auto* reverb_params = reinterpret_cast<I3dl2ReverbParams*>(in_params.raw.data()); if (!ValidChannelCountForEffect(reverb_params->max_channels)) { UNREACHABLE_MSG("Invalid reverb max channel count {}", reverb_params->max_channels); return; } - const auto last_status = internal_params.status; + const auto last_status = params.status; mix_id = in_params.mix_id; processing_order = in_params.processing_order; - internal_params = *reverb_params; + params = *reverb_params; if (!ValidChannelCountForEffect(reverb_params->channel_count)) { - internal_params.channel_count = internal_params.max_channels; + params.channel_count = params.max_channels; } enabled = in_params.is_enabled; if (last_status != ParameterStatus::Updated) { - internal_params.status = last_status; + params.status = last_status; } if (in_params.is_new || skipped) { usage = UsageState::Initialized; - internal_params.status = ParameterStatus::Initialized; + params.status = ParameterStatus::Initialized; skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0; } } @@ -129,15 +129,15 @@ void EffectI3dl2Reverb::UpdateForCommandGeneration() { GetParams().status = ParameterStatus::Updated; } -EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric::EffectGeneric(EffectType::BiquadFilter) {} +EffectBiquadFilter::EffectBiquadFilter() : EffectGeneric(EffectType::BiquadFilter) {} EffectBiquadFilter::~EffectBiquadFilter() = default; void EffectBiquadFilter::Update(EffectInfo::InParams& in_params) { - auto& internal_params = GetParams(); + auto& params = GetParams(); const auto* biquad_params = reinterpret_cast<BiquadFilterParams*>(in_params.raw.data()); mix_id = in_params.mix_id; processing_order = in_params.processing_order; - internal_params = *biquad_params; + params = *biquad_params; enabled = in_params.is_enabled; } @@ -150,7 +150,7 @@ void EffectBiquadFilter::UpdateForCommandGeneration() { GetParams().status = ParameterStatus::Updated; } -EffectAuxInfo::EffectAuxInfo() : EffectGeneric::EffectGeneric(EffectType::Aux) {} +EffectAuxInfo::EffectAuxInfo() : EffectGeneric(EffectType::Aux) {} EffectAuxInfo::~EffectAuxInfo() = default; void EffectAuxInfo::Update(EffectInfo::InParams& in_params) { @@ -184,48 +184,48 @@ void EffectAuxInfo::UpdateForCommandGeneration() { } } -const VAddr EffectAuxInfo::GetSendInfo() const { +VAddr EffectAuxInfo::GetSendInfo() const { return send_info; } -const VAddr EffectAuxInfo::GetSendBuffer() const { +VAddr EffectAuxInfo::GetSendBuffer() const { return send_buffer; } -const VAddr EffectAuxInfo::GetRecvInfo() const { +VAddr EffectAuxInfo::GetRecvInfo() const { return recv_info; } -const VAddr EffectAuxInfo::GetRecvBuffer() const { +VAddr EffectAuxInfo::GetRecvBuffer() const { return recv_buffer; } -EffectDelay::EffectDelay() : EffectGeneric::EffectGeneric(EffectType::Delay) {} +EffectDelay::EffectDelay() : EffectGeneric(EffectType::Delay) {} EffectDelay::~EffectDelay() = default; void EffectDelay::Update(EffectInfo::InParams& in_params) { const auto* delay_params = reinterpret_cast<DelayParams*>(in_params.raw.data()); - auto& internal_params = GetParams(); + auto& params = GetParams(); if (!ValidChannelCountForEffect(delay_params->max_channels)) { return; } - const auto last_status = internal_params.status; + const auto last_status = params.status; mix_id = in_params.mix_id; processing_order = in_params.processing_order; - internal_params = *delay_params; + params = *delay_params; if (!ValidChannelCountForEffect(delay_params->channels)) { - internal_params.channels = internal_params.max_channels; + params.channels = params.max_channels; } enabled = in_params.is_enabled; if (last_status != ParameterStatus::Updated) { - internal_params.status = last_status; + params.status = last_status; } if (in_params.is_new || skipped) { usage = UsageState::Initialized; - internal_params.status = ParameterStatus::Initialized; + params.status = ParameterStatus::Initialized; skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0; } } @@ -239,7 +239,7 @@ void EffectDelay::UpdateForCommandGeneration() { GetParams().status = ParameterStatus::Updated; } -EffectBufferMixer::EffectBufferMixer() : EffectGeneric::EffectGeneric(EffectType::BufferMixer) {} +EffectBufferMixer::EffectBufferMixer() : EffectGeneric(EffectType::BufferMixer) {} EffectBufferMixer::~EffectBufferMixer() = default; void EffectBufferMixer::Update(EffectInfo::InParams& in_params) { @@ -257,32 +257,32 @@ void EffectBufferMixer::UpdateForCommandGeneration() { } } -EffectReverb::EffectReverb() : EffectGeneric::EffectGeneric(EffectType::Reverb) {} +EffectReverb::EffectReverb() : EffectGeneric(EffectType::Reverb) {} EffectReverb::~EffectReverb() = default; void EffectReverb::Update(EffectInfo::InParams& in_params) { const auto* reverb_params = reinterpret_cast<ReverbParams*>(in_params.raw.data()); - auto& internal_params = GetParams(); + auto& params = GetParams(); if (!ValidChannelCountForEffect(reverb_params->max_channels)) { return; } - const auto last_status = internal_params.status; + const auto last_status = params.status; mix_id = in_params.mix_id; processing_order = in_params.processing_order; - internal_params = *reverb_params; + params = *reverb_params; if (!ValidChannelCountForEffect(reverb_params->channels)) { - internal_params.channels = internal_params.max_channels; + params.channels = params.max_channels; } enabled = in_params.is_enabled; if (last_status != ParameterStatus::Updated) { - internal_params.status = last_status; + params.status = last_status; } if (in_params.is_new || skipped) { usage = UsageState::Initialized; - internal_params.status = ParameterStatus::Initialized; + params.status = ParameterStatus::Initialized; skipped = in_params.buffer_address == 0 || in_params.buffer_size == 0; } } diff --git a/src/audio_core/effect_context.h b/src/audio_core/effect_context.h index 2f2da72dd..c5e0b398c 100644 --- a/src/audio_core/effect_context.h +++ b/src/audio_core/effect_context.h @@ -166,13 +166,13 @@ public: std::array<u8, 0xa0> raw; }; }; - static_assert(sizeof(EffectInfo::InParams) == 0xc0, "InParams is an invalid size"); + static_assert(sizeof(InParams) == 0xc0, "InParams is an invalid size"); struct OutParams { UsageStatus status{}; INSERT_PADDING_BYTES(15); }; - static_assert(sizeof(EffectInfo::OutParams) == 0x10, "OutParams is an invalid size"); + static_assert(sizeof(OutParams) == 0x10, "OutParams is an invalid size"); }; struct AuxAddress { @@ -184,16 +184,16 @@ struct AuxAddress { class EffectBase { public: - EffectBase(EffectType effect_type); - ~EffectBase(); + explicit EffectBase(EffectType effect_type_); + virtual ~EffectBase(); virtual void Update(EffectInfo::InParams& in_params) = 0; virtual void UpdateForCommandGeneration() = 0; - UsageState GetUsage() const; - EffectType GetType() const; - bool IsEnabled() const; - s32 GetMixID() const; - s32 GetProcessingOrder() const; + [[nodiscard]] UsageState GetUsage() const; + [[nodiscard]] EffectType GetType() const; + [[nodiscard]] bool IsEnabled() const; + [[nodiscard]] s32 GetMixID() const; + [[nodiscard]] s32 GetProcessingOrder() const; protected: UsageState usage{UsageState::Invalid}; @@ -206,8 +206,7 @@ protected: template <typename T> class EffectGeneric : public EffectBase { public: - EffectGeneric(EffectType effect_type) : EffectBase::EffectBase(effect_type) {} - ~EffectGeneric() = default; + explicit EffectGeneric(EffectType effect_type_) : EffectBase(effect_type_) {} T& GetParams() { return internal_params; @@ -224,7 +223,7 @@ private: class EffectStubbed : public EffectBase { public: explicit EffectStubbed(); - ~EffectStubbed(); + ~EffectStubbed() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; @@ -233,7 +232,7 @@ public: class EffectI3dl2Reverb : public EffectGeneric<I3dl2ReverbParams> { public: explicit EffectI3dl2Reverb(); - ~EffectI3dl2Reverb(); + ~EffectI3dl2Reverb() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; @@ -245,7 +244,7 @@ private: class EffectBiquadFilter : public EffectGeneric<BiquadFilterParams> { public: explicit EffectBiquadFilter(); - ~EffectBiquadFilter(); + ~EffectBiquadFilter() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; @@ -254,14 +253,14 @@ public: class EffectAuxInfo : public EffectGeneric<AuxInfo> { public: explicit EffectAuxInfo(); - ~EffectAuxInfo(); + ~EffectAuxInfo() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; - const VAddr GetSendInfo() const; - const VAddr GetSendBuffer() const; - const VAddr GetRecvInfo() const; - const VAddr GetRecvBuffer() const; + [[nodiscard]] VAddr GetSendInfo() const; + [[nodiscard]] VAddr GetSendBuffer() const; + [[nodiscard]] VAddr GetRecvInfo() const; + [[nodiscard]] VAddr GetRecvBuffer() const; private: VAddr send_info{}; @@ -275,7 +274,7 @@ private: class EffectDelay : public EffectGeneric<DelayParams> { public: explicit EffectDelay(); - ~EffectDelay(); + ~EffectDelay() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; @@ -287,7 +286,7 @@ private: class EffectBufferMixer : public EffectGeneric<BufferMixerParams> { public: explicit EffectBufferMixer(); - ~EffectBufferMixer(); + ~EffectBufferMixer() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; @@ -296,7 +295,7 @@ public: class EffectReverb : public EffectGeneric<ReverbParams> { public: explicit EffectReverb(); - ~EffectReverb(); + ~EffectReverb() override; void Update(EffectInfo::InParams& in_params) override; void UpdateForCommandGeneration() override; @@ -307,13 +306,13 @@ private: class EffectContext { public: - explicit EffectContext(std::size_t effect_count); + explicit EffectContext(std::size_t effect_count_); ~EffectContext(); - std::size_t GetCount() const; - EffectBase* GetInfo(std::size_t i); - EffectBase* RetargetEffect(std::size_t i, EffectType effect); - const EffectBase* GetInfo(std::size_t i) const; + [[nodiscard]] std::size_t GetCount() const; + [[nodiscard]] EffectBase* GetInfo(std::size_t i); + [[nodiscard]] EffectBase* RetargetEffect(std::size_t i, EffectType effect); + [[nodiscard]] const EffectBase* GetInfo(std::size_t i) const; private: std::size_t effect_count{}; diff --git a/src/audio_core/info_updater.cpp b/src/audio_core/info_updater.cpp index f53ce21a5..d3ac90827 100644 --- a/src/audio_core/info_updater.cpp +++ b/src/audio_core/info_updater.cpp @@ -14,9 +14,9 @@ namespace AudioCore { -InfoUpdater::InfoUpdater(const std::vector<u8>& in_params, std::vector<u8>& out_params, - BehaviorInfo& behavior_info) - : in_params(in_params), out_params(out_params), behavior_info(behavior_info) { +InfoUpdater::InfoUpdater(const std::vector<u8>& in_params_, std::vector<u8>& out_params_, + BehaviorInfo& behavior_info_) + : in_params(in_params_), out_params(out_params_), behavior_info(behavior_info_) { ASSERT( AudioCommon::CanConsumeBuffer(in_params.size(), 0, sizeof(AudioCommon::UpdateDataHeader))); std::memcpy(&input_header, in_params.data(), sizeof(AudioCommon::UpdateDataHeader)); @@ -64,7 +64,6 @@ bool InfoUpdater::UpdateBehaviorInfo(BehaviorInfo& in_behavior_info) { } bool InfoUpdater::UpdateMemoryPools(std::vector<ServerMemoryPoolInfo>& memory_pool_info) { - const auto force_mapping = behavior_info.IsMemoryPoolForceMappingEnabled(); const auto memory_pool_count = memory_pool_info.size(); const auto total_memory_pool_in = sizeof(ServerMemoryPoolInfo::InParams) * memory_pool_count; const auto total_memory_pool_out = sizeof(ServerMemoryPoolInfo::OutParams) * memory_pool_count; @@ -136,8 +135,8 @@ bool InfoUpdater::UpdateVoiceChannelResources(VoiceContext& voice_context) { } bool InfoUpdater::UpdateVoices(VoiceContext& voice_context, - std::vector<ServerMemoryPoolInfo>& memory_pool_info, - VAddr audio_codec_dsp_addr) { + [[maybe_unused]] std::vector<ServerMemoryPoolInfo>& memory_pool_info, + [[maybe_unused]] VAddr audio_codec_dsp_addr) { const auto voice_count = voice_context.GetVoiceCount(); std::vector<VoiceInfo::InParams> voice_in(voice_count); std::vector<VoiceInfo::OutParams> voice_out(voice_count); @@ -166,28 +165,28 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context, // Update our voices for (std::size_t i = 0; i < voice_count; i++) { - auto& in_params = voice_in[i]; - const auto channel_count = static_cast<std::size_t>(in_params.channel_count); + auto& voice_in_params = voice_in[i]; + const auto channel_count = static_cast<std::size_t>(voice_in_params.channel_count); // Skip if it's not currently in use - if (!in_params.is_in_use) { + if (!voice_in_params.is_in_use) { continue; } // Voice states for each channel std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT> voice_states{}; - ASSERT(in_params.id < voice_count); + ASSERT(static_cast<std::size_t>(voice_in_params.id) < voice_count); // Grab our current voice info - auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(in_params.id)); + auto& voice_info = voice_context.GetInfo(static_cast<std::size_t>(voice_in_params.id)); ASSERT(channel_count <= AudioCommon::MAX_CHANNEL_COUNT); // Get all our channel voice states for (std::size_t channel = 0; channel < channel_count; channel++) { voice_states[channel] = - &voice_context.GetState(in_params.voice_channel_resource_ids[channel]); + &voice_context.GetState(voice_in_params.voice_channel_resource_ids[channel]); } - if (in_params.is_new) { + if (voice_in_params.is_new) { // Default our values for our voice voice_info.Initialize(); if (channel_count == 0 || channel_count > AudioCommon::MAX_CHANNEL_COUNT) { @@ -201,12 +200,12 @@ bool InfoUpdater::UpdateVoices(VoiceContext& voice_context, } // Update our voice - voice_info.UpdateParameters(in_params, behavior_info); + voice_info.UpdateParameters(voice_in_params, behavior_info); // TODO(ogniK): Handle mapping errors with behavior info based on in params response // Update our wave buffers - voice_info.UpdateWaveBuffers(in_params, voice_states, behavior_info); - voice_info.WriteOutStatus(voice_out[i], in_params, voice_states); + voice_info.UpdateWaveBuffers(voice_in_params, voice_states, behavior_info); + voice_info.WriteOutStatus(voice_out[i], voice_in_params, voice_states); } if (!AudioCommon::CanConsumeBuffer(out_params.size(), output_offset, voice_out_size)) { @@ -352,8 +351,8 @@ ResultCode InfoUpdater::UpdateMixes(MixContext& mix_context, std::size_t mix_buf for (std::size_t i = 0; i < mix_count; i++) { const auto& in = mix_in_params[i]; total_buffer_count += in.buffer_count; - if (in.dest_mix_id > mix_count && in.dest_mix_id != AudioCommon::NO_MIX && - in.mix_id != AudioCommon::FINAL_MIX) { + if (static_cast<std::size_t>(in.dest_mix_id) > mix_count && + in.dest_mix_id != AudioCommon::NO_MIX && in.mix_id != AudioCommon::FINAL_MIX) { LOG_ERROR( Audio, "Invalid mix destination, mix_id={:X}, dest_mix_id={:X}, mix_buffer_count={:X}", @@ -446,7 +445,7 @@ bool InfoUpdater::UpdatePerformanceBuffer() { return true; } -bool InfoUpdater::UpdateErrorInfo(BehaviorInfo& in_behavior_info) { +bool InfoUpdater::UpdateErrorInfo([[maybe_unused]] BehaviorInfo& in_behavior_info) { const auto total_beahvior_info_out = sizeof(BehaviorInfo::OutParams); if (!AudioCommon::CanConsumeBuffer(out_params.size(), output_offset, total_beahvior_info_out)) { diff --git a/src/audio_core/info_updater.h b/src/audio_core/info_updater.h index 06f9d770f..d315c91ed 100644 --- a/src/audio_core/info_updater.h +++ b/src/audio_core/info_updater.h @@ -21,8 +21,8 @@ class SplitterContext; class InfoUpdater { public: // TODO(ogniK): Pass process handle when we support it - InfoUpdater(const std::vector<u8>& in_params, std::vector<u8>& out_params, - BehaviorInfo& behavior_info); + InfoUpdater(const std::vector<u8>& in_params_, std::vector<u8>& out_params_, + BehaviorInfo& behavior_info_); ~InfoUpdater(); bool UpdateBehaviorInfo(BehaviorInfo& in_behavior_info); diff --git a/src/audio_core/memory_pool.cpp b/src/audio_core/memory_pool.cpp index 5a3453063..6b6908d26 100644 --- a/src/audio_core/memory_pool.cpp +++ b/src/audio_core/memory_pool.cpp @@ -10,11 +10,10 @@ namespace AudioCore { ServerMemoryPoolInfo::ServerMemoryPoolInfo() = default; ServerMemoryPoolInfo::~ServerMemoryPoolInfo() = default; -bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_params, - ServerMemoryPoolInfo::OutParams& out_params) { + +bool ServerMemoryPoolInfo::Update(const InParams& in_params, OutParams& out_params) { // Our state does not need to be changed - if (in_params.state != ServerMemoryPoolInfo::State::RequestAttach && - in_params.state != ServerMemoryPoolInfo::State::RequestDetach) { + if (in_params.state != State::RequestAttach && in_params.state != State::RequestDetach) { return true; } @@ -32,11 +31,11 @@ bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_param return false; } - if (in_params.state == ServerMemoryPoolInfo::State::RequestAttach) { + if (in_params.state == State::RequestAttach) { cpu_address = in_params.address; size = in_params.size; used = true; - out_params.state = ServerMemoryPoolInfo::State::Attached; + out_params.state = State::Attached; } else { // Unexpected address if (cpu_address != in_params.address) { @@ -54,7 +53,7 @@ bool ServerMemoryPoolInfo::Update(const ServerMemoryPoolInfo::InParams& in_param cpu_address = 0; size = 0; used = false; - out_params.state = ServerMemoryPoolInfo::State::Detached; + out_params.state = State::Detached; } return true; } diff --git a/src/audio_core/memory_pool.h b/src/audio_core/memory_pool.h index 8ac503f1c..3e9e777ae 100644 --- a/src/audio_core/memory_pool.h +++ b/src/audio_core/memory_pool.h @@ -28,19 +28,18 @@ public: struct InParams { u64_le address{}; u64_le size{}; - ServerMemoryPoolInfo::State state{}; + State state{}; INSERT_PADDING_WORDS(3); }; - static_assert(sizeof(ServerMemoryPoolInfo::InParams) == 0x20, "InParams are an invalid size"); + static_assert(sizeof(InParams) == 0x20, "InParams are an invalid size"); struct OutParams { - ServerMemoryPoolInfo::State state{}; + State state{}; INSERT_PADDING_WORDS(3); }; - static_assert(sizeof(ServerMemoryPoolInfo::OutParams) == 0x10, "OutParams are an invalid size"); + static_assert(sizeof(OutParams) == 0x10, "OutParams are an invalid size"); - bool Update(const ServerMemoryPoolInfo::InParams& in_params, - ServerMemoryPoolInfo::OutParams& out_params); + bool Update(const InParams& in_params, OutParams& out_params); private: // There's another entry here which is the DSP address, however since we're not talking to the diff --git a/src/audio_core/mix_context.cpp b/src/audio_core/mix_context.cpp index 042891490..4bca72eb0 100644 --- a/src/audio_core/mix_context.cpp +++ b/src/audio_core/mix_context.cpp @@ -53,7 +53,7 @@ void MixContext::UpdateDistancesFromFinalMix() { auto mix_id = in_params.mix_id; // Needs to be referenced out of scope s32 distance_to_final_mix{AudioCommon::FINAL_MIX}; - for (; distance_to_final_mix < info_count; distance_to_final_mix++) { + for (; distance_to_final_mix < static_cast<s32>(info_count); distance_to_final_mix++) { if (mix_id == AudioCommon::FINAL_MIX) { // If we're at the final mix, we're done break; @@ -77,7 +77,7 @@ void MixContext::UpdateDistancesFromFinalMix() { } // If we're out of range for our distance, mark it as no final mix - if (distance_to_final_mix >= info_count) { + if (distance_to_final_mix >= static_cast<s32>(info_count)) { distance_to_final_mix = AudioCommon::NO_FINAL_MIX; } diff --git a/src/audio_core/mix_context.h b/src/audio_core/mix_context.h index 6a588eeb4..68bc673c6 100644 --- a/src/audio_core/mix_context.h +++ b/src/audio_core/mix_context.h @@ -62,17 +62,17 @@ public: ServerMixInfo(); ~ServerMixInfo(); - const ServerMixInfo::InParams& GetInParams() const; - ServerMixInfo::InParams& GetInParams(); + [[nodiscard]] const ServerMixInfo::InParams& GetInParams() const; + [[nodiscard]] ServerMixInfo::InParams& GetInParams(); bool Update(EdgeMatrix& edge_matrix, const MixInfo::InParams& mix_in, BehaviorInfo& behavior_info, SplitterContext& splitter_context, EffectContext& effect_context); - bool HasAnyConnection() const; + [[nodiscard]] bool HasAnyConnection() const; void Cleanup(); void SetEffectCount(std::size_t count); void ResetEffectProcessingOrder(); - s32 GetEffectOrder(std::size_t i) const; + [[nodiscard]] s32 GetEffectOrder(std::size_t i) const; private: std::vector<s32> effect_processing_order; @@ -91,15 +91,15 @@ public: void SortInfo(); bool TsortInfo(SplitterContext& splitter_context); - std::size_t GetCount() const; - ServerMixInfo& GetInfo(std::size_t i); - const ServerMixInfo& GetInfo(std::size_t i) const; - ServerMixInfo& GetSortedInfo(std::size_t i); - const ServerMixInfo& GetSortedInfo(std::size_t i) const; - ServerMixInfo& GetFinalMixInfo(); - const ServerMixInfo& GetFinalMixInfo() const; - EdgeMatrix& GetEdgeMatrix(); - const EdgeMatrix& GetEdgeMatrix() const; + [[nodiscard]] std::size_t GetCount() const; + [[nodiscard]] ServerMixInfo& GetInfo(std::size_t i); + [[nodiscard]] const ServerMixInfo& GetInfo(std::size_t i) const; + [[nodiscard]] ServerMixInfo& GetSortedInfo(std::size_t i); + [[nodiscard]] const ServerMixInfo& GetSortedInfo(std::size_t i) const; + [[nodiscard]] ServerMixInfo& GetFinalMixInfo(); + [[nodiscard]] const ServerMixInfo& GetFinalMixInfo() const; + [[nodiscard]] EdgeMatrix& GetEdgeMatrix(); + [[nodiscard]] const EdgeMatrix& GetEdgeMatrix() const; private: void CalcMixBufferOffset(); diff --git a/src/audio_core/sink_context.cpp b/src/audio_core/sink_context.cpp index 0882b411a..a69543696 100644 --- a/src/audio_core/sink_context.cpp +++ b/src/audio_core/sink_context.cpp @@ -5,17 +5,23 @@ #include "audio_core/sink_context.h" namespace AudioCore { -SinkContext::SinkContext(std::size_t sink_count) : sink_count(sink_count) {} +SinkContext::SinkContext(std::size_t sink_count_) : sink_count{sink_count_} {} SinkContext::~SinkContext() = default; std::size_t SinkContext::GetCount() const { return sink_count; } -void SinkContext::UpdateMainSink(SinkInfo::InParams& in) { +void SinkContext::UpdateMainSink(const SinkInfo::InParams& in) { + ASSERT(in.type == SinkTypes::Device); + + has_downmix_coefs = in.device.down_matrix_enabled; + if (has_downmix_coefs) { + downmix_coefficients = in.device.down_matrix_coef; + } in_use = in.in_use; use_count = in.device.input_count; - std::memcpy(buffers.data(), in.device.input.data(), AudioCommon::MAX_CHANNEL_COUNT); + buffers = in.device.input; } bool SinkContext::InUse() const { @@ -28,4 +34,12 @@ std::vector<u8> SinkContext::OutputBuffers() const { return buffer_ret; } +bool SinkContext::HasDownMixingCoefficients() const { + return has_downmix_coefs; +} + +const DownmixCoefficients& SinkContext::GetDownmixCoefficients() const { + return downmix_coefficients; +} + } // namespace AudioCore diff --git a/src/audio_core/sink_context.h b/src/audio_core/sink_context.h index d7aa72ba7..05541becb 100644 --- a/src/audio_core/sink_context.h +++ b/src/audio_core/sink_context.h @@ -11,6 +11,8 @@ namespace AudioCore { +using DownmixCoefficients = std::array<float_le, 4>; + enum class SinkTypes : u8 { Invalid = 0, Device = 1, @@ -40,7 +42,7 @@ public: bool in_use; INSERT_UNION_PADDING_BYTES(5); }; - static_assert(sizeof(SinkInfo::CircularBufferIn) == 0x28, + static_assert(sizeof(CircularBufferIn) == 0x28, "SinkInfo::CircularBufferIn is in invalid size"); struct DeviceIn { @@ -50,9 +52,9 @@ public: std::array<u8, AudioCommon::MAX_CHANNEL_COUNT> input; INSERT_UNION_PADDING_BYTES(1); bool down_matrix_enabled; - std::array<float_le, 4> down_matrix_coef; + DownmixCoefficients down_matrix_coef; }; - static_assert(sizeof(SinkInfo::DeviceIn) == 0x11c, "SinkInfo::DeviceIn is an invalid size"); + static_assert(sizeof(DeviceIn) == 0x11c, "SinkInfo::DeviceIn is an invalid size"); struct InParams { SinkTypes type{}; @@ -62,28 +64,33 @@ public: INSERT_PADDING_WORDS(6); union { // std::array<u8, 0x120> raw{}; - SinkInfo::DeviceIn device; - SinkInfo::CircularBufferIn circular_buffer; + DeviceIn device; + CircularBufferIn circular_buffer; }; }; - static_assert(sizeof(SinkInfo::InParams) == 0x140, "SinkInfo::InParams are an invalid size!"); + static_assert(sizeof(InParams) == 0x140, "SinkInfo::InParams are an invalid size!"); }; class SinkContext { public: - explicit SinkContext(std::size_t sink_count); + explicit SinkContext(std::size_t sink_count_); ~SinkContext(); - std::size_t GetCount() const; + [[nodiscard]] std::size_t GetCount() const; + + void UpdateMainSink(const SinkInfo::InParams& in); + [[nodiscard]] bool InUse() const; + [[nodiscard]] std::vector<u8> OutputBuffers() const; - void UpdateMainSink(SinkInfo::InParams& in); - bool InUse() const; - std::vector<u8> OutputBuffers() const; + [[nodiscard]] bool HasDownMixingCoefficients() const; + [[nodiscard]] const DownmixCoefficients& GetDownmixCoefficients() const; private: bool in_use{false}; s32 use_count{}; std::array<u8, AudioCommon::MAX_CHANNEL_COUNT> buffers{}; std::size_t sink_count{}; + bool has_downmix_coefs{false}; + DownmixCoefficients downmix_coefficients{}; }; } // namespace AudioCore diff --git a/src/audio_core/splitter_context.cpp b/src/audio_core/splitter_context.cpp index 79bb2f516..f4bcd0391 100644 --- a/src/audio_core/splitter_context.cpp +++ b/src/audio_core/splitter_context.cpp @@ -10,7 +10,7 @@ namespace AudioCore { -ServerSplitterDestinationData::ServerSplitterDestinationData(s32 id) : id(id) {} +ServerSplitterDestinationData::ServerSplitterDestinationData(s32 id_) : id{id_} {} ServerSplitterDestinationData::~ServerSplitterDestinationData() = default; void ServerSplitterDestinationData::Update(SplitterInfo::InDestinationParams& header) { @@ -87,7 +87,7 @@ void ServerSplitterDestinationData::UpdateInternalState() { needs_update = false; } -ServerSplitterInfo::ServerSplitterInfo(s32 id) : id(id) {} +ServerSplitterInfo::ServerSplitterInfo(s32 id_) : id(id_) {} ServerSplitterInfo::~ServerSplitterInfo() = default; void ServerSplitterInfo::InitializeInfos() { @@ -121,7 +121,7 @@ const ServerSplitterDestinationData* ServerSplitterInfo::GetHead() const { } ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) { - auto current_head = head; + auto* current_head = head; for (std::size_t i = 0; i < depth; i++) { if (current_head == nullptr) { return nullptr; @@ -132,7 +132,7 @@ ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) { } const ServerSplitterDestinationData* ServerSplitterInfo::GetData(std::size_t depth) const { - auto current_head = head; + auto* current_head = head; for (std::size_t i = 0; i < depth; i++) { if (current_head == nullptr) { return nullptr; @@ -245,7 +245,7 @@ ServerSplitterDestinationData* SplitterContext::GetDestinationData(std::size_t i const ServerSplitterDestinationData* SplitterContext::GetDestinationData(std::size_t info, std::size_t data) const { ASSERT(info < info_count); - auto& cur_info = GetInfo(info); + const auto& cur_info = GetInfo(info); return cur_info.GetData(data); } @@ -267,11 +267,11 @@ std::size_t SplitterContext::GetDataCount() const { return data_count; } -void SplitterContext::Setup(std::size_t _info_count, std::size_t _data_count, +void SplitterContext::Setup(std::size_t info_count_, std::size_t data_count_, bool is_splitter_bug_fixed) { - info_count = _info_count; - data_count = _data_count; + info_count = info_count_; + data_count = data_count_; for (std::size_t i = 0; i < info_count; i++) { auto& splitter = infos.emplace_back(static_cast<s32>(i)); @@ -306,7 +306,7 @@ bool SplitterContext::UpdateInfo(const std::vector<u8>& input, std::size_t& inpu break; } - if (header.send_id < 0 || header.send_id > info_count) { + if (header.send_id < 0 || static_cast<std::size_t>(header.send_id) > info_count) { LOG_ERROR(Audio, "Bad splitter data id"); break; } @@ -348,7 +348,7 @@ bool SplitterContext::UpdateData(const std::vector<u8>& input, std::size_t& inpu break; } - if (header.splitter_id < 0 || header.splitter_id > data_count) { + if (header.splitter_id < 0 || static_cast<std::size_t>(header.splitter_id) > data_count) { LOG_ERROR(Audio, "Bad splitter data id"); break; } @@ -364,7 +364,7 @@ bool SplitterContext::RecomposeDestination(ServerSplitterInfo& info, // Clear our current destinations auto* current_head = info.GetHead(); while (current_head != nullptr) { - auto next_head = current_head->GetNextDestination(); + auto* next_head = current_head->GetNextDestination(); current_head->SetNextDestination(nullptr); current_head = next_head; } @@ -434,7 +434,7 @@ const std::vector<s32>& NodeStates::GetIndexList() const { } void NodeStates::PushTsortResult(s32 index) { - ASSERT(index < node_count); + ASSERT(index < static_cast<s32>(node_count)); index_list[index_pos++] = index; } @@ -471,8 +471,8 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) { continue; } - const auto node_count = edge_matrix.GetNodeCount(); - for (s32 j = 0; j < static_cast<s32>(node_count); j++) { + const auto edge_node_count = edge_matrix.GetNodeCount(); + for (s32 j = 0; j < static_cast<s32>(edge_node_count); j++) { // Check if our node is connected to our edge matrix if (!edge_matrix.Connected(current_stack_index, j)) { continue; diff --git a/src/audio_core/splitter_context.h b/src/audio_core/splitter_context.h index ea6239fdb..b490627f5 100644 --- a/src/audio_core/splitter_context.h +++ b/src/audio_core/splitter_context.h @@ -63,7 +63,7 @@ public: NodeStates(); ~NodeStates(); - void Initialize(std::size_t _node_count); + void Initialize(std::size_t node_count_); bool Tsort(EdgeMatrix& edge_matrix); std::size_t GetIndexPos() const; const std::vector<s32>& GetIndexList() const; @@ -72,15 +72,15 @@ private: void PushTsortResult(s32 index); bool DepthFirstSearch(EdgeMatrix& edge_matrix); void ResetState(); - void UpdateState(NodeStates::State state, std::size_t i); - NodeStates::State GetState(std::size_t i); + void UpdateState(State state, std::size_t i); + State GetState(std::size_t i); std::size_t node_count{}; std::vector<bool> was_node_found{}; std::vector<bool> was_node_completed{}; std::size_t index_pos{}; std::vector<s32> index_list{}; - NodeStates::Stack index_stack{}; + Stack index_stack{}; }; enum class SplitterMagic : u32_le { @@ -97,8 +97,7 @@ public: s32_le data_count{}; INSERT_PADDING_WORDS(5); }; - static_assert(sizeof(SplitterInfo::InHeader) == 0x20, - "SplitterInfo::InHeader is an invalid size"); + static_assert(sizeof(InHeader) == 0x20, "SplitterInfo::InHeader is an invalid size"); struct InInfoPrams { SplitterMagic magic{}; @@ -107,8 +106,7 @@ public: s32_le length{}; s32_le resource_id_base{}; }; - static_assert(sizeof(SplitterInfo::InInfoPrams) == 0x14, - "SplitterInfo::InInfoPrams is an invalid size"); + static_assert(sizeof(InInfoPrams) == 0x14, "SplitterInfo::InInfoPrams is an invalid size"); struct InDestinationParams { SplitterMagic magic{}; @@ -118,13 +116,13 @@ public: bool in_use{}; INSERT_PADDING_BYTES(3); }; - static_assert(sizeof(SplitterInfo::InDestinationParams) == 0x70, + static_assert(sizeof(InDestinationParams) == 0x70, "SplitterInfo::InDestinationParams is an invalid size"); }; class ServerSplitterDestinationData { public: - explicit ServerSplitterDestinationData(s32 id); + explicit ServerSplitterDestinationData(s32 id_); ~ServerSplitterDestinationData(); void Update(SplitterInfo::InDestinationParams& header); @@ -153,7 +151,7 @@ private: class ServerSplitterInfo { public: - explicit ServerSplitterInfo(s32 id); + explicit ServerSplitterInfo(s32 id_); ~ServerSplitterInfo(); void InitializeInfos(); diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index cb33926bc..afe68c9ed 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp @@ -12,7 +12,6 @@ #include "common/assert.h" #include "common/logging/log.h" #include "core/core_timing.h" -#include "core/core_timing_util.h" #include "core/settings.h" namespace AudioCore { @@ -32,10 +31,10 @@ u32 Stream::GetNumChannels() const { return {}; } -Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format format, - ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_) - : sample_rate{sample_rate}, format{format}, release_callback{std::move(release_callback)}, - sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} { +Stream::Stream(Core::Timing::CoreTiming& core_timing_, u32 sample_rate_, Format format_, + ReleaseCallback&& release_callback_, SinkStream& sink_stream_, std::string&& name_) + : sample_rate{sample_rate_}, format{format_}, release_callback{std::move(release_callback_)}, + sink_stream{sink_stream_}, core_timing{core_timing_}, name{std::move(name_)} { release_event = Core::Timing::CreateEvent(name, [this](std::uintptr_t, std::chrono::nanoseconds ns_late) { ReleaseActiveBuffer(ns_late); @@ -123,7 +122,7 @@ bool Stream::QueueBuffer(BufferPtr&& buffer) { return false; } -bool Stream::ContainsBuffer(Buffer::Tag tag) const { +bool Stream::ContainsBuffer([[maybe_unused]] Buffer::Tag tag) const { UNIMPLEMENTED(); return {}; } @@ -131,7 +130,25 @@ bool Stream::ContainsBuffer(Buffer::Tag tag) const { std::vector<Buffer::Tag> Stream::GetTagsAndReleaseBuffers(std::size_t max_count) { std::vector<Buffer::Tag> tags; for (std::size_t count = 0; count < max_count && !released_buffers.empty(); ++count) { - tags.push_back(released_buffers.front()->GetTag()); + if (released_buffers.front()) { + tags.push_back(released_buffers.front()->GetTag()); + } else { + ASSERT_MSG(false, "Invalid tag in released_buffers!"); + } + released_buffers.pop(); + } + return tags; +} + +std::vector<Buffer::Tag> Stream::GetTagsAndReleaseBuffers() { + std::vector<Buffer::Tag> tags; + tags.reserve(released_buffers.size()); + while (!released_buffers.empty()) { + if (released_buffers.front()) { + tags.push_back(released_buffers.front()->GetTag()); + } else { + ASSERT_MSG(false, "Invalid tag in released_buffers!"); + } released_buffers.pop(); } return tags; diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h index 6437b8591..506ac536b 100644 --- a/src/audio_core/stream.h +++ b/src/audio_core/stream.h @@ -44,8 +44,8 @@ public: /// Callback function type, used to change guest state on a buffer being released using ReleaseCallback = std::function<void()>; - Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format format, - ReleaseCallback&& release_callback, SinkStream& sink_stream, std::string&& name_); + Stream(Core::Timing::CoreTiming& core_timing_, u32 sample_rate_, Format format_, + ReleaseCallback&& release_callback_, SinkStream& sink_stream_, std::string&& name_); /// Plays the audio stream void Play(); @@ -57,37 +57,40 @@ public: bool QueueBuffer(BufferPtr&& buffer); /// Returns true if the audio stream contains a buffer with the specified tag - bool ContainsBuffer(Buffer::Tag tag) const; + [[nodiscard]] bool ContainsBuffer(Buffer::Tag tag) const; /// Returns a vector of recently released buffers specified by tag - std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(std::size_t max_count); + [[nodiscard]] std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(std::size_t max_count); + + /// Returns a vector of all recently released buffers specified by tag + [[nodiscard]] std::vector<Buffer::Tag> GetTagsAndReleaseBuffers(); void SetVolume(float volume); - float GetVolume() const { + [[nodiscard]] float GetVolume() const { return game_volume; } /// Returns true if the stream is currently playing - bool IsPlaying() const { + [[nodiscard]] bool IsPlaying() const { return state == State::Playing; } /// Returns the number of queued buffers - std::size_t GetQueueSize() const { + [[nodiscard]] std::size_t GetQueueSize() const { return queued_buffers.size(); } /// Gets the sample rate - u32 GetSampleRate() const { + [[nodiscard]] u32 GetSampleRate() const { return sample_rate; } /// Gets the number of channels - u32 GetNumChannels() const; + [[nodiscard]] u32 GetNumChannels() const; /// Get the state - State GetState() const; + [[nodiscard]] State GetState() const; private: /// Plays the next queued buffer in the audio stream, starting playback if necessary @@ -97,7 +100,7 @@ private: void ReleaseActiveBuffer(std::chrono::nanoseconds ns_late = {}); /// Gets the number of core cycles when the specified buffer will be released - std::chrono::nanoseconds GetBufferReleaseNS(const Buffer& buffer) const; + [[nodiscard]] std::chrono::nanoseconds GetBufferReleaseNS(const Buffer& buffer) const; u32 sample_rate; ///< Sample rate of the stream Format format; ///< Format of the stream diff --git a/src/audio_core/voice_context.cpp b/src/audio_core/voice_context.cpp index 1d8f69844..867b8fc6b 100644 --- a/src/audio_core/voice_context.cpp +++ b/src/audio_core/voice_context.cpp @@ -8,7 +8,7 @@ namespace AudioCore { -ServerVoiceChannelResource::ServerVoiceChannelResource(s32 id) : id(id) {} +ServerVoiceChannelResource::ServerVoiceChannelResource(s32 id_) : id(id_) {} ServerVoiceChannelResource::~ServerVoiceChannelResource() = default; bool ServerVoiceChannelResource::InUse() const { @@ -128,7 +128,10 @@ void ServerVoiceInfo::UpdateParameters(const VoiceInfo::InParams& voice_in, in_params.wave_buffer_count = voice_in.wave_buffer_count; in_params.wave_bufffer_head = voice_in.wave_buffer_head; if (behavior_info.IsFlushVoiceWaveBuffersSupported()) { - in_params.wave_buffer_flush_request_count += voice_in.wave_buffer_flush_request_count; + const auto in_request_count = in_params.wave_buffer_flush_request_count; + const auto voice_request_count = voice_in.wave_buffer_flush_request_count; + in_params.wave_buffer_flush_request_count = + static_cast<u8>(in_request_count + voice_request_count); } in_params.mix_id = voice_in.mix_id; if (behavior_info.IsSplitterSupported()) { @@ -206,7 +209,8 @@ void ServerVoiceInfo::UpdateWaveBuffers( void ServerVoiceInfo::UpdateWaveBuffer(ServerWaveBuffer& out_wavebuffer, const WaveBuffer& in_wave_buffer, SampleFormat sample_format, - bool is_buffer_valid, BehaviorInfo& behavior_info) { + bool is_buffer_valid, + [[maybe_unused]] BehaviorInfo& behavior_info) { if (!is_buffer_valid && out_wavebuffer.sent_to_dsp) { out_wavebuffer.buffer_address = 0; out_wavebuffer.buffer_size = 0; @@ -397,7 +401,7 @@ bool ServerVoiceInfo::HasValidWaveBuffer(const VoiceState* state) const { return std::find(valid_wb.begin(), valid_wb.end(), true) != valid_wb.end(); } -VoiceContext::VoiceContext(std::size_t voice_count) : voice_count(voice_count) { +VoiceContext::VoiceContext(std::size_t voice_count_) : voice_count{voice_count_} { for (std::size_t i = 0; i < voice_count; i++) { voice_channel_resources.emplace_back(static_cast<s32>(i)); sorted_voice_info.push_back(&voice_info.emplace_back()); @@ -488,11 +492,11 @@ s32 VoiceContext::DecodePcm16(s32* output_buffer, ServerWaveBuffer* wave_buffer, // Fast path if (channel_count == 1) { - for (std::size_t i = 0; i < samples_processed; i++) { + for (std::ptrdiff_t i = 0; i < samples_processed; i++) { output_buffer[i] = buffer_data[i]; } } else { - for (std::size_t i = 0; i < samples_processed; i++) { + for (std::ptrdiff_t i = 0; i < samples_processed; i++) { output_buffer[i] = buffer_data[i * channel_count + channel]; } } diff --git a/src/audio_core/voice_context.h b/src/audio_core/voice_context.h index 59d3d7dfb..863248761 100644 --- a/src/audio_core/voice_context.h +++ b/src/audio_core/voice_context.h @@ -118,12 +118,12 @@ public: bool in_use{}; INSERT_PADDING_BYTES(11); }; - static_assert(sizeof(VoiceChannelResource::InParams) == 0x70, "InParams is an invalid size"); + static_assert(sizeof(InParams) == 0x70, "InParams is an invalid size"); }; class ServerVoiceChannelResource { public: - explicit ServerVoiceChannelResource(s32 id); + explicit ServerVoiceChannelResource(s32 id_); ~ServerVoiceChannelResource(); bool InUse() const; @@ -174,7 +174,7 @@ public: BehaviorFlags behavior_flags{}; INSERT_PADDING_BYTES(16); }; - static_assert(sizeof(VoiceInfo::InParams) == 0x170, "InParams is an invalid size"); + static_assert(sizeof(InParams) == 0x170, "InParams is an invalid size"); struct OutParams { u64_le played_sample_count{}; @@ -182,7 +182,7 @@ public: u8 voice_dropped{}; INSERT_PADDING_BYTES(3); }; - static_assert(sizeof(VoiceInfo::OutParams) == 0x10, "OutParams is an invalid size"); + static_assert(sizeof(OutParams) == 0x10, "OutParams is an invalid size"); }; class ServerVoiceInfo { @@ -263,7 +263,7 @@ private: class VoiceContext { public: - VoiceContext(std::size_t voice_count); + explicit VoiceContext(std::size_t voice_count_); ~VoiceContext(); std::size_t GetVoiceCount() const; |