summaryrefslogtreecommitdiffstats
path: root/src/audio_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_core')
-rw-r--r--src/audio_core/CMakeLists.txt18
-rw-r--r--src/audio_core/algorithm/filter.cpp9
-rw-r--r--src/audio_core/algorithm/filter.h4
-rw-r--r--src/audio_core/algorithm/interpolate.cpp7
-rw-r--r--src/audio_core/audio_out.cpp4
-rw-r--r--src/audio_core/audio_out.h3
-rw-r--r--src/audio_core/audio_renderer.cpp131
-rw-r--r--src/audio_core/audio_renderer.h29
-rw-r--r--src/audio_core/behavior_info.cpp6
-rw-r--r--src/audio_core/behavior_info.h30
-rw-r--r--src/audio_core/buffer.h2
-rw-r--r--src/audio_core/codec.cpp5
-rw-r--r--src/audio_core/codec.h2
-rw-r--r--src/audio_core/command_generator.cpp47
-rw-r--r--src/audio_core/command_generator.h23
-rw-r--r--src/audio_core/common.h3
-rw-r--r--src/audio_core/cubeb_sink.cpp26
-rw-r--r--src/audio_core/effect_context.cpp68
-rw-r--r--src/audio_core/effect_context.h53
-rw-r--r--src/audio_core/info_updater.cpp37
-rw-r--r--src/audio_core/info_updater.h4
-rw-r--r--src/audio_core/memory_pool.cpp13
-rw-r--r--src/audio_core/memory_pool.h11
-rw-r--r--src/audio_core/mix_context.cpp4
-rw-r--r--src/audio_core/mix_context.h26
-rw-r--r--src/audio_core/sink_context.cpp20
-rw-r--r--src/audio_core/sink_context.h29
-rw-r--r--src/audio_core/splitter_context.cpp28
-rw-r--r--src/audio_core/splitter_context.h20
-rw-r--r--src/audio_core/stream.cpp31
-rw-r--r--src/audio_core/stream.h25
-rw-r--r--src/audio_core/voice_context.cpp16
-rw-r--r--src/audio_core/voice_context.h10
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;