summaryrefslogtreecommitdiff
path: root/src/audio_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_core')
-rw-r--r--src/audio_core/CMakeLists.txt6
-rw-r--r--src/audio_core/algorithm/interpolate.cpp6
-rw-r--r--src/audio_core/audio_renderer.cpp4
-rw-r--r--src/audio_core/codec.cpp6
-rw-r--r--src/audio_core/command_generator.cpp212
-rw-r--r--src/audio_core/command_generator.h4
-rw-r--r--src/audio_core/cubeb_sink.cpp2
-rw-r--r--src/audio_core/cubeb_sink.h2
-rw-r--r--src/audio_core/info_updater.cpp4
-rw-r--r--src/audio_core/mix_context.cpp17
-rw-r--r--src/audio_core/sink_context.cpp5
-rw-r--r--src/audio_core/splitter_context.cpp60
-rw-r--r--src/audio_core/time_stretch.h10
-rw-r--r--src/audio_core/voice_context.cpp47
14 files changed, 171 insertions, 214 deletions
diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt
index 74c1453aa..68c67507b 100644
--- a/src/audio_core/CMakeLists.txt
+++ b/src/audio_core/CMakeLists.txt
@@ -51,10 +51,12 @@ if (NOT MSVC)
51 -Werror=implicit-fallthrough 51 -Werror=implicit-fallthrough
52 -Werror=reorder 52 -Werror=reorder
53 -Werror=sign-compare 53 -Werror=sign-compare
54 -Werror=sign-conversion 54 -Werror=unused-variable
55
55 $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> 56 $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
56 $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> 57 $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable>
57 -Werror=unused-variable 58
59 -Wno-sign-conversion
58 ) 60 )
59endif() 61endif()
60 62
diff --git a/src/audio_core/algorithm/interpolate.cpp b/src/audio_core/algorithm/interpolate.cpp
index 587ee5b7b..699fcb84c 100644
--- a/src/audio_core/algorithm/interpolate.cpp
+++ b/src/audio_core/algorithm/interpolate.cpp
@@ -167,8 +167,8 @@ std::vector<s16> Interpolate(InterpolationState& state, std::vector<s16> input,
167 output.reserve(static_cast<std::size_t>(static_cast<double>(input.size()) / ratio + 167 output.reserve(static_cast<std::size_t>(static_cast<double>(input.size()) / ratio +
168 InterpolationState::taps)); 168 InterpolationState::taps));
169 169
170 for (std::size_t frame = 0; frame < num_frames; ++frame) { 170 for (std::size_t frame{}; frame < num_frames; ++frame) {
171 const auto lut_index{static_cast<size_t>(state.fraction >> 8) * InterpolationState::taps}; 171 const std::size_t lut_index{(state.fraction >> 8) * InterpolationState::taps};
172 172
173 std::rotate(state.history.begin(), state.history.end() - 1, state.history.end()); 173 std::rotate(state.history.begin(), state.history.end() - 1, state.history.end());
174 state.history[0][0] = input[frame * 2 + 0]; 174 state.history[0][0] = input[frame * 2 + 0];
@@ -225,7 +225,7 @@ void Resample(s32* output, const s32* input, s32 pitch, s32& fraction, std::size
225 225
226 output[i] = (l0 * s0 + l1 * s1 + l2 * s2 + l3 * s3) >> 15; 226 output[i] = (l0 * s0 + l1 * s1 + l2 * s2 + l3 * s3) >> 15;
227 fraction += pitch; 227 fraction += pitch;
228 index += static_cast<size_t>(fraction >> 15); 228 index += (fraction >> 15);
229 fraction &= 0x7fff; 229 fraction &= 0x7fff;
230 } 230 }
231} 231}
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index 094bace9c..a7e851bb8 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -187,8 +187,8 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
187 const auto& in_params = final_mix.GetInParams(); 187 const auto& in_params = final_mix.GetInParams();
188 std::vector<s32*> mix_buffers(channel_count); 188 std::vector<s32*> mix_buffers(channel_count);
189 for (std::size_t i = 0; i < channel_count; i++) { 189 for (std::size_t i = 0; i < channel_count; i++) {
190 mix_buffers[i] = command_generator.GetMixBuffer( 190 mix_buffers[i] =
191 static_cast<u32>(in_params.buffer_offset) + buffer_offsets[i]); 191 command_generator.GetMixBuffer(in_params.buffer_offset + buffer_offsets[i]);
192 } 192 }
193 193
194 for (std::size_t i = 0; i < BUFFER_SIZE; i++) { 194 for (std::size_t i = 0; i < BUFFER_SIZE; i++) {
diff --git a/src/audio_core/codec.cpp b/src/audio_core/codec.cpp
index d89f94ea2..2fb91c13a 100644
--- a/src/audio_core/codec.cpp
+++ b/src/audio_core/codec.cpp
@@ -32,7 +32,7 @@ std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM
32 for (std::size_t framei = 0; framei < NUM_FRAMES; framei++) { 32 for (std::size_t framei = 0; framei < NUM_FRAMES; framei++) {
33 const int frame_header = data[framei * FRAME_LEN]; 33 const int frame_header = data[framei * FRAME_LEN];
34 const int scale = 1 << (frame_header & 0xF); 34 const int scale = 1 << (frame_header & 0xF);
35 const auto idx = static_cast<size_t>((frame_header >> 4) & 0x7); 35 const int idx = (frame_header >> 4) & 0x7;
36 36
37 // Coefficients are fixed point with 11 bits fractional part. 37 // Coefficients are fixed point with 11 bits fractional part.
38 const int coef1 = coeff[idx * 2 + 0]; 38 const int coef1 = coeff[idx * 2 + 0];
@@ -57,11 +57,11 @@ std::vector<s16> DecodeADPCM(const u8* const data, std::size_t size, const ADPCM
57 std::size_t outputi = framei * SAMPLES_PER_FRAME; 57 std::size_t outputi = framei * SAMPLES_PER_FRAME;
58 std::size_t datai = framei * FRAME_LEN + 1; 58 std::size_t datai = framei * FRAME_LEN + 1;
59 for (std::size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) { 59 for (std::size_t i = 0; i < SAMPLES_PER_FRAME && outputi < sample_count; i += 2) {
60 const s16 sample1 = decode_sample(SIGNED_NIBBLES[static_cast<u32>(data[datai] >> 4)]); 60 const s16 sample1 = decode_sample(SIGNED_NIBBLES[data[datai] >> 4]);
61 ret[outputi] = sample1; 61 ret[outputi] = sample1;
62 outputi++; 62 outputi++;
63 63
64 const s16 sample2 = decode_sample(SIGNED_NIBBLES[static_cast<u32>(data[datai] & 0xF)]); 64 const s16 sample2 = decode_sample(SIGNED_NIBBLES[data[datai] & 0xF]);
65 ret[outputi] = sample2; 65 ret[outputi] = sample2;
66 outputi++; 66 outputi++;
67 67
diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp
index c0edb625d..fb8700ccf 100644
--- a/src/audio_core/command_generator.cpp
+++ b/src/audio_core/command_generator.cpp
@@ -15,8 +15,8 @@ constexpr std::size_t MIX_BUFFER_SIZE = 0x3f00;
15constexpr std::size_t SCALED_MIX_BUFFER_SIZE = MIX_BUFFER_SIZE << 15ULL; 15constexpr std::size_t SCALED_MIX_BUFFER_SIZE = MIX_BUFFER_SIZE << 15ULL;
16 16
17template <std::size_t N> 17template <std::size_t N>
18void ApplyMix(s32* output, const s32* input, s32 gain, std::size_t sample_count) { 18void ApplyMix(s32* output, const s32* input, s32 gain, s32 sample_count) {
19 for (std::size_t i = 0; i < sample_count; i += N) { 19 for (std::size_t i = 0; i < static_cast<std::size_t>(sample_count); i += N) {
20 for (std::size_t j = 0; j < N; j++) { 20 for (std::size_t j = 0; j < N; j++) {
21 output[i + j] += 21 output[i + j] +=
22 static_cast<s32>((static_cast<s64>(input[i + j]) * gain + 0x4000) >> 15); 22 static_cast<s32>((static_cast<s64>(input[i + j]) * gain + 0x4000) >> 15);
@@ -111,8 +111,7 @@ void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) {
111 const auto channel_count = in_params.channel_count; 111 const auto channel_count = in_params.channel_count;
112 112
113 for (s32 channel = 0; channel < channel_count; channel++) { 113 for (s32 channel = 0; channel < channel_count; channel++) {
114 const auto resource_id = 114 const auto resource_id = in_params.voice_channel_resource_id[channel];
115 static_cast<u32>(in_params.voice_channel_resource_id[static_cast<u32>(channel)]);
116 auto& dsp_state = voice_context.GetDspSharedState(resource_id); 115 auto& dsp_state = voice_context.GetDspSharedState(resource_id);
117 auto& channel_resource = voice_context.GetChannelResource(resource_id); 116 auto& channel_resource = voice_context.GetChannelResource(resource_id);
118 117
@@ -133,15 +132,14 @@ void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) {
133 132
134 if (in_params.mix_id != AudioCommon::NO_MIX) { 133 if (in_params.mix_id != AudioCommon::NO_MIX) {
135 // If we're using a mix id 134 // If we're using a mix id
136 auto& mix_info = mix_context.GetInfo(static_cast<u32>(in_params.mix_id)); 135 auto& mix_info = mix_context.GetInfo(in_params.mix_id);
137 const auto& dest_mix_params = mix_info.GetInParams(); 136 const auto& dest_mix_params = mix_info.GetInParams();
138 137
139 // Voice Mixing 138 // Voice Mixing
140 GenerateVoiceMixCommand( 139 GenerateVoiceMixCommand(
141 channel_resource.GetCurrentMixVolume(), channel_resource.GetLastMixVolume(), 140 channel_resource.GetCurrentMixVolume(), channel_resource.GetLastMixVolume(),
142 dsp_state, static_cast<u32>(dest_mix_params.buffer_offset), 141 dsp_state, dest_mix_params.buffer_offset, dest_mix_params.buffer_count,
143 static_cast<u32>(dest_mix_params.buffer_count), 142 worker_params.mix_buffer_count + channel, in_params.node_id);
144 worker_params.mix_buffer_count + static_cast<u32>(channel), in_params.node_id);
145 143
146 // Update last mix volumes 144 // Update last mix volumes
147 channel_resource.UpdateLastMixVolumes(); 145 channel_resource.UpdateLastMixVolumes();
@@ -158,15 +156,12 @@ void CommandGenerator::GenerateVoiceCommand(ServerVoiceInfo& voice_info) {
158 continue; 156 continue;
159 } 157 }
160 158
161 const auto& mix_info = 159 const auto& mix_info = mix_context.GetInfo(destination_data->GetMixId());
162 mix_context.GetInfo(static_cast<u32>(destination_data->GetMixId()));
163 const auto& dest_mix_params = mix_info.GetInParams(); 160 const auto& dest_mix_params = mix_info.GetInParams();
164 GenerateVoiceMixCommand( 161 GenerateVoiceMixCommand(
165 destination_data->CurrentMixVolumes(), destination_data->LastMixVolumes(), 162 destination_data->CurrentMixVolumes(), destination_data->LastMixVolumes(),
166 dsp_state, static_cast<u32>(dest_mix_params.buffer_offset), 163 dsp_state, dest_mix_params.buffer_offset, dest_mix_params.buffer_count,
167 static_cast<u32>(dest_mix_params.buffer_count), 164 worker_params.mix_buffer_count + channel, in_params.node_id);
168 worker_params.mix_buffer_count + static_cast<u32>(channel),
169 in_params.node_id);
170 destination_data->MarkDirty(); 165 destination_data->MarkDirty();
171 } 166 }
172 } 167 }
@@ -224,10 +219,9 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo
224 219
225 if (depop) { 220 if (depop) {
226 if (in_params.mix_id != AudioCommon::NO_MIX) { 221 if (in_params.mix_id != AudioCommon::NO_MIX) {
227 auto& mix_info = mix_context.GetInfo(static_cast<u32>(in_params.mix_id)); 222 auto& mix_info = mix_context.GetInfo(in_params.mix_id);
228 const auto& mix_in = mix_info.GetInParams(); 223 const auto& mix_in = mix_info.GetInParams();
229 GenerateDepopPrepareCommand(dsp_state, static_cast<u32>(mix_in.buffer_count), 224 GenerateDepopPrepareCommand(dsp_state, mix_in.buffer_count, mix_in.buffer_offset);
230 static_cast<u32>(mix_in.buffer_offset));
231 } else if (in_params.splitter_info_id != AudioCommon::NO_SPLITTER) { 225 } else if (in_params.splitter_info_id != AudioCommon::NO_SPLITTER) {
232 s32 index{}; 226 s32 index{};
233 while (const auto* destination = 227 while (const auto* destination =
@@ -235,24 +229,23 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo
235 if (!destination->IsConfigured()) { 229 if (!destination->IsConfigured()) {
236 continue; 230 continue;
237 } 231 }
238 auto& mix_info = mix_context.GetInfo(static_cast<u32>(destination->GetMixId())); 232 auto& mix_info = mix_context.GetInfo(destination->GetMixId());
239 const auto& mix_in = mix_info.GetInParams(); 233 const auto& mix_in = mix_info.GetInParams();
240 GenerateDepopPrepareCommand(dsp_state, static_cast<u32>(mix_in.buffer_count), 234 GenerateDepopPrepareCommand(dsp_state, mix_in.buffer_count, mix_in.buffer_offset);
241 static_cast<u32>(mix_in.buffer_offset));
242 } 235 }
243 } 236 }
244 } else { 237 } else {
245 switch (in_params.sample_format) { 238 switch (in_params.sample_format) {
246 case SampleFormat::Pcm16: 239 case SampleFormat::Pcm16:
247 DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(channel), dsp_state, channel, 240 DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(channel), dsp_state, channel,
248 static_cast<s32>(worker_params.sample_rate), 241 worker_params.sample_rate, worker_params.sample_count,
249 static_cast<s32>(worker_params.sample_count), in_params.node_id); 242 in_params.node_id);
250 break; 243 break;
251 case SampleFormat::Adpcm: 244 case SampleFormat::Adpcm:
252 ASSERT(channel == 0 && in_params.channel_count == 1); 245 ASSERT(channel == 0 && in_params.channel_count == 1);
253 DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(0), dsp_state, 0, 246 DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(0), dsp_state, 0,
254 static_cast<s32>(worker_params.sample_rate), 247 worker_params.sample_rate, worker_params.sample_count,
255 static_cast<s32>(worker_params.sample_count), in_params.node_id); 248 in_params.node_id);
256 break; 249 break;
257 default: 250 default:
258 UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format); 251 UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format);
@@ -262,7 +255,7 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo
262 255
263void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info, 256void CommandGenerator::GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info,
264 VoiceState& dsp_state, 257 VoiceState& dsp_state,
265 u32 mix_buffer_count, s32 channel) { 258 s32 mix_buffer_count, s32 channel) {
266 for (std::size_t i = 0; i < AudioCommon::MAX_BIQUAD_FILTERS; i++) { 259 for (std::size_t i = 0; i < AudioCommon::MAX_BIQUAD_FILTERS; i++) {
267 const auto& in_params = voice_info.GetInParams(); 260 const auto& in_params = voice_info.GetInParams();
268 auto& biquad_filter = in_params.biquad_filter[i]; 261 auto& biquad_filter = in_params.biquad_filter[i];
@@ -342,8 +335,8 @@ void CommandGenerator::GenerateDepopForMixBuffersCommand(std::size_t mix_buffer_
342 continue; 335 continue;
343 } 336 }
344 337
345 depop_buffer[i] = ApplyMixDepop(GetMixBuffer(i), depop_buffer[i], delta, 338 depop_buffer[i] =
346 static_cast<s32>(worker_params.sample_count)); 339 ApplyMixDepop(GetMixBuffer(i), depop_buffer[i], delta, worker_params.sample_count);
347 } 340 }
348} 341}
349 342
@@ -355,7 +348,7 @@ void CommandGenerator::GenerateEffectCommand(ServerMixInfo& mix_info) {
355 if (index == AudioCommon::NO_EFFECT_ORDER) { 348 if (index == AudioCommon::NO_EFFECT_ORDER) {
356 break; 349 break;
357 } 350 }
358 auto* info = effect_context.GetInfo(static_cast<u32>(index)); 351 auto* info = effect_context.GetInfo(index);
359 const auto type = info->GetType(); 352 const auto type = info->GetType();
360 353
361 // TODO(ogniK): Finish remaining effects 354 // TODO(ogniK): Finish remaining effects
@@ -384,11 +377,11 @@ void CommandGenerator::GenerateI3dl2ReverbEffectCommand(s32 mix_buffer_offset, E
384 } 377 }
385 const auto& params = dynamic_cast<EffectI3dl2Reverb*>(info)->GetParams(); 378 const auto& params = dynamic_cast<EffectI3dl2Reverb*>(info)->GetParams();
386 const auto channel_count = params.channel_count; 379 const auto channel_count = params.channel_count;
387 for (size_t i = 0; i < channel_count; i++) { 380 for (s32 i = 0; i < channel_count; i++) {
388 // TODO(ogniK): Actually implement reverb 381 // TODO(ogniK): Actually implement reverb
389 if (params.input[i] != params.output[i]) { 382 if (params.input[i] != params.output[i]) {
390 const auto* input = GetMixBuffer(static_cast<u32>(mix_buffer_offset + params.input[i])); 383 const auto* input = GetMixBuffer(mix_buffer_offset + params.input[i]);
391 auto* output = GetMixBuffer(static_cast<u32>(mix_buffer_offset + params.output[i])); 384 auto* output = GetMixBuffer(mix_buffer_offset + params.output[i]);
392 ApplyMix<1>(output, input, 32768, worker_params.sample_count); 385 ApplyMix<1>(output, input, 32768, worker_params.sample_count);
393 } 386 }
394 } 387 }
@@ -399,14 +392,13 @@ void CommandGenerator::GenerateBiquadFilterEffectCommand(s32 mix_buffer_offset,
399 if (!enabled) { 392 if (!enabled) {
400 return; 393 return;
401 } 394 }
402
403 const auto& params = dynamic_cast<EffectBiquadFilter*>(info)->GetParams(); 395 const auto& params = dynamic_cast<EffectBiquadFilter*>(info)->GetParams();
404 const auto channel_count = static_cast<u32>(params.channel_count); 396 const auto channel_count = params.channel_count;
405 for (size_t i = 0; i < channel_count; i++) { 397 for (s32 i = 0; i < channel_count; i++) {
406 // TODO(ogniK): Actually implement biquad filter 398 // TODO(ogniK): Actually implement biquad filter
407 if (params.input[i] != params.output[i]) { 399 if (params.input[i] != params.output[i]) {
408 const auto* input = GetMixBuffer(static_cast<u32>(mix_buffer_offset + params.input[i])); 400 const auto* input = GetMixBuffer(mix_buffer_offset + params.input[i]);
409 auto* output = GetMixBuffer(static_cast<u32>(mix_buffer_offset + params.output[i])); 401 auto* output = GetMixBuffer(mix_buffer_offset + params.output[i]);
410 ApplyMix<1>(output, input, 32768, worker_params.sample_count); 402 ApplyMix<1>(output, input, 32768, worker_params.sample_count);
411 } 403 }
412 } 404 }
@@ -433,30 +425,26 @@ void CommandGenerator::GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* inf
433 memory.ReadBlock(aux->GetSendInfo(), &send_info, sizeof(AuxInfoDSP)); 425 memory.ReadBlock(aux->GetSendInfo(), &send_info, sizeof(AuxInfoDSP));
434 memory.ReadBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP)); 426 memory.ReadBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP));
435 427
436 WriteAuxBuffer(send_info, aux->GetSendBuffer(), 428 WriteAuxBuffer(send_info, aux->GetSendBuffer(), params.sample_count,
437 static_cast<u32>(params.sample_count), 429 GetMixBuffer(input_index), worker_params.sample_count, offset,
438 GetMixBuffer(static_cast<u32>(input_index)), 430 write_count);
439 worker_params.sample_count, offset, write_count);
440 memory.WriteBlock(aux->GetSendInfo(), &send_info, sizeof(AuxInfoDSP)); 431 memory.WriteBlock(aux->GetSendInfo(), &send_info, sizeof(AuxInfoDSP));
441 432
442 const auto samples_read = ReadAuxBuffer( 433 const auto samples_read = ReadAuxBuffer(
443 recv_info, aux->GetRecvBuffer(), static_cast<u32>(params.sample_count), 434 recv_info, aux->GetRecvBuffer(), params.sample_count,
444 GetMixBuffer(static_cast<u32>(output_index)), worker_params.sample_count, 435 GetMixBuffer(output_index), worker_params.sample_count, offset, write_count);
445 offset, write_count);
446 memory.WriteBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP)); 436 memory.WriteBlock(aux->GetRecvInfo(), &recv_info, sizeof(AuxInfoDSP));
447 437
448 if (samples_read != static_cast<int>(worker_params.sample_count) && 438 if (samples_read != static_cast<int>(worker_params.sample_count) &&
449 samples_read <= params.sample_count) { 439 samples_read <= params.sample_count) {
450 std::memset(GetMixBuffer(static_cast<u32>(output_index)), 0, 440 std::memset(GetMixBuffer(output_index), 0, params.sample_count - samples_read);
451 static_cast<size_t>(params.sample_count - samples_read));
452 } 441 }
453 } else { 442 } else {
454 AuxInfoDSP empty{}; 443 AuxInfoDSP empty{};
455 memory.WriteBlock(aux->GetSendInfo(), &empty, sizeof(AuxInfoDSP)); 444 memory.WriteBlock(aux->GetSendInfo(), &empty, sizeof(AuxInfoDSP));
456 memory.WriteBlock(aux->GetRecvInfo(), &empty, sizeof(AuxInfoDSP)); 445 memory.WriteBlock(aux->GetRecvInfo(), &empty, sizeof(AuxInfoDSP));
457 if (output_index != input_index) { 446 if (output_index != input_index) {
458 std::memcpy(GetMixBuffer(static_cast<u32>(output_index)), 447 std::memcpy(GetMixBuffer(output_index), GetMixBuffer(input_index),
459 GetMixBuffer(static_cast<u32>(input_index)),
460 worker_params.sample_count * sizeof(s32)); 448 worker_params.sample_count * sizeof(s32));
461 } 449 }
462 } 450 }
@@ -470,8 +458,7 @@ ServerSplitterDestinationData* CommandGenerator::GetDestinationData(s32 splitter
470 if (splitter_id == AudioCommon::NO_SPLITTER) { 458 if (splitter_id == AudioCommon::NO_SPLITTER) {
471 return nullptr; 459 return nullptr;
472 } 460 }
473 return splitter_context.GetDestinationData(static_cast<u32>(splitter_id), 461 return splitter_context.GetDestinationData(splitter_id, index);
474 static_cast<u32>(index));
475} 462}
476 463
477s32 CommandGenerator::WriteAuxBuffer(AuxInfoDSP& dsp_info, VAddr send_buffer, u32 max_samples, 464s32 CommandGenerator::WriteAuxBuffer(AuxInfoDSP& dsp_info, VAddr send_buffer, u32 max_samples,
@@ -501,7 +488,7 @@ s32 CommandGenerator::WriteAuxBuffer(AuxInfoDSP& dsp_info, VAddr send_buffer, u3
501 if (write_count != 0) { 488 if (write_count != 0) {
502 dsp_info.write_offset = (dsp_info.write_offset + write_count) % max_samples; 489 dsp_info.write_offset = (dsp_info.write_offset + write_count) % max_samples;
503 } 490 }
504 return static_cast<s32>(sample_count); 491 return sample_count;
505} 492}
506 493
507s32 CommandGenerator::ReadAuxBuffer(AuxInfoDSP& recv_info, VAddr recv_buffer, u32 max_samples, 494s32 CommandGenerator::ReadAuxBuffer(AuxInfoDSP& recv_info, VAddr recv_buffer, u32 max_samples,
@@ -531,7 +518,7 @@ s32 CommandGenerator::ReadAuxBuffer(AuxInfoDSP& recv_info, VAddr recv_buffer, u3
531 if (read_count != 0) { 518 if (read_count != 0) {
532 recv_info.read_offset = (recv_info.read_offset + read_count) % max_samples; 519 recv_info.read_offset = (recv_info.read_offset + read_count) % max_samples;
533 } 520 }
534 return static_cast<s32>(sample_count); 521 return sample_count;
535} 522}
536 523
537void CommandGenerator::GenerateVolumeRampCommand(float last_volume, float current_volume, 524void CommandGenerator::GenerateVolumeRampCommand(float last_volume, float current_volume,
@@ -550,15 +537,15 @@ void CommandGenerator::GenerateVolumeRampCommand(float last_volume, float curren
550 } 537 }
551 // Apply generic gain on samples 538 // Apply generic gain on samples
552 ApplyGain(GetChannelMixBuffer(channel), GetChannelMixBuffer(channel), last, delta, 539 ApplyGain(GetChannelMixBuffer(channel), GetChannelMixBuffer(channel), last, delta,
553 static_cast<s32>(worker_params.sample_count)); 540 worker_params.sample_count);
554} 541}
555 542
556void CommandGenerator::GenerateVoiceMixCommand(const MixVolumeBuffer& mix_volumes, 543void CommandGenerator::GenerateVoiceMixCommand(const MixVolumeBuffer& mix_volumes,
557 const MixVolumeBuffer& last_mix_volumes, 544 const MixVolumeBuffer& last_mix_volumes,
558 VoiceState& dsp_state, u32 mix_buffer_offset, 545 VoiceState& dsp_state, s32 mix_buffer_offset,
559 u32 mix_buffer_count, u32 voice_index, s32 node_id) { 546 s32 mix_buffer_count, s32 voice_index, s32 node_id) {
560 // Loop all our mix buffers 547 // Loop all our mix buffers
561 for (size_t i = 0; i < mix_buffer_count; i++) { 548 for (s32 i = 0; i < mix_buffer_count; i++) {
562 if (last_mix_volumes[i] != 0.0f || mix_volumes[i] != 0.0f) { 549 if (last_mix_volumes[i] != 0.0f || mix_volumes[i] != 0.0f) {
563 const auto delta = static_cast<float>((mix_volumes[i] - last_mix_volumes[i])) / 550 const auto delta = static_cast<float>((mix_volumes[i] - last_mix_volumes[i])) /
564 static_cast<float>(worker_params.sample_count); 551 static_cast<float>(worker_params.sample_count);
@@ -571,9 +558,9 @@ void CommandGenerator::GenerateVoiceMixCommand(const MixVolumeBuffer& mix_volume
571 mix_volumes[i]); 558 mix_volumes[i]);
572 } 559 }
573 560
574 dsp_state.previous_samples[i] = ApplyMixRamp( 561 dsp_state.previous_samples[i] =
575 GetMixBuffer(mix_buffer_offset + i), GetMixBuffer(voice_index), last_mix_volumes[i], 562 ApplyMixRamp(GetMixBuffer(mix_buffer_offset + i), GetMixBuffer(voice_index),
576 delta, static_cast<s32>(worker_params.sample_count)); 563 last_mix_volumes[i], delta, worker_params.sample_count);
577 } else { 564 } else {
578 dsp_state.previous_samples[i] = 0; 565 dsp_state.previous_samples[i] = 0;
579 } 566 }
@@ -585,8 +572,7 @@ void CommandGenerator::GenerateSubMixCommand(ServerMixInfo& mix_info) {
585 LOG_DEBUG(Audio, "(DSP_TRACE) GenerateSubMixCommand"); 572 LOG_DEBUG(Audio, "(DSP_TRACE) GenerateSubMixCommand");
586 } 573 }
587 const auto& in_params = mix_info.GetInParams(); 574 const auto& in_params = mix_info.GetInParams();
588 GenerateDepopForMixBuffersCommand(static_cast<u32>(in_params.buffer_count), 575 GenerateDepopForMixBuffersCommand(in_params.buffer_count, in_params.buffer_offset,
589 static_cast<u32>(in_params.buffer_offset),
590 in_params.sample_rate); 576 in_params.sample_rate);
591 577
592 GenerateEffectCommand(mix_info); 578 GenerateEffectCommand(mix_info);
@@ -600,18 +586,18 @@ void CommandGenerator::GenerateMixCommands(ServerMixInfo& mix_info) {
600 } 586 }
601 const auto& in_params = mix_info.GetInParams(); 587 const auto& in_params = mix_info.GetInParams();
602 if (in_params.dest_mix_id != AudioCommon::NO_MIX) { 588 if (in_params.dest_mix_id != AudioCommon::NO_MIX) {
603 const auto& dest_mix = mix_context.GetInfo(static_cast<u32>(in_params.dest_mix_id)); 589 const auto& dest_mix = mix_context.GetInfo(in_params.dest_mix_id);
604 const auto& dest_in_params = dest_mix.GetInParams(); 590 const auto& dest_in_params = dest_mix.GetInParams();
605 591
606 const auto buffer_count = static_cast<u32>(in_params.buffer_count); 592 const auto buffer_count = in_params.buffer_count;
607 593
608 for (u32 i = 0; i < buffer_count; i++) { 594 for (s32 i = 0; i < buffer_count; i++) {
609 for (u32 j = 0; j < static_cast<u32>(dest_in_params.buffer_count); j++) { 595 for (s32 j = 0; j < dest_in_params.buffer_count; j++) {
610 const auto mixed_volume = in_params.volume * in_params.mix_volume[i][j]; 596 const auto mixed_volume = in_params.volume * in_params.mix_volume[i][j];
611 if (mixed_volume != 0.0f) { 597 if (mixed_volume != 0.0f) {
612 GenerateMixCommand(static_cast<size_t>(dest_in_params.buffer_offset) + j, 598 GenerateMixCommand(dest_in_params.buffer_offset + j,
613 static_cast<size_t>(in_params.buffer_offset) + i, 599 in_params.buffer_offset + i, mixed_volume,
614 mixed_volume, static_cast<s32>(in_params.node_id)); 600 in_params.node_id);
615 } 601 }
616 } 602 }
617 } 603 }
@@ -622,17 +608,15 @@ void CommandGenerator::GenerateMixCommands(ServerMixInfo& mix_info) {
622 continue; 608 continue;
623 } 609 }
624 610
625 const auto& dest_mix = 611 const auto& dest_mix = mix_context.GetInfo(destination_data->GetMixId());
626 mix_context.GetInfo(static_cast<u32>(destination_data->GetMixId()));
627 const auto& dest_in_params = dest_mix.GetInParams(); 612 const auto& dest_in_params = dest_mix.GetInParams();
628 const auto mix_index = (base - 1) % in_params.buffer_count + in_params.buffer_offset; 613 const auto mix_index = (base - 1) % in_params.buffer_count + in_params.buffer_offset;
629 for (std::size_t i = 0; i < static_cast<std::size_t>(dest_in_params.buffer_count); 614 for (std::size_t i = 0; i < static_cast<std::size_t>(dest_in_params.buffer_count);
630 i++) { 615 i++) {
631 const auto mixed_volume = in_params.volume * destination_data->GetMixVolume(i); 616 const auto mixed_volume = in_params.volume * destination_data->GetMixVolume(i);
632 if (mixed_volume != 0.0f) { 617 if (mixed_volume != 0.0f) {
633 GenerateMixCommand(static_cast<size_t>(dest_in_params.buffer_offset) + i, 618 GenerateMixCommand(dest_in_params.buffer_offset + i, mix_index, mixed_volume,
634 static_cast<size_t>(mix_index), mixed_volume, 619 in_params.node_id);
635 static_cast<s32>(in_params.node_id));
636 } 620 }
637 } 621 }
638 } 622 }
@@ -651,8 +635,7 @@ void CommandGenerator::GenerateMixCommand(std::size_t output_offset, std::size_t
651 auto* output = GetMixBuffer(output_offset); 635 auto* output = GetMixBuffer(output_offset);
652 const auto* input = GetMixBuffer(input_offset); 636 const auto* input = GetMixBuffer(input_offset);
653 637
654 const auto gain = static_cast<s32>(volume * 32768.0f); 638 const s32 gain = static_cast<s32>(volume * 32768.0f);
655
656 // Mix with loop unrolling 639 // Mix with loop unrolling
657 if (worker_params.sample_count % 4 == 0) { 640 if (worker_params.sample_count % 4 == 0) {
658 ApplyMix<4>(output, input, gain, worker_params.sample_count); 641 ApplyMix<4>(output, input, gain, worker_params.sample_count);
@@ -670,8 +653,7 @@ void CommandGenerator::GenerateFinalMixCommand() {
670 auto& mix_info = mix_context.GetFinalMixInfo(); 653 auto& mix_info = mix_context.GetFinalMixInfo();
671 const auto& in_params = mix_info.GetInParams(); 654 const auto& in_params = mix_info.GetInParams();
672 655
673 GenerateDepopForMixBuffersCommand(static_cast<u32>(in_params.buffer_count), 656 GenerateDepopForMixBuffersCommand(in_params.buffer_count, in_params.buffer_offset,
674 static_cast<u32>(in_params.buffer_offset),
675 in_params.sample_rate); 657 in_params.sample_rate);
676 658
677 GenerateEffectCommand(mix_info); 659 GenerateEffectCommand(mix_info);
@@ -685,16 +667,16 @@ void CommandGenerator::GenerateFinalMixCommand() {
685 in_params.node_id, in_params.buffer_offset + i, in_params.buffer_offset + i, 667 in_params.node_id, in_params.buffer_offset + i, in_params.buffer_offset + i,
686 in_params.volume); 668 in_params.volume);
687 } 669 }
688 ApplyGainWithoutDelta(GetMixBuffer(static_cast<size_t>(in_params.buffer_offset + i)), 670 ApplyGainWithoutDelta(GetMixBuffer(in_params.buffer_offset + i),
689 GetMixBuffer(static_cast<size_t>(in_params.buffer_offset + i)), gain, 671 GetMixBuffer(in_params.buffer_offset + i), gain,
690 static_cast<s32>(worker_params.sample_count)); 672 worker_params.sample_count);
691 } 673 }
692} 674}
693 675
694s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_state, 676s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
695 s32 sample_count, s32 channel, std::size_t mix_offset) { 677 s32 sample_count, s32 channel, std::size_t mix_offset) {
696 const auto& in_params = voice_info.GetInParams(); 678 const auto& in_params = voice_info.GetInParams();
697 const auto& wave_buffer = in_params.wave_buffer[static_cast<u32>(dsp_state.wave_buffer_index)]; 679 const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
698 if (wave_buffer.buffer_address == 0) { 680 if (wave_buffer.buffer_address == 0) {
699 return 0; 681 return 0;
700 } 682 }
@@ -707,26 +689,24 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s
707 const auto samples_remaining = 689 const auto samples_remaining =
708 (wave_buffer.end_sample_offset - wave_buffer.start_sample_offset) - dsp_state.offset; 690 (wave_buffer.end_sample_offset - wave_buffer.start_sample_offset) - dsp_state.offset;
709 const auto start_offset = 691 const auto start_offset =
710 static_cast<size_t>((wave_buffer.start_sample_offset + dsp_state.offset) * 692 ((wave_buffer.start_sample_offset + dsp_state.offset) * in_params.channel_count) *
711 in_params.channel_count) *
712 sizeof(s16); 693 sizeof(s16);
713 const auto buffer_pos = wave_buffer.buffer_address + start_offset; 694 const auto buffer_pos = wave_buffer.buffer_address + start_offset;
714 const auto samples_processed = std::min(sample_count, samples_remaining); 695 const auto samples_processed = std::min(sample_count, samples_remaining);
715 696
716 if (in_params.channel_count == 1) { 697 if (in_params.channel_count == 1) {
717 std::vector<s16> buffer(static_cast<size_t>(samples_processed)); 698 std::vector<s16> buffer(samples_processed);
718 memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); 699 memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16));
719 for (std::size_t i = 0; i < buffer.size(); i++) { 700 for (std::size_t i = 0; i < buffer.size(); i++) {
720 sample_buffer[mix_offset + i] = buffer[i]; 701 sample_buffer[mix_offset + i] = buffer[i];
721 } 702 }
722 } else { 703 } else {
723 const auto channel_count = in_params.channel_count; 704 const auto channel_count = in_params.channel_count;
724 std::vector<s16> buffer(static_cast<size_t>(samples_processed * channel_count)); 705 std::vector<s16> buffer(samples_processed * channel_count);
725 memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); 706 memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16));
726 707
727 for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) { 708 for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) {
728 sample_buffer[mix_offset + i] = 709 sample_buffer[mix_offset + i] = buffer[i * channel_count + channel];
729 buffer[i * static_cast<u32>(channel_count) + static_cast<u32>(channel)];
730 } 710 }
731 } 711 }
732 712
@@ -736,7 +716,7 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s
736s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state, 716s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
737 s32 sample_count, s32 channel, std::size_t mix_offset) { 717 s32 sample_count, s32 channel, std::size_t mix_offset) {
738 const auto& in_params = voice_info.GetInParams(); 718 const auto& in_params = voice_info.GetInParams();
739 const auto& wave_buffer = in_params.wave_buffer[static_cast<u32>(dsp_state.wave_buffer_index)]; 719 const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
740 if (wave_buffer.buffer_address == 0) { 720 if (wave_buffer.buffer_address == 0) {
741 return 0; 721 return 0;
742 } 722 }
@@ -756,7 +736,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
756 constexpr std::size_t SAMPLES_PER_FRAME = 14; 736 constexpr std::size_t SAMPLES_PER_FRAME = 14;
757 737
758 auto frame_header = dsp_state.context.header; 738 auto frame_header = dsp_state.context.header;
759 auto idx = static_cast<size_t>((frame_header >> 4) & 0xf); 739 s32 idx = (frame_header >> 4) & 0xf;
760 s32 scale = frame_header & 0xf; 740 s32 scale = frame_header & 0xf;
761 s16 yn1 = dsp_state.context.yn1; 741 s16 yn1 = dsp_state.context.yn1;
762 s16 yn2 = dsp_state.context.yn2; 742 s16 yn2 = dsp_state.context.yn2;
@@ -773,10 +753,9 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
773 const auto samples_processed = std::min(sample_count, samples_remaining); 753 const auto samples_processed = std::min(sample_count, samples_remaining);
774 const auto sample_pos = wave_buffer.start_sample_offset + dsp_state.offset; 754 const auto sample_pos = wave_buffer.start_sample_offset + dsp_state.offset;
775 755
776 const auto samples_remaining_in_frame = static_cast<u32>(sample_pos) % SAMPLES_PER_FRAME; 756 const auto samples_remaining_in_frame = sample_pos % SAMPLES_PER_FRAME;
777 auto position_in_frame = 757 auto position_in_frame = ((sample_pos / SAMPLES_PER_FRAME) * NIBBLES_PER_SAMPLE) +
778 ((static_cast<u32>(sample_pos) / SAMPLES_PER_FRAME) * NIBBLES_PER_SAMPLE) + 758 samples_remaining_in_frame + (samples_remaining_in_frame != 0 ? 2 : 0);
779 samples_remaining_in_frame + (samples_remaining_in_frame != 0 ? 2 : 0);
780 759
781 const auto decode_sample = [&](const int nibble) -> s16 { 760 const auto decode_sample = [&](const int nibble) -> s16 {
782 const int xn = nibble * (1 << scale); 761 const int xn = nibble * (1 << scale);
@@ -795,7 +774,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
795 774
796 std::size_t buffer_offset{}; 775 std::size_t buffer_offset{};
797 std::vector<u8> buffer( 776 std::vector<u8> buffer(
798 std::max((static_cast<u32>(samples_processed) / FRAME_LEN) * SAMPLES_PER_FRAME, FRAME_LEN)); 777 std::max((samples_processed / FRAME_LEN) * SAMPLES_PER_FRAME, FRAME_LEN));
799 memory.ReadBlock(wave_buffer.buffer_address + (position_in_frame / 2), buffer.data(), 778 memory.ReadBlock(wave_buffer.buffer_address + (position_in_frame / 2), buffer.data(),
800 buffer.size()); 779 buffer.size());
801 std::size_t cur_mix_offset = mix_offset; 780 std::size_t cur_mix_offset = mix_offset;
@@ -805,7 +784,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
805 if (position_in_frame % NIBBLES_PER_SAMPLE == 0) { 784 if (position_in_frame % NIBBLES_PER_SAMPLE == 0) {
806 // Read header 785 // Read header
807 frame_header = buffer[buffer_offset++]; 786 frame_header = buffer[buffer_offset++];
808 idx = static_cast<size_t>((frame_header >> 4) & 0xf); 787 idx = (frame_header >> 4) & 0xf;
809 scale = frame_header & 0xf; 788 scale = frame_header & 0xf;
810 coef1 = coeffs[idx * 2]; 789 coef1 = coeffs[idx * 2];
811 coef2 = coeffs[idx * 2 + 1]; 790 coef2 = coeffs[idx * 2 + 1];
@@ -815,8 +794,8 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
815 if (remaining_samples >= static_cast<int>(SAMPLES_PER_FRAME)) { 794 if (remaining_samples >= static_cast<int>(SAMPLES_PER_FRAME)) {
816 for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) { 795 for (std::size_t i = 0; i < SAMPLES_PER_FRAME / 2; i++) {
817 // Sample 1 796 // Sample 1
818 const s32 s0 = SIGNED_NIBBLES[static_cast<u32>(buffer[buffer_offset] >> 4)]; 797 const s32 s0 = SIGNED_NIBBLES[buffer[buffer_offset] >> 4];
819 const s32 s1 = SIGNED_NIBBLES[static_cast<u32>(buffer[buffer_offset++] & 0xf)]; 798 const s32 s1 = SIGNED_NIBBLES[buffer[buffer_offset++] & 0xf];
820 const s16 sample_1 = decode_sample(s0); 799 const s16 sample_1 = decode_sample(s0);
821 const s16 sample_2 = decode_sample(s1); 800 const s16 sample_2 = decode_sample(s1);
822 sample_buffer[cur_mix_offset++] = sample_1; 801 sample_buffer[cur_mix_offset++] = sample_1;
@@ -828,14 +807,14 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
828 } 807 }
829 } 808 }
830 // Decode mid frame 809 // Decode mid frame
831 auto current_nibble = static_cast<s32>(buffer[buffer_offset]); 810 s32 current_nibble = buffer[buffer_offset];
832 if ((position_in_frame++ & 1) != 0) { 811 if (position_in_frame++ & 0x1) {
833 current_nibble &= 0xf; 812 current_nibble &= 0xf;
834 buffer_offset++; 813 buffer_offset++;
835 } else { 814 } else {
836 current_nibble >>= 4; 815 current_nibble >>= 4;
837 } 816 }
838 const s16 sample = decode_sample(SIGNED_NIBBLES[static_cast<u32>(current_nibble)]); 817 const s16 sample = decode_sample(SIGNED_NIBBLES[current_nibble]);
839 sample_buffer[cur_mix_offset++] = sample; 818 sample_buffer[cur_mix_offset++] = sample;
840 remaining_samples--; 819 remaining_samples--;
841 } 820 }
@@ -856,7 +835,7 @@ const s32* CommandGenerator::GetMixBuffer(std::size_t index) const {
856} 835}
857 836
858std::size_t CommandGenerator::GetMixChannelBufferOffset(s32 channel) const { 837std::size_t CommandGenerator::GetMixChannelBufferOffset(s32 channel) const {
859 return worker_params.mix_buffer_count + static_cast<u32>(channel); 838 return worker_params.mix_buffer_count + channel;
860} 839}
861 840
862std::size_t CommandGenerator::GetTotalMixBufferCount() const { 841std::size_t CommandGenerator::GetTotalMixBufferCount() const {
@@ -864,11 +843,11 @@ std::size_t CommandGenerator::GetTotalMixBufferCount() const {
864} 843}
865 844
866s32* CommandGenerator::GetChannelMixBuffer(s32 channel) { 845s32* CommandGenerator::GetChannelMixBuffer(s32 channel) {
867 return GetMixBuffer(worker_params.mix_buffer_count + static_cast<u32>(channel)); 846 return GetMixBuffer(worker_params.mix_buffer_count + channel);
868} 847}
869 848
870const s32* CommandGenerator::GetChannelMixBuffer(s32 channel) const { 849const s32* CommandGenerator::GetChannelMixBuffer(s32 channel) const {
871 return GetMixBuffer(worker_params.mix_buffer_count + static_cast<u32>(channel)); 850 return GetMixBuffer(worker_params.mix_buffer_count + channel);
872} 851}
873 852
874void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* output, 853void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* output,
@@ -916,10 +895,9 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
916 895
917 s32 samples_read{}; 896 s32 samples_read{};
918 while (samples_read < samples_to_read) { 897 while (samples_read < samples_to_read) {
919 const auto& wave_buffer = 898 const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
920 in_params.wave_buffer[static_cast<u32>(dsp_state.wave_buffer_index)];
921 // No more data can be read 899 // No more data can be read
922 if (!dsp_state.is_wave_buffer_valid[static_cast<u32>(dsp_state.wave_buffer_index)]) { 900 if (!dsp_state.is_wave_buffer_valid[dsp_state.wave_buffer_index]) {
923 is_buffer_completed = true; 901 is_buffer_completed = true;
924 break; 902 break;
925 } 903 }
@@ -943,7 +921,7 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
943 UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format); 921 UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format);
944 } 922 }
945 923
946 temp_mix_offset += static_cast<size_t>(samples_decoded); 924 temp_mix_offset += samples_decoded;
947 samples_read += samples_decoded; 925 samples_read += samples_decoded;
948 dsp_state.offset += samples_decoded; 926 dsp_state.offset += samples_decoded;
949 dsp_state.played_sample_count += samples_decoded; 927 dsp_state.played_sample_count += samples_decoded;
@@ -966,12 +944,10 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
966 } else { 944 } else {
967 945
968 // Update our wave buffer states 946 // Update our wave buffer states
969 dsp_state.is_wave_buffer_valid[static_cast<u32>(dsp_state.wave_buffer_index)] = 947 dsp_state.is_wave_buffer_valid[dsp_state.wave_buffer_index] = false;
970 false;
971 dsp_state.wave_buffer_consumed++; 948 dsp_state.wave_buffer_consumed++;
972 dsp_state.wave_buffer_index = 949 dsp_state.wave_buffer_index =
973 static_cast<u32>(dsp_state.wave_buffer_index + 1) % 950 (dsp_state.wave_buffer_index + 1) % AudioCommon::MAX_WAVE_BUFFERS;
974 AudioCommon::MAX_WAVE_BUFFERS;
975 if (wave_buffer.end_of_stream) { 951 if (wave_buffer.end_of_stream) {
976 dsp_state.played_sample_count = 0; 952 dsp_state.played_sample_count = 0;
977 } 953 }
@@ -981,20 +957,16 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
981 957
982 if (in_params.behavior_flags.is_pitch_and_src_skipped.Value()) { 958 if (in_params.behavior_flags.is_pitch_and_src_skipped.Value()) {
983 // No need to resample 959 // No need to resample
984 std::memcpy(output, sample_buffer.data(), 960 std::memcpy(output, sample_buffer.data(), samples_read * sizeof(s32));
985 static_cast<size_t>(samples_read) * sizeof(s32));
986 } else { 961 } else {
987 { 962 std::fill(sample_buffer.begin() + temp_mix_offset,
988 const auto begin = sample_buffer.begin() + static_cast<ptrdiff_t>(temp_mix_offset); 963 sample_buffer.begin() + temp_mix_offset + (samples_to_read - samples_read),
989 const auto end = begin + (samples_to_read - samples_read); 964 0);
990 std::fill(begin, end, 0);
991 }
992 AudioCore::Resample(output, sample_buffer.data(), resample_rate, dsp_state.fraction, 965 AudioCore::Resample(output, sample_buffer.data(), resample_rate, dsp_state.fraction,
993 static_cast<size_t>(samples_to_output)); 966 samples_to_output);
994 // Resample 967 // Resample
995 for (std::size_t i = 0; i < AudioCommon::MAX_SAMPLE_HISTORY; i++) { 968 for (std::size_t i = 0; i < AudioCommon::MAX_SAMPLE_HISTORY; i++) {
996 dsp_state.sample_history[i] = 969 dsp_state.sample_history[i] = sample_buffer[samples_to_read + i];
997 sample_buffer[static_cast<size_t>(samples_to_read) + i];
998 } 970 }
999 } 971 }
1000 output += samples_to_output; 972 output += samples_to_output;
diff --git a/src/audio_core/command_generator.h b/src/audio_core/command_generator.h
index 6cba70ae3..53e57748b 100644
--- a/src/audio_core/command_generator.h
+++ b/src/audio_core/command_generator.h
@@ -50,12 +50,12 @@ public:
50private: 50private:
51 void GenerateDataSourceCommand(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 channel); 51 void GenerateDataSourceCommand(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 channel);
52 void GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info, VoiceState& dsp_state, 52 void GenerateBiquadFilterCommandForVoice(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
53 u32 mix_buffer_count, s32 channel); 53 s32 mix_buffer_count, s32 channel);
54 void GenerateVolumeRampCommand(float last_volume, float current_volume, s32 channel, 54 void GenerateVolumeRampCommand(float last_volume, float current_volume, s32 channel,
55 s32 node_id); 55 s32 node_id);
56 void GenerateVoiceMixCommand(const MixVolumeBuffer& mix_volumes, 56 void GenerateVoiceMixCommand(const MixVolumeBuffer& mix_volumes,
57 const MixVolumeBuffer& last_mix_volumes, VoiceState& dsp_state, 57 const MixVolumeBuffer& last_mix_volumes, VoiceState& dsp_state,
58 u32 mix_buffer_offset, u32 mix_buffer_count, u32 voice_index, 58 s32 mix_buffer_offset, s32 mix_buffer_count, s32 voice_index,
59 s32 node_id); 59 s32 node_id);
60 void GenerateSubMixCommand(ServerMixInfo& mix_info); 60 void GenerateSubMixCommand(ServerMixInfo& mix_info);
61 void GenerateMixCommands(ServerMixInfo& mix_info); 61 void GenerateMixCommands(ServerMixInfo& mix_info);
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp
index a20b6ad5f..6eaa60815 100644
--- a/src/audio_core/cubeb_sink.cpp
+++ b/src/audio_core/cubeb_sink.cpp
@@ -202,7 +202,7 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const
202 } 202 }
203 203
204 const std::size_t num_channels = impl->GetNumChannels(); 204 const std::size_t num_channels = impl->GetNumChannels();
205 const std::size_t samples_to_write = num_channels * static_cast<u64>(num_frames); 205 const std::size_t samples_to_write = num_channels * num_frames;
206 std::size_t samples_written; 206 std::size_t samples_written;
207 207
208 /* 208 /*
diff --git a/src/audio_core/cubeb_sink.h b/src/audio_core/cubeb_sink.h
index c50d0b7bd..7ce850f47 100644
--- a/src/audio_core/cubeb_sink.h
+++ b/src/audio_core/cubeb_sink.h
@@ -27,7 +27,7 @@ private:
27 std::vector<SinkStreamPtr> sink_streams; 27 std::vector<SinkStreamPtr> sink_streams;
28 28
29#ifdef _WIN32 29#ifdef _WIN32
30 s32 com_init_result = 0; 30 u32 com_init_result = 0;
31#endif 31#endif
32}; 32};
33 33
diff --git a/src/audio_core/info_updater.cpp b/src/audio_core/info_updater.cpp
index f999a8b17..2940e53a9 100644
--- a/src/audio_core/info_updater.cpp
+++ b/src/audio_core/info_updater.cpp
@@ -350,7 +350,7 @@ ResultCode InfoUpdater::UpdateMixes(MixContext& mix_context, std::size_t mix_buf
350 std::size_t total_buffer_count{}; 350 std::size_t total_buffer_count{};
351 for (std::size_t i = 0; i < mix_count; i++) { 351 for (std::size_t i = 0; i < mix_count; i++) {
352 const auto& in = mix_in_params[i]; 352 const auto& in = mix_in_params[i];
353 total_buffer_count += static_cast<size_t>(in.buffer_count); 353 total_buffer_count += in.buffer_count;
354 if (static_cast<std::size_t>(in.dest_mix_id) > mix_count && 354 if (static_cast<std::size_t>(in.dest_mix_id) > mix_count &&
355 in.dest_mix_id != AudioCommon::NO_MIX && in.mix_id != AudioCommon::FINAL_MIX) { 355 in.dest_mix_id != AudioCommon::NO_MIX && in.mix_id != AudioCommon::FINAL_MIX) {
356 LOG_ERROR( 356 LOG_ERROR(
@@ -379,7 +379,7 @@ ResultCode InfoUpdater::UpdateMixes(MixContext& mix_context, std::size_t mix_buf
379 const auto& mix_in = mix_in_params[i]; 379 const auto& mix_in = mix_in_params[i];
380 std::size_t target_mix{}; 380 std::size_t target_mix{};
381 if (behavior_info.IsMixInParameterDirtyOnlyUpdateSupported()) { 381 if (behavior_info.IsMixInParameterDirtyOnlyUpdateSupported()) {
382 target_mix = static_cast<size_t>(mix_in.mix_id); 382 target_mix = mix_in.mix_id;
383 } else { 383 } else {
384 // Non dirty supported games just use i instead of the actual mix_id 384 // Non dirty supported games just use i instead of the actual mix_id
385 target_mix = i; 385 target_mix = i;
diff --git a/src/audio_core/mix_context.cpp b/src/audio_core/mix_context.cpp
index c28bee453..4bca72eb0 100644
--- a/src/audio_core/mix_context.cpp
+++ b/src/audio_core/mix_context.cpp
@@ -62,7 +62,7 @@ void MixContext::UpdateDistancesFromFinalMix() {
62 distance_to_final_mix = AudioCommon::NO_FINAL_MIX; 62 distance_to_final_mix = AudioCommon::NO_FINAL_MIX;
63 break; 63 break;
64 } else { 64 } else {
65 const auto& dest_mix = GetInfo(static_cast<u32>(mix_id)); 65 const auto& dest_mix = GetInfo(mix_id);
66 const auto dest_mix_distance = dest_mix.GetInParams().final_mix_distance; 66 const auto dest_mix_distance = dest_mix.GetInParams().final_mix_distance;
67 67
68 if (dest_mix_distance == AudioCommon::NO_FINAL_MIX) { 68 if (dest_mix_distance == AudioCommon::NO_FINAL_MIX) {
@@ -129,7 +129,7 @@ bool MixContext::TsortInfo(SplitterContext& splitter_context) {
129 std::size_t info_id{}; 129 std::size_t info_id{};
130 for (auto itr = sorted_list.rbegin(); itr != sorted_list.rend(); ++itr) { 130 for (auto itr = sorted_list.rbegin(); itr != sorted_list.rend(); ++itr) {
131 // Set our sorted info 131 // Set our sorted info
132 sorted_info[info_id++] = &GetInfo(static_cast<u32>(*itr)); 132 sorted_info[info_id++] = &GetInfo(*itr);
133 } 133 }
134 134
135 // Calculate the mix buffer offset 135 // Calculate the mix buffer offset
@@ -218,8 +218,7 @@ bool ServerMixInfo::Update(EdgeMatrix& edge_matrix, const MixInfo::InParams& mix
218 for (std::size_t i = 0; i < effect_count; i++) { 218 for (std::size_t i = 0; i < effect_count; i++) {
219 auto* effect_info = effect_context.GetInfo(i); 219 auto* effect_info = effect_context.GetInfo(i);
220 if (effect_info->GetMixID() == in_params.mix_id) { 220 if (effect_info->GetMixID() == in_params.mix_id) {
221 const auto processing_order = static_cast<u32>(effect_info->GetProcessingOrder()); 221 effect_processing_order[effect_info->GetProcessingOrder()] = static_cast<s32>(i);
222 effect_processing_order[processing_order] = static_cast<s32>(i);
223 } 222 }
224 } 223 }
225 224
@@ -266,7 +265,7 @@ bool ServerMixInfo::UpdateConnection(EdgeMatrix& edge_matrix, const MixInfo::InP
266 if (in_params.dest_mix_id == mix_in.dest_mix_id && 265 if (in_params.dest_mix_id == mix_in.dest_mix_id &&
267 in_params.splitter_id == mix_in.splitter_id && 266 in_params.splitter_id == mix_in.splitter_id &&
268 ((in_params.splitter_id == AudioCommon::NO_SPLITTER) || 267 ((in_params.splitter_id == AudioCommon::NO_SPLITTER) ||
269 !splitter_context.GetInfo(static_cast<u32>(in_params.splitter_id)).HasNewConnection())) { 268 !splitter_context.GetInfo(in_params.splitter_id).HasNewConnection())) {
270 return false; 269 return false;
271 } 270 }
272 // Remove current edges for mix id 271 // Remove current edges for mix id
@@ -276,11 +275,11 @@ bool ServerMixInfo::UpdateConnection(EdgeMatrix& edge_matrix, const MixInfo::InP
276 edge_matrix.Connect(in_params.mix_id, mix_in.dest_mix_id); 275 edge_matrix.Connect(in_params.mix_id, mix_in.dest_mix_id);
277 } else if (mix_in.splitter_id != AudioCommon::NO_SPLITTER) { 276 } else if (mix_in.splitter_id != AudioCommon::NO_SPLITTER) {
278 // Recurse our splitter linked and set our edges 277 // Recurse our splitter linked and set our edges
279 auto& splitter_info = splitter_context.GetInfo(static_cast<u32>(mix_in.splitter_id)); 278 auto& splitter_info = splitter_context.GetInfo(mix_in.splitter_id);
280 const auto length = static_cast<size_t>(splitter_info.GetLength()); 279 const auto length = splitter_info.GetLength();
281 for (size_t i = 0; i < length; i++) { 280 for (s32 i = 0; i < length; i++) {
282 const auto* splitter_destination = 281 const auto* splitter_destination =
283 splitter_context.GetDestinationData(static_cast<u32>(mix_in.splitter_id), i); 282 splitter_context.GetDestinationData(mix_in.splitter_id, i);
284 if (splitter_destination == nullptr) { 283 if (splitter_destination == nullptr) {
285 continue; 284 continue;
286 } 285 }
diff --git a/src/audio_core/sink_context.cpp b/src/audio_core/sink_context.cpp
index 3d713814a..0882b411a 100644
--- a/src/audio_core/sink_context.cpp
+++ b/src/audio_core/sink_context.cpp
@@ -23,9 +23,8 @@ bool SinkContext::InUse() const {
23} 23}
24 24
25std::vector<u8> SinkContext::OutputBuffers() const { 25std::vector<u8> SinkContext::OutputBuffers() const {
26 const auto output_use_count = static_cast<size_t>(use_count); 26 std::vector<u8> buffer_ret(use_count);
27 std::vector<u8> buffer_ret(output_use_count); 27 std::memcpy(buffer_ret.data(), buffers.data(), use_count);
28 std::memcpy(buffer_ret.data(), buffers.data(), output_use_count);
29 return buffer_ret; 28 return buffer_ret;
30} 29}
31 30
diff --git a/src/audio_core/splitter_context.cpp b/src/audio_core/splitter_context.cpp
index f3e870648..f21b53147 100644
--- a/src/audio_core/splitter_context.cpp
+++ b/src/audio_core/splitter_context.cpp
@@ -109,7 +109,7 @@ std::size_t ServerSplitterInfo::Update(SplitterInfo::InInfoPrams& header) {
109 new_connection = true; 109 new_connection = true;
110 // We need to update the size here due to the splitter bug being present and providing an 110 // We need to update the size here due to the splitter bug being present and providing an
111 // incorrect size. We're suppose to also update the header here but we just ignore and continue 111 // incorrect size. We're suppose to also update the header here but we just ignore and continue
112 return (sizeof(s32_le) * static_cast<size_t>(header.length - 1)) + (sizeof(s32_le) * 3); 112 return (sizeof(s32_le) * (header.length - 1)) + (sizeof(s32_le) * 3);
113} 113}
114 114
115ServerSplitterDestinationData* ServerSplitterInfo::GetHead() { 115ServerSplitterDestinationData* ServerSplitterInfo::GetHead() {
@@ -306,14 +306,13 @@ bool SplitterContext::UpdateInfo(const std::vector<u8>& input, std::size_t& inpu
306 break; 306 break;
307 } 307 }
308 308
309 const auto send_id = static_cast<std::size_t>(header.send_id); 309 if (header.send_id < 0 || static_cast<std::size_t>(header.send_id) > info_count) {
310 if (header.send_id < 0 || send_id > info_count) {
311 LOG_ERROR(Audio, "Bad splitter data id"); 310 LOG_ERROR(Audio, "Bad splitter data id");
312 break; 311 break;
313 } 312 }
314 313
315 UpdateOffsets(sizeof(SplitterInfo::InInfoPrams)); 314 UpdateOffsets(sizeof(SplitterInfo::InInfoPrams));
316 auto& info = GetInfo(send_id); 315 auto& info = GetInfo(header.send_id);
317 if (!RecomposeDestination(info, header, input, input_offset)) { 316 if (!RecomposeDestination(info, header, input, input_offset)) {
318 LOG_ERROR(Audio, "Failed to recompose destination for splitter!"); 317 LOG_ERROR(Audio, "Failed to recompose destination for splitter!");
319 return false; 318 return false;
@@ -349,12 +348,11 @@ bool SplitterContext::UpdateData(const std::vector<u8>& input, std::size_t& inpu
349 break; 348 break;
350 } 349 }
351 350
352 const auto splitter_id = static_cast<std::size_t>(header.splitter_id); 351 if (header.splitter_id < 0 || static_cast<std::size_t>(header.splitter_id) > data_count) {
353 if (header.splitter_id < 0 || splitter_id > data_count) {
354 LOG_ERROR(Audio, "Bad splitter data id"); 352 LOG_ERROR(Audio, "Bad splitter data id");
355 break; 353 break;
356 } 354 }
357 GetData(splitter_id).Update(header); 355 GetData(header.splitter_id).Update(header);
358 } 356 }
359 return true; 357 return true;
360} 358}
@@ -388,9 +386,9 @@ bool SplitterContext::RecomposeDestination(ServerSplitterInfo& info,
388 return true; 386 return true;
389 } 387 }
390 388
391 auto* start_head = &GetData(static_cast<u32>(header.resource_id_base)); 389 auto* start_head = &GetData(header.resource_id_base);
392 current_head = start_head; 390 current_head = start_head;
393 std::vector<s32_le> resource_ids(static_cast<size_t>(size - 1)); 391 std::vector<s32_le> resource_ids(size - 1);
394 if (!AudioCommon::CanConsumeBuffer(input.size(), input_offset, 392 if (!AudioCommon::CanConsumeBuffer(input.size(), input_offset,
395 resource_ids.size() * sizeof(s32_le))) { 393 resource_ids.size() * sizeof(s32_le))) {
396 LOG_ERROR(Audio, "Buffer is an invalid size!"); 394 LOG_ERROR(Audio, "Buffer is an invalid size!");
@@ -399,8 +397,8 @@ bool SplitterContext::RecomposeDestination(ServerSplitterInfo& info,
399 std::memcpy(resource_ids.data(), input.data() + input_offset, 397 std::memcpy(resource_ids.data(), input.data() + input_offset,
400 resource_ids.size() * sizeof(s32_le)); 398 resource_ids.size() * sizeof(s32_le));
401 399
402 for (const auto resource_id : resource_ids) { 400 for (auto resource_id : resource_ids) {
403 auto* head = &GetData(static_cast<u32>(resource_id)); 401 auto* head = &GetData(resource_id);
404 current_head->SetNextDestination(head); 402 current_head->SetNextDestination(head);
405 current_head = head; 403 current_head = head;
406 } 404 }
@@ -446,7 +444,7 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) {
446 const auto node_id = static_cast<s32>(i); 444 const auto node_id = static_cast<s32>(i);
447 445
448 // If we don't have a state, send to our index stack for work 446 // If we don't have a state, send to our index stack for work
449 if (GetState(i) == State::NoState) { 447 if (GetState(i) == NodeStates::State::NoState) {
450 index_stack.push(node_id); 448 index_stack.push(node_id);
451 } 449 }
452 450
@@ -455,19 +453,19 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) {
455 // Get the current node 453 // Get the current node
456 const auto current_stack_index = index_stack.top(); 454 const auto current_stack_index = index_stack.top();
457 // Check if we've seen the node yet 455 // Check if we've seen the node yet
458 const auto index_state = GetState(static_cast<u32>(current_stack_index)); 456 const auto index_state = GetState(current_stack_index);
459 if (index_state == State::NoState) { 457 if (index_state == NodeStates::State::NoState) {
460 // Mark the node as seen 458 // Mark the node as seen
461 UpdateState(State::InFound, static_cast<u32>(current_stack_index)); 459 UpdateState(NodeStates::State::InFound, current_stack_index);
462 } else if (index_state == State::InFound) { 460 } else if (index_state == NodeStates::State::InFound) {
463 // We've seen this node before, mark it as completed 461 // We've seen this node before, mark it as completed
464 UpdateState(State::InCompleted, static_cast<u32>(current_stack_index)); 462 UpdateState(NodeStates::State::InCompleted, current_stack_index);
465 // Update our index list 463 // Update our index list
466 PushTsortResult(current_stack_index); 464 PushTsortResult(current_stack_index);
467 // Pop the stack 465 // Pop the stack
468 index_stack.pop(); 466 index_stack.pop();
469 continue; 467 continue;
470 } else if (index_state == State::InCompleted) { 468 } else if (index_state == NodeStates::State::InCompleted) {
471 // If our node is already sorted, clear it 469 // If our node is already sorted, clear it
472 index_stack.pop(); 470 index_stack.pop();
473 continue; 471 continue;
@@ -481,11 +479,11 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) {
481 } 479 }
482 480
483 // Check if our node exists 481 // Check if our node exists
484 const auto node_state = GetState(static_cast<u32>(j)); 482 const auto node_state = GetState(j);
485 if (node_state == State::NoState) { 483 if (node_state == NodeStates::State::NoState) {
486 // Add more work 484 // Add more work
487 index_stack.push(j); 485 index_stack.push(j);
488 } else if (node_state == State::InFound) { 486 } else if (node_state == NodeStates::State::InFound) {
489 UNREACHABLE_MSG("Node start marked as found"); 487 UNREACHABLE_MSG("Node start marked as found");
490 ResetState(); 488 ResetState();
491 return false; 489 return false;
@@ -509,17 +507,17 @@ void NodeStates::ResetState() {
509 } 507 }
510} 508}
511 509
512void NodeStates::UpdateState(State state, std::size_t i) { 510void NodeStates::UpdateState(NodeStates::State state, std::size_t i) {
513 switch (state) { 511 switch (state) {
514 case State::NoState: 512 case NodeStates::State::NoState:
515 was_node_found[i] = false; 513 was_node_found[i] = false;
516 was_node_completed[i] = false; 514 was_node_completed[i] = false;
517 break; 515 break;
518 case State::InFound: 516 case NodeStates::State::InFound:
519 was_node_found[i] = true; 517 was_node_found[i] = true;
520 was_node_completed[i] = false; 518 was_node_completed[i] = false;
521 break; 519 break;
522 case State::InCompleted: 520 case NodeStates::State::InCompleted:
523 was_node_found[i] = false; 521 was_node_found[i] = false;
524 was_node_completed[i] = true; 522 was_node_completed[i] = true;
525 break; 523 break;
@@ -530,13 +528,13 @@ NodeStates::State NodeStates::GetState(std::size_t i) {
530 ASSERT(i < node_count); 528 ASSERT(i < node_count);
531 if (was_node_found[i]) { 529 if (was_node_found[i]) {
532 // If our node exists in our found list 530 // If our node exists in our found list
533 return State::InFound; 531 return NodeStates::State::InFound;
534 } else if (was_node_completed[i]) { 532 } else if (was_node_completed[i]) {
535 // If node is in the completed list 533 // If node is in the completed list
536 return State::InCompleted; 534 return NodeStates::State::InCompleted;
537 } else { 535 } else {
538 // If in neither 536 // If in neither
539 return State::NoState; 537 return NodeStates::State::NoState;
540 } 538 }
541} 539}
542 540
@@ -603,16 +601,16 @@ std::size_t EdgeMatrix::GetNodeCount() const {
603 601
604void EdgeMatrix::SetState(s32 a, s32 b, bool state) { 602void EdgeMatrix::SetState(s32 a, s32 b, bool state) {
605 ASSERT(InRange(a, b)); 603 ASSERT(InRange(a, b));
606 edge_matrix.at(static_cast<u32>(a) * node_count + static_cast<u32>(b)) = state; 604 edge_matrix.at(a * node_count + b) = state;
607} 605}
608 606
609bool EdgeMatrix::GetState(s32 a, s32 b) { 607bool EdgeMatrix::GetState(s32 a, s32 b) {
610 ASSERT(InRange(a, b)); 608 ASSERT(InRange(a, b));
611 return edge_matrix.at(static_cast<u32>(a) * node_count + static_cast<u32>(b)); 609 return edge_matrix.at(a * node_count + b);
612} 610}
613 611
614bool EdgeMatrix::InRange(s32 a, s32 b) const { 612bool EdgeMatrix::InRange(s32 a, s32 b) const {
615 const std::size_t pos = static_cast<u32>(a) * node_count + static_cast<u32>(b); 613 const std::size_t pos = a * node_count + b;
616 return pos < (node_count * node_count); 614 return pos < (node_count * node_count);
617} 615}
618 616
diff --git a/src/audio_core/time_stretch.h b/src/audio_core/time_stretch.h
index 3808e554d..bb2270b96 100644
--- a/src/audio_core/time_stretch.h
+++ b/src/audio_core/time_stretch.h
@@ -5,16 +5,8 @@
5#pragma once 5#pragma once
6 6
7#include <cstddef> 7#include <cstddef>
8#include "common/common_types.h"
9
10#if defined(__GNUC__)
11#pragma GCC diagnostic push
12#pragma GCC diagnostic ignored "-Wsign-conversion"
13#endif
14#include <SoundTouch.h> 8#include <SoundTouch.h>
15#if defined(__GNUC__) 9#include "common/common_types.h"
16#pragma GCC diagnostic pop
17#endif
18 10
19namespace AudioCore { 11namespace AudioCore {
20 12
diff --git a/src/audio_core/voice_context.cpp b/src/audio_core/voice_context.cpp
index 276b96ca4..c46ee55f1 100644
--- a/src/audio_core/voice_context.cpp
+++ b/src/audio_core/voice_context.cpp
@@ -98,7 +98,7 @@ void ServerVoiceInfo::UpdateParameters(const VoiceInfo::InParams& voice_in,
98 BehaviorInfo& behavior_info) { 98 BehaviorInfo& behavior_info) {
99 in_params.in_use = voice_in.is_in_use; 99 in_params.in_use = voice_in.is_in_use;
100 in_params.id = voice_in.id; 100 in_params.id = voice_in.id;
101 in_params.node_id = static_cast<s32>(voice_in.node_id); 101 in_params.node_id = voice_in.node_id;
102 in_params.last_playstate = in_params.current_playstate; 102 in_params.last_playstate = in_params.current_playstate;
103 switch (voice_in.play_state) { 103 switch (voice_in.play_state) {
104 case PlayState::Paused: 104 case PlayState::Paused:
@@ -220,10 +220,8 @@ void ServerVoiceInfo::UpdateWaveBuffer(ServerWaveBuffer& out_wavebuffer,
220 if (sample_format == SampleFormat::Pcm16) { 220 if (sample_format == SampleFormat::Pcm16) {
221 const auto buffer_size = in_wave_buffer.buffer_size; 221 const auto buffer_size = in_wave_buffer.buffer_size;
222 if (in_wave_buffer.start_sample_offset < 0 || in_wave_buffer.end_sample_offset < 0 || 222 if (in_wave_buffer.start_sample_offset < 0 || in_wave_buffer.end_sample_offset < 0 ||
223 (buffer_size < 223 (buffer_size < (sizeof(s16) * in_wave_buffer.start_sample_offset)) ||
224 (sizeof(s16) * static_cast<u32>(in_wave_buffer.start_sample_offset))) || 224 (buffer_size < (sizeof(s16) * in_wave_buffer.end_sample_offset))) {
225 (buffer_size <
226 (sizeof(s16) * static_cast<u32>(in_wave_buffer.end_sample_offset)))) {
227 // TODO(ogniK): Write error info 225 // TODO(ogniK): Write error info
228 return; 226 return;
229 } 227 }
@@ -256,8 +254,8 @@ void ServerVoiceInfo::WriteOutStatus(
256 voice_out.played_sample_count = 0; 254 voice_out.played_sample_count = 0;
257 voice_out.voice_dropped = false; 255 voice_out.voice_dropped = false;
258 } else if (!in_params.is_new) { 256 } else if (!in_params.is_new) {
259 voice_out.wave_buffer_consumed = static_cast<u32>(voice_states[0]->wave_buffer_consumed); 257 voice_out.wave_buffer_consumed = voice_states[0]->wave_buffer_consumed;
260 voice_out.played_sample_count = static_cast<u64>(voice_states[0]->played_sample_count); 258 voice_out.played_sample_count = voice_states[0]->played_sample_count;
261 voice_out.voice_dropped = in_params.voice_drop_flag; 259 voice_out.voice_dropped = in_params.voice_drop_flag;
262 } else { 260 } else {
263 voice_out.wave_buffer_consumed = 0; 261 voice_out.wave_buffer_consumed = 0;
@@ -295,8 +293,8 @@ bool ServerVoiceInfo::UpdateForCommandGeneration(VoiceContext& voice_context) {
295 in_params.is_new = false; 293 in_params.is_new = false;
296 } 294 }
297 295
298 const auto channel_count = static_cast<size_t>(in_params.channel_count); 296 const s32 channel_count = in_params.channel_count;
299 for (size_t i = 0; i < channel_count; i++) { 297 for (s32 i = 0; i < channel_count; i++) {
300 const auto channel_resource = in_params.voice_channel_resource_id[i]; 298 const auto channel_resource = in_params.voice_channel_resource_id[i];
301 dsp_voice_states[i] = 299 dsp_voice_states[i] =
302 &voice_context.GetDspSharedState(static_cast<std::size_t>(channel_resource)); 300 &voice_context.GetDspSharedState(static_cast<std::size_t>(channel_resource));
@@ -305,9 +303,8 @@ bool ServerVoiceInfo::UpdateForCommandGeneration(VoiceContext& voice_context) {
305} 303}
306 304
307void ServerVoiceInfo::ResetResources(VoiceContext& voice_context) { 305void ServerVoiceInfo::ResetResources(VoiceContext& voice_context) {
308 const auto channel_count = static_cast<size_t>(in_params.channel_count); 306 const s32 channel_count = in_params.channel_count;
309 307 for (s32 i = 0; i < channel_count; i++) {
310 for (size_t i = 0; i < channel_count; i++) {
311 const auto channel_resource = in_params.voice_channel_resource_id[i]; 308 const auto channel_resource = in_params.voice_channel_resource_id[i];
312 auto& dsp_state = 309 auto& dsp_state =
313 voice_context.GetDspSharedState(static_cast<std::size_t>(channel_resource)); 310 voice_context.GetDspSharedState(static_cast<std::size_t>(channel_resource));
@@ -328,9 +325,9 @@ bool ServerVoiceInfo::UpdateParametersForCommandGeneration(
328 325
329 switch (in_params.current_playstate) { 326 switch (in_params.current_playstate) {
330 case ServerPlayState::Play: { 327 case ServerPlayState::Play: {
331 for (size_t i = 0; i < AudioCommon::MAX_WAVE_BUFFERS; i++) { 328 for (std::size_t i = 0; i < AudioCommon::MAX_WAVE_BUFFERS; i++) {
332 if (!in_params.wave_buffer[i].sent_to_dsp) { 329 if (!in_params.wave_buffer[i].sent_to_dsp) {
333 for (size_t channel = 0; channel < static_cast<size_t>(channel_count); channel++) { 330 for (s32 channel = 0; channel < channel_count; channel++) {
334 dsp_voice_states[channel]->is_wave_buffer_valid[i] = true; 331 dsp_voice_states[channel]->is_wave_buffer_valid[i] = true;
335 } 332 }
336 in_params.wave_buffer[i].sent_to_dsp = true; 333 in_params.wave_buffer[i].sent_to_dsp = true;
@@ -347,13 +344,12 @@ bool ServerVoiceInfo::UpdateParametersForCommandGeneration(
347 case ServerPlayState::RequestStop: { 344 case ServerPlayState::RequestStop: {
348 for (std::size_t i = 0; i < AudioCommon::MAX_WAVE_BUFFERS; i++) { 345 for (std::size_t i = 0; i < AudioCommon::MAX_WAVE_BUFFERS; i++) {
349 in_params.wave_buffer[i].sent_to_dsp = true; 346 in_params.wave_buffer[i].sent_to_dsp = true;
350 for (std::size_t channel = 0; channel < static_cast<size_t>(channel_count); channel++) { 347 for (s32 channel = 0; channel < channel_count; channel++) {
351 auto* dsp_state = dsp_voice_states[channel]; 348 auto* dsp_state = dsp_voice_states[channel];
352 349
353 if (dsp_state->is_wave_buffer_valid[i]) { 350 if (dsp_state->is_wave_buffer_valid[i]) {
354 dsp_state->wave_buffer_index = 351 dsp_state->wave_buffer_index =
355 static_cast<s32>(static_cast<u32>(dsp_state->wave_buffer_index + 1) % 352 (dsp_state->wave_buffer_index + 1) % AudioCommon::MAX_WAVE_BUFFERS;
356 AudioCommon::MAX_WAVE_BUFFERS);
357 dsp_state->wave_buffer_consumed++; 353 dsp_state->wave_buffer_consumed++;
358 } 354 }
359 355
@@ -361,7 +357,7 @@ bool ServerVoiceInfo::UpdateParametersForCommandGeneration(
361 } 357 }
362 } 358 }
363 359
364 for (size_t channel = 0; channel < static_cast<size_t>(channel_count); channel++) { 360 for (s32 channel = 0; channel < channel_count; channel++) {
365 auto* dsp_state = dsp_voice_states[channel]; 361 auto* dsp_state = dsp_voice_states[channel];
366 dsp_state->offset = 0; 362 dsp_state->offset = 0;
367 dsp_state->played_sample_count = 0; 363 dsp_state->played_sample_count = 0;
@@ -387,16 +383,15 @@ void ServerVoiceInfo::FlushWaveBuffers(
387 auto wave_head = in_params.wave_bufffer_head; 383 auto wave_head = in_params.wave_bufffer_head;
388 384
389 for (u8 i = 0; i < flush_count; i++) { 385 for (u8 i = 0; i < flush_count; i++) {
390 in_params.wave_buffer[static_cast<u16>(wave_head)].sent_to_dsp = true; 386 in_params.wave_buffer[wave_head].sent_to_dsp = true;
391 for (size_t channel = 0; channel < static_cast<size_t>(channel_count); channel++) { 387 for (s32 channel = 0; channel < channel_count; channel++) {
392 auto* dsp_state = dsp_voice_states[channel]; 388 auto* dsp_state = dsp_voice_states[channel];
393 dsp_state->wave_buffer_consumed++; 389 dsp_state->wave_buffer_consumed++;
394 dsp_state->is_wave_buffer_valid[static_cast<u16>(wave_head)] = false; 390 dsp_state->is_wave_buffer_valid[wave_head] = false;
395 dsp_state->wave_buffer_index = static_cast<s32>( 391 dsp_state->wave_buffer_index =
396 static_cast<u32>(dsp_state->wave_buffer_index + 1) % AudioCommon::MAX_WAVE_BUFFERS); 392 (dsp_state->wave_buffer_index + 1) % AudioCommon::MAX_WAVE_BUFFERS;
397 } 393 }
398 wave_head = 394 wave_head = (wave_head + 1) % AudioCommon::MAX_WAVE_BUFFERS;
399 static_cast<s16>(static_cast<u32>(wave_head + 1) % AudioCommon::MAX_WAVE_BUFFERS);
400 } 395 }
401} 396}
402 397
@@ -488,7 +483,7 @@ s32 VoiceContext::DecodePcm16(s32* output_buffer, ServerWaveBuffer* wave_buffer,
488 const auto samples_remaining = 483 const auto samples_remaining =
489 (wave_buffer->end_sample_offset - wave_buffer->start_sample_offset) - buffer_offset; 484 (wave_buffer->end_sample_offset - wave_buffer->start_sample_offset) - buffer_offset;
490 const auto start_offset = (wave_buffer->start_sample_offset + buffer_offset) * channel_count; 485 const auto start_offset = (wave_buffer->start_sample_offset + buffer_offset) * channel_count;
491 const auto buffer_pos = wave_buffer->buffer_address + static_cast<VAddr>(start_offset); 486 const auto buffer_pos = wave_buffer->buffer_address + start_offset;
492 487
493 s16* buffer_data = reinterpret_cast<s16*>(memory.GetPointer(buffer_pos)); 488 s16* buffer_data = reinterpret_cast<s16*>(memory.GetPointer(buffer_pos));
494 489