diff options
| author | 2023-09-08 07:17:52 +0100 | |
|---|---|---|
| committer | 2023-09-08 15:03:21 +0100 | |
| commit | 800d6f7d0d36701bacda9ec97c716515ed13fa6f (patch) | |
| tree | 319305324c9b8308e21f1c77c5499fee59fc7751 | |
| parent | Merge pull request #11428 from Kelebek1/adsp_rework (diff) | |
| download | yuzu-800d6f7d0d36701bacda9ec97c716515ed13fa6f.tar.gz yuzu-800d6f7d0d36701bacda9ec97c716515ed13fa6f.tar.xz yuzu-800d6f7d0d36701bacda9ec97c716515ed13fa6f.zip | |
Fix data source version 1 command looping
4 files changed, 72 insertions, 52 deletions
diff --git a/src/audio_core/renderer/command/data_source/adpcm.cpp b/src/audio_core/renderer/command/data_source/adpcm.cpp index 28e76fdcc..e7f82d3b3 100644 --- a/src/audio_core/renderer/command/data_source/adpcm.cpp +++ b/src/audio_core/renderer/command/data_source/adpcm.cpp | |||
| @@ -20,6 +20,12 @@ void AdpcmDataSourceVersion1Command::Process(const AudioRenderer::CommandListPro | |||
| 20 | auto out_buffer{processor.mix_buffers.subspan(output_index * processor.sample_count, | 20 | auto out_buffer{processor.mix_buffers.subspan(output_index * processor.sample_count, |
| 21 | processor.sample_count)}; | 21 | processor.sample_count)}; |
| 22 | 22 | ||
| 23 | for (auto& wave_buffer : wave_buffers) { | ||
| 24 | wave_buffer.loop_start_offset = wave_buffer.start_offset; | ||
| 25 | wave_buffer.loop_end_offset = wave_buffer.end_offset; | ||
| 26 | wave_buffer.loop_count = wave_buffer.loop ? -1 : 0; | ||
| 27 | } | ||
| 28 | |||
| 23 | DecodeFromWaveBuffersArgs args{ | 29 | DecodeFromWaveBuffersArgs args{ |
| 24 | .sample_format{SampleFormat::Adpcm}, | 30 | .sample_format{SampleFormat::Adpcm}, |
| 25 | .output{out_buffer}, | 31 | .output{out_buffer}, |
diff --git a/src/audio_core/renderer/command/data_source/decode.cpp b/src/audio_core/renderer/command/data_source/decode.cpp index 762aec8ad..911dae3c1 100644 --- a/src/audio_core/renderer/command/data_source/decode.cpp +++ b/src/audio_core/renderer/command/data_source/decode.cpp | |||
| @@ -123,11 +123,13 @@ static u32 DecodeAdpcm(Core::Memory::Memory& memory, std::span<s16> out_buffer, | |||
| 123 | return 0; | 123 | return 0; |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | auto samples_to_process{ | 126 | auto start_pos{req.start_offset + req.offset}; |
| 127 | std::min(req.end_offset - req.start_offset - req.offset, req.samples_to_read)}; | 127 | auto samples_to_process{std::min(req.end_offset - start_pos, req.samples_to_read)}; |
| 128 | if (samples_to_process == 0) { | ||
| 129 | return 0; | ||
| 130 | } | ||
| 128 | 131 | ||
| 129 | auto samples_to_read{samples_to_process}; | 132 | auto samples_to_read{samples_to_process}; |
| 130 | auto start_pos{req.start_offset + req.offset}; | ||
| 131 | auto samples_remaining_in_frame{start_pos % SamplesPerFrame}; | 133 | auto samples_remaining_in_frame{start_pos % SamplesPerFrame}; |
| 132 | auto position_in_frame{(start_pos / SamplesPerFrame) * NibblesPerFrame + | 134 | auto position_in_frame{(start_pos / SamplesPerFrame) * NibblesPerFrame + |
| 133 | samples_remaining_in_frame}; | 135 | samples_remaining_in_frame}; |
| @@ -225,13 +227,24 @@ static u32 DecodeAdpcm(Core::Memory::Memory& memory, std::span<s16> out_buffer, | |||
| 225 | * @param args - The wavebuffer data, and information for how to decode it. | 227 | * @param args - The wavebuffer data, and information for how to decode it. |
| 226 | */ | 228 | */ |
| 227 | void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuffersArgs& args) { | 229 | void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuffersArgs& args) { |
| 230 | static constexpr auto EndWaveBuffer = [](auto& voice_state, auto& wavebuffer, auto& index, | ||
| 231 | auto& played_samples, auto& consumed) -> void { | ||
| 232 | voice_state.wave_buffer_valid[index] = false; | ||
| 233 | voice_state.loop_count = 0; | ||
| 234 | |||
| 235 | if (wavebuffer.stream_ended) { | ||
| 236 | played_samples = 0; | ||
| 237 | } | ||
| 238 | |||
| 239 | index = (index + 1) % MaxWaveBuffers; | ||
| 240 | consumed++; | ||
| 241 | }; | ||
| 228 | auto& voice_state{*args.voice_state}; | 242 | auto& voice_state{*args.voice_state}; |
| 229 | auto remaining_sample_count{args.sample_count}; | 243 | auto remaining_sample_count{args.sample_count}; |
| 230 | auto fraction{voice_state.fraction}; | 244 | auto fraction{voice_state.fraction}; |
| 231 | 245 | ||
| 232 | const auto sample_rate_ratio{ | 246 | const auto sample_rate_ratio{Common::FixedPoint<49, 15>( |
| 233 | (Common::FixedPoint<49, 15>(args.source_sample_rate) / args.target_sample_rate) * | 247 | (f32)args.source_sample_rate / (f32)args.target_sample_rate * (f32)args.pitch)}; |
| 234 | args.pitch}; | ||
| 235 | const auto size_required{fraction + remaining_sample_count * sample_rate_ratio}; | 248 | const auto size_required{fraction + remaining_sample_count * sample_rate_ratio}; |
| 236 | 249 | ||
| 237 | if (size_required < 0) { | 250 | if (size_required < 0) { |
| @@ -298,22 +311,23 @@ void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuf | |||
| 298 | auto end_offset{wavebuffer.end_offset}; | 311 | auto end_offset{wavebuffer.end_offset}; |
| 299 | 312 | ||
| 300 | if (wavebuffer.loop && voice_state.loop_count > 0 && | 313 | if (wavebuffer.loop && voice_state.loop_count > 0 && |
| 301 | wavebuffer.loop_start_offset != 0 && wavebuffer.loop_end_offset != 0 && | ||
| 302 | wavebuffer.loop_start_offset <= wavebuffer.loop_end_offset) { | 314 | wavebuffer.loop_start_offset <= wavebuffer.loop_end_offset) { |
| 303 | start_offset = wavebuffer.loop_start_offset; | 315 | start_offset = wavebuffer.loop_start_offset; |
| 304 | end_offset = wavebuffer.loop_end_offset; | 316 | end_offset = wavebuffer.loop_end_offset; |
| 305 | } | 317 | } |
| 306 | 318 | ||
| 307 | DecodeArg decode_arg{.buffer{wavebuffer.buffer}, | 319 | DecodeArg decode_arg{ |
| 308 | .buffer_size{wavebuffer.buffer_size}, | 320 | .buffer{wavebuffer.buffer}, |
| 309 | .start_offset{start_offset}, | 321 | .buffer_size{wavebuffer.buffer_size}, |
| 310 | .end_offset{end_offset}, | 322 | .start_offset{start_offset}, |
| 311 | .channel_count{args.channel_count}, | 323 | .end_offset{end_offset}, |
| 312 | .coefficients{}, | 324 | .channel_count{args.channel_count}, |
| 313 | .adpcm_context{nullptr}, | 325 | .coefficients{}, |
| 314 | .target_channel{args.channel}, | 326 | .adpcm_context{nullptr}, |
| 315 | .offset{offset}, | 327 | .target_channel{args.channel}, |
| 316 | .samples_to_read{samples_to_read - samples_read}}; | 328 | .offset{offset}, |
| 329 | .samples_to_read{samples_to_read - samples_read}, | ||
| 330 | }; | ||
| 317 | 331 | ||
| 318 | s32 samples_decoded{0}; | 332 | s32 samples_decoded{0}; |
| 319 | 333 | ||
| @@ -350,42 +364,30 @@ void DecodeFromWaveBuffers(Core::Memory::Memory& memory, const DecodeFromWaveBuf | |||
| 350 | temp_buffer_pos += samples_decoded; | 364 | temp_buffer_pos += samples_decoded; |
| 351 | offset += samples_decoded; | 365 | offset += samples_decoded; |
| 352 | 366 | ||
| 353 | if (samples_decoded == 0 || offset >= end_offset - start_offset) { | 367 | if (samples_decoded && offset < end_offset - start_offset) { |
| 354 | offset = 0; | 368 | continue; |
| 355 | if (!wavebuffer.loop) { | 369 | } |
| 356 | voice_state.wave_buffer_valid[wavebuffer_index] = false; | 370 | |
| 357 | voice_state.loop_count = 0; | 371 | offset = 0; |
| 358 | 372 | if (wavebuffer.loop) { | |
| 359 | if (wavebuffer.stream_ended) { | 373 | voice_state.loop_count++; |
| 360 | played_sample_count = 0; | 374 | if (wavebuffer.loop_count >= 0 && |
| 361 | } | 375 | (voice_state.loop_count > wavebuffer.loop_count || samples_decoded == 0)) { |
| 362 | 376 | EndWaveBuffer(voice_state, wavebuffer, wavebuffer_index, played_sample_count, | |
| 363 | wavebuffer_index = (wavebuffer_index + 1) % MaxWaveBuffers; | 377 | wavebuffers_consumed); |
| 364 | wavebuffers_consumed++; | 378 | } |
| 365 | } else { | 379 | |
| 366 | voice_state.loop_count++; | 380 | if (samples_decoded == 0) { |
| 367 | if (wavebuffer.loop_count >= 0 && | 381 | is_buffer_starved = true; |
| 368 | (voice_state.loop_count > wavebuffer.loop_count || samples_decoded == 0)) { | 382 | break; |
| 369 | voice_state.wave_buffer_valid[wavebuffer_index] = false; | 383 | } |
| 370 | voice_state.loop_count = 0; | 384 | |
| 371 | 385 | if (args.IsVoicePlayedSampleCountResetAtLoopPointSupported) { | |
| 372 | if (wavebuffer.stream_ended) { | 386 | played_sample_count = 0; |
| 373 | played_sample_count = 0; | ||
| 374 | } | ||
| 375 | |||
| 376 | wavebuffer_index = (wavebuffer_index + 1) % MaxWaveBuffers; | ||
| 377 | wavebuffers_consumed++; | ||
| 378 | } | ||
| 379 | |||
| 380 | if (samples_decoded == 0) { | ||
| 381 | is_buffer_starved = true; | ||
| 382 | break; | ||
| 383 | } | ||
| 384 | |||
| 385 | if (args.IsVoicePlayedSampleCountResetAtLoopPointSupported) { | ||
| 386 | played_sample_count = 0; | ||
| 387 | } | ||
| 388 | } | 387 | } |
| 388 | } else { | ||
| 389 | EndWaveBuffer(voice_state, wavebuffer, wavebuffer_index, played_sample_count, | ||
| 390 | wavebuffers_consumed); | ||
| 389 | } | 391 | } |
| 390 | } | 392 | } |
| 391 | 393 | ||
diff --git a/src/audio_core/renderer/command/data_source/pcm_float.cpp b/src/audio_core/renderer/command/data_source/pcm_float.cpp index 5cc0797f4..d1f685656 100644 --- a/src/audio_core/renderer/command/data_source/pcm_float.cpp +++ b/src/audio_core/renderer/command/data_source/pcm_float.cpp | |||
| @@ -21,6 +21,12 @@ void PcmFloatDataSourceVersion1Command::Process( | |||
| 21 | auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count, | 21 | auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count, |
| 22 | processor.sample_count); | 22 | processor.sample_count); |
| 23 | 23 | ||
| 24 | for (auto& wave_buffer : wave_buffers) { | ||
| 25 | wave_buffer.loop_start_offset = wave_buffer.start_offset; | ||
| 26 | wave_buffer.loop_end_offset = wave_buffer.end_offset; | ||
| 27 | wave_buffer.loop_count = wave_buffer.loop ? -1 : 0; | ||
| 28 | } | ||
| 29 | |||
| 24 | DecodeFromWaveBuffersArgs args{ | 30 | DecodeFromWaveBuffersArgs args{ |
| 25 | .sample_format{SampleFormat::PcmFloat}, | 31 | .sample_format{SampleFormat::PcmFloat}, |
| 26 | .output{out_buffer}, | 32 | .output{out_buffer}, |
diff --git a/src/audio_core/renderer/command/data_source/pcm_int16.cpp b/src/audio_core/renderer/command/data_source/pcm_int16.cpp index 649993068..c89a5aaac 100644 --- a/src/audio_core/renderer/command/data_source/pcm_int16.cpp +++ b/src/audio_core/renderer/command/data_source/pcm_int16.cpp | |||
| @@ -23,6 +23,12 @@ void PcmInt16DataSourceVersion1Command::Process( | |||
| 23 | auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count, | 23 | auto out_buffer = processor.mix_buffers.subspan(output_index * processor.sample_count, |
| 24 | processor.sample_count); | 24 | processor.sample_count); |
| 25 | 25 | ||
| 26 | for (auto& wave_buffer : wave_buffers) { | ||
| 27 | wave_buffer.loop_start_offset = wave_buffer.start_offset; | ||
| 28 | wave_buffer.loop_end_offset = wave_buffer.end_offset; | ||
| 29 | wave_buffer.loop_count = wave_buffer.loop ? -1 : 0; | ||
| 30 | } | ||
| 31 | |||
| 26 | DecodeFromWaveBuffersArgs args{ | 32 | DecodeFromWaveBuffersArgs args{ |
| 27 | .sample_format{SampleFormat::PcmInt16}, | 33 | .sample_format{SampleFormat::PcmInt16}, |
| 28 | .output{out_buffer}, | 34 | .output{out_buffer}, |