diff options
| author | 2021-07-06 15:01:18 +0100 | |
|---|---|---|
| committer | 2021-07-06 18:43:23 +0100 | |
| commit | dbcc093d88c9dd48e490430a6491106ea175aff0 (patch) | |
| tree | c4f9b3eb4de4ba62a2b741bc43a2d88380413d2a /src | |
| parent | Merge pull request #6537 from Morph1984/warnings (diff) | |
| download | yuzu-dbcc093d88c9dd48e490430a6491106ea175aff0.tar.gz yuzu-dbcc093d88c9dd48e490430a6491106ea175aff0.tar.xz yuzu-dbcc093d88c9dd48e490430a6491106ea175aff0.zip | |
Support more PCM formats. Fixes Ys IX audio.
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio_core/command_generator.cpp | 64 | ||||
| -rw-r--r-- | src/audio_core/command_generator.h | 5 |
2 files changed, 51 insertions, 18 deletions
diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp index 27437f1ea..b3250be09 100644 --- a/src/audio_core/command_generator.cpp +++ b/src/audio_core/command_generator.cpp | |||
| @@ -400,7 +400,10 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo | |||
| 400 | } | 400 | } |
| 401 | } else { | 401 | } else { |
| 402 | switch (in_params.sample_format) { | 402 | switch (in_params.sample_format) { |
| 403 | case SampleFormat::Pcm8: | ||
| 403 | case SampleFormat::Pcm16: | 404 | case SampleFormat::Pcm16: |
| 405 | case SampleFormat::Pcm32: | ||
| 406 | case SampleFormat::PcmFloat: | ||
| 404 | DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(channel), dsp_state, channel, | 407 | DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(channel), dsp_state, channel, |
| 405 | worker_params.sample_rate, worker_params.sample_count, | 408 | worker_params.sample_rate, worker_params.sample_count, |
| 406 | in_params.node_id); | 409 | in_params.node_id); |
| @@ -1003,9 +1006,10 @@ void CommandGenerator::GenerateFinalMixCommand() { | |||
| 1003 | } | 1006 | } |
| 1004 | } | 1007 | } |
| 1005 | 1008 | ||
| 1006 | s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_state, | 1009 | template <typename T> |
| 1007 | s32 sample_start_offset, s32 sample_end_offset, s32 sample_count, | 1010 | s32 CommandGenerator::DecodePcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state, |
| 1008 | s32 channel, std::size_t mix_offset) { | 1011 | s32 sample_start_offset, s32 sample_end_offset, s32 sample_count, |
| 1012 | s32 channel, std::size_t mix_offset) { | ||
| 1009 | const auto& in_params = voice_info.GetInParams(); | 1013 | const auto& in_params = voice_info.GetInParams(); |
| 1010 | const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index]; | 1014 | const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index]; |
| 1011 | if (wave_buffer.buffer_address == 0) { | 1015 | if (wave_buffer.buffer_address == 0) { |
| @@ -1019,24 +1023,37 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s | |||
| 1019 | } | 1023 | } |
| 1020 | const auto samples_remaining = (sample_end_offset - sample_start_offset) - dsp_state.offset; | 1024 | const auto samples_remaining = (sample_end_offset - sample_start_offset) - dsp_state.offset; |
| 1021 | const auto start_offset = | 1025 | const auto start_offset = |
| 1022 | ((dsp_state.offset + sample_start_offset) * in_params.channel_count) * sizeof(s16); | 1026 | ((dsp_state.offset + sample_start_offset) * in_params.channel_count) * sizeof(T); |
| 1023 | const auto buffer_pos = wave_buffer.buffer_address + start_offset; | 1027 | const auto buffer_pos = wave_buffer.buffer_address + start_offset; |
| 1024 | const auto samples_processed = std::min(sample_count, samples_remaining); | 1028 | const auto samples_processed = std::min(sample_count, samples_remaining); |
| 1025 | 1029 | ||
| 1026 | if (in_params.channel_count == 1) { | 1030 | const auto channel_count = in_params.channel_count; |
| 1027 | std::vector<s16> buffer(samples_processed); | 1031 | std::vector<T> buffer(samples_processed * channel_count); |
| 1028 | memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); | 1032 | memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(T)); |
| 1029 | for (std::size_t i = 0; i < buffer.size(); i++) { | ||
| 1030 | sample_buffer[mix_offset + i] = buffer[i]; | ||
| 1031 | } | ||
| 1032 | } else { | ||
| 1033 | const auto channel_count = in_params.channel_count; | ||
| 1034 | std::vector<s16> buffer(samples_processed * channel_count); | ||
| 1035 | memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16)); | ||
| 1036 | 1033 | ||
| 1034 | if constexpr (std::is_floating_point_v<T>) { | ||
| 1035 | for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) { | ||
| 1036 | sample_buffer[mix_offset + i] = static_cast<s32>(buffer[i * channel_count + channel] * | ||
| 1037 | std::numeric_limits<s16>::max()); | ||
| 1038 | } | ||
| 1039 | } else if constexpr (sizeof(T) == 1) { | ||
| 1040 | for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) { | ||
| 1041 | sample_buffer[mix_offset + i] = | ||
| 1042 | static_cast<s32>(static_cast<f32>(buffer[i * channel_count + channel] / | ||
| 1043 | std::numeric_limits<s8>::max()) * | ||
| 1044 | std::numeric_limits<s16>::max()); | ||
| 1045 | } | ||
| 1046 | } else if constexpr (sizeof(T) == 2) { | ||
| 1037 | for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) { | 1047 | for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) { |
| 1038 | sample_buffer[mix_offset + i] = buffer[i * channel_count + channel]; | 1048 | sample_buffer[mix_offset + i] = buffer[i * channel_count + channel]; |
| 1039 | } | 1049 | } |
| 1050 | } else { | ||
| 1051 | for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) { | ||
| 1052 | sample_buffer[mix_offset + i] = | ||
| 1053 | static_cast<s32>(static_cast<f32>(buffer[i * channel_count + channel] / | ||
| 1054 | std::numeric_limits<s32>::max()) * | ||
| 1055 | std::numeric_limits<s16>::max()); | ||
| 1056 | } | ||
| 1040 | } | 1057 | } |
| 1041 | 1058 | ||
| 1042 | return samples_processed; | 1059 | return samples_processed; |
| @@ -1249,10 +1266,25 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o | |||
| 1249 | 1266 | ||
| 1250 | s32 samples_decoded{0}; | 1267 | s32 samples_decoded{0}; |
| 1251 | switch (in_params.sample_format) { | 1268 | switch (in_params.sample_format) { |
| 1269 | case SampleFormat::Pcm8: | ||
| 1270 | samples_decoded = | ||
| 1271 | DecodePcm<s8>(voice_info, dsp_state, samples_offset_start, samples_offset_end, | ||
| 1272 | samples_to_read - samples_read, channel, temp_mix_offset); | ||
| 1273 | break; | ||
| 1252 | case SampleFormat::Pcm16: | 1274 | case SampleFormat::Pcm16: |
| 1253 | samples_decoded = | 1275 | samples_decoded = |
| 1254 | DecodePcm16(voice_info, dsp_state, samples_offset_start, samples_offset_end, | 1276 | DecodePcm<s16>(voice_info, dsp_state, samples_offset_start, samples_offset_end, |
| 1255 | samples_to_read - samples_read, channel, temp_mix_offset); | 1277 | samples_to_read - samples_read, channel, temp_mix_offset); |
| 1278 | break; | ||
| 1279 | case SampleFormat::Pcm32: | ||
| 1280 | samples_decoded = | ||
| 1281 | DecodePcm<s32>(voice_info, dsp_state, samples_offset_start, samples_offset_end, | ||
| 1282 | samples_to_read - samples_read, channel, temp_mix_offset); | ||
| 1283 | break; | ||
| 1284 | case SampleFormat::PcmFloat: | ||
| 1285 | samples_decoded = | ||
| 1286 | DecodePcm<f32>(voice_info, dsp_state, samples_offset_start, samples_offset_end, | ||
| 1287 | samples_to_read - samples_read, channel, temp_mix_offset); | ||
| 1256 | break; | 1288 | break; |
| 1257 | case SampleFormat::Adpcm: | 1289 | case SampleFormat::Adpcm: |
| 1258 | samples_decoded = | 1290 | samples_decoded = |
diff --git a/src/audio_core/command_generator.h b/src/audio_core/command_generator.h index 673e4fbef..f310d7317 100644 --- a/src/audio_core/command_generator.h +++ b/src/audio_core/command_generator.h | |||
| @@ -86,8 +86,9 @@ private: | |||
| 86 | std::vector<u8>& work_buffer); | 86 | std::vector<u8>& work_buffer); |
| 87 | void UpdateI3dl2Reverb(I3dl2ReverbParams& info, I3dl2ReverbState& state, bool should_clear); | 87 | void UpdateI3dl2Reverb(I3dl2ReverbParams& info, I3dl2ReverbState& state, bool should_clear); |
| 88 | // DSP Code | 88 | // DSP Code |
| 89 | s32 DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 sample_start_offset, | 89 | template <typename T> |
| 90 | s32 sample_end_offset, s32 sample_count, s32 channel, std::size_t mix_offset); | 90 | s32 DecodePcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 sample_start_offset, |
| 91 | s32 sample_end_offset, s32 sample_count, s32 channel, std::size_t mix_offset); | ||
| 91 | s32 DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 sample_start_offset, | 92 | s32 DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state, s32 sample_start_offset, |
| 92 | s32 sample_end_offset, s32 sample_count, s32 channel, std::size_t mix_offset); | 93 | s32 sample_end_offset, s32 sample_count, s32 channel, std::size_t mix_offset); |
| 93 | void DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* output, VoiceState& dsp_state, | 94 | void DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* output, VoiceState& dsp_state, |