diff options
| author | 2018-10-07 14:14:09 +1100 | |
|---|---|---|
| committer | 2018-10-07 14:14:09 +1100 | |
| commit | 2de52e3af65e71df8a1ef00c9bcfcaa9f67330c3 (patch) | |
| tree | 9b6e8edf522ccd2b29bcfa26bd357ffa632e29d2 /src/audio_core/audio_renderer.cpp | |
| parent | Merge pull request #1452 from FearlessTobi/port-4313 (diff) | |
| download | yuzu-2de52e3af65e71df8a1ef00c9bcfcaa9f67330c3.tar.gz yuzu-2de52e3af65e71df8a1ef00c9bcfcaa9f67330c3.tar.xz yuzu-2de52e3af65e71df8a1ef00c9bcfcaa9f67330c3.zip | |
Fixed smo softlock
Diffstat (limited to 'src/audio_core/audio_renderer.cpp')
| -rw-r--r-- | src/audio_core/audio_renderer.cpp | 84 |
1 files changed, 71 insertions, 13 deletions
diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp index 6f0ff953a..9b7970d42 100644 --- a/src/audio_core/audio_renderer.cpp +++ b/src/audio_core/audio_renderer.cpp | |||
| @@ -51,9 +51,30 @@ private: | |||
| 51 | VoiceInfo info{}; | 51 | VoiceInfo info{}; |
| 52 | }; | 52 | }; |
| 53 | 53 | ||
| 54 | class AudioRenderer::EffectState { | ||
| 55 | public: | ||
| 56 | const EffectOutStatus& GetOutStatus() const { | ||
| 57 | return out_status; | ||
| 58 | } | ||
| 59 | |||
| 60 | const EffectInStatus& GetInfo() const { | ||
| 61 | info; | ||
| 62 | } | ||
| 63 | |||
| 64 | EffectInStatus& Info() { | ||
| 65 | return info; | ||
| 66 | } | ||
| 67 | |||
| 68 | void UpdateState(); | ||
| 69 | |||
| 70 | private: | ||
| 71 | EffectOutStatus out_status{}; | ||
| 72 | EffectInStatus info{}; | ||
| 73 | }; | ||
| 54 | AudioRenderer::AudioRenderer(AudioRendererParameter params, | 74 | AudioRenderer::AudioRenderer(AudioRendererParameter params, |
| 55 | Kernel::SharedPtr<Kernel::Event> buffer_event) | 75 | Kernel::SharedPtr<Kernel::Event> buffer_event) |
| 56 | : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count) { | 76 | : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count), |
| 77 | effects(params.effect_count) { | ||
| 57 | 78 | ||
| 58 | audio_out = std::make_unique<AudioCore::AudioOut>(); | 79 | audio_out = std::make_unique<AudioCore::AudioOut>(); |
| 59 | stream = audio_out->OpenStream(STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, "AudioRenderer", | 80 | stream = audio_out->OpenStream(STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS, "AudioRenderer", |
| @@ -96,11 +117,29 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_ | |||
| 96 | memory_pool_count * sizeof(MemoryPoolInfo)); | 117 | memory_pool_count * sizeof(MemoryPoolInfo)); |
| 97 | 118 | ||
| 98 | // Copy VoiceInfo structs | 119 | // Copy VoiceInfo structs |
| 99 | std::size_t offset{sizeof(UpdateDataHeader) + config.behavior_size + config.memory_pools_size + | 120 | std::size_t voice_offset{sizeof(UpdateDataHeader) + config.behavior_size + |
| 100 | config.voice_resource_size}; | 121 | config.memory_pools_size + config.voice_resource_size}; |
| 101 | for (auto& voice : voices) { | 122 | for (auto& voice : voices) { |
| 102 | std::memcpy(&voice.Info(), input_params.data() + offset, sizeof(VoiceInfo)); | 123 | std::memcpy(&voice.Info(), input_params.data() + voice_offset, sizeof(VoiceInfo)); |
| 103 | offset += sizeof(VoiceInfo); | 124 | voice_offset += sizeof(VoiceInfo); |
| 125 | } | ||
| 126 | |||
| 127 | std::size_t effect_offset{sizeof(UpdateDataHeader) + config.behavior_size + | ||
| 128 | config.memory_pools_size + config.voice_resource_size + | ||
| 129 | config.voices_size}; | ||
| 130 | for (auto& effect : effects) { | ||
| 131 | std::memcpy(&effect.Info(), input_params.data() + effect_offset, sizeof(EffectInStatus)); | ||
| 132 | effect_offset += sizeof(EffectInStatus); | ||
| 133 | } | ||
| 134 | |||
| 135 | // Update memory pool state | ||
| 136 | std::vector<MemoryPoolEntry> memory_pool(memory_pool_count); | ||
| 137 | for (std::size_t index = 0; index < memory_pool.size(); ++index) { | ||
| 138 | if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestAttach) { | ||
| 139 | memory_pool[index].state = MemoryPoolStates::Attached; | ||
| 140 | } else if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestDetach) { | ||
| 141 | memory_pool[index].state = MemoryPoolStates::Detached; | ||
| 142 | } | ||
| 104 | } | 143 | } |
| 105 | 144 | ||
| 106 | // Update voices | 145 | // Update voices |
| @@ -114,14 +153,8 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_ | |||
| 114 | } | 153 | } |
| 115 | } | 154 | } |
| 116 | 155 | ||
| 117 | // Update memory pool state | 156 | for (auto& effect : effects) { |
| 118 | std::vector<MemoryPoolEntry> memory_pool(memory_pool_count); | 157 | effect.UpdateState(); |
| 119 | for (std::size_t index = 0; index < memory_pool.size(); ++index) { | ||
| 120 | if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestAttach) { | ||
| 121 | memory_pool[index].state = MemoryPoolStates::Attached; | ||
| 122 | } else if (mem_pool_info[index].pool_state == MemoryPoolStates::RequestDetach) { | ||
| 123 | memory_pool[index].state = MemoryPoolStates::Detached; | ||
| 124 | } | ||
| 125 | } | 158 | } |
| 126 | 159 | ||
| 127 | // Release previous buffers and queue next ones for playback | 160 | // Release previous buffers and queue next ones for playback |
| @@ -144,6 +177,14 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_ | |||
| 144 | voice_out_status_offset += sizeof(VoiceOutStatus); | 177 | voice_out_status_offset += sizeof(VoiceOutStatus); |
| 145 | } | 178 | } |
| 146 | 179 | ||
| 180 | std::size_t effect_out_status_offset{ | ||
| 181 | sizeof(UpdateDataHeader) + response_data.memory_pools_size + response_data.voices_size + | ||
| 182 | response_data.voice_resource_size}; | ||
| 183 | for (const auto& effect : effects) { | ||
| 184 | std::memcpy(output_params.data() + effect_out_status_offset, &effect.GetOutStatus(), | ||
| 185 | sizeof(EffectOutStatus)); | ||
| 186 | effect_out_status_offset += sizeof(EffectOutStatus); | ||
| 187 | } | ||
| 147 | return output_params; | 188 | return output_params; |
| 148 | } | 189 | } |
| 149 | 190 | ||
| @@ -249,6 +290,23 @@ void AudioRenderer::VoiceState::RefreshBuffer() { | |||
| 249 | is_refresh_pending = false; | 290 | is_refresh_pending = false; |
| 250 | } | 291 | } |
| 251 | 292 | ||
| 293 | void AudioRenderer::EffectState::UpdateState() { | ||
| 294 | if (info.is_new) { | ||
| 295 | out_status.state = EffectStatus::New; | ||
| 296 | } else { | ||
| 297 | if (info.type == Effect::Aux) { | ||
| 298 | ASSERT_MSG(Memory::Read32(info.aux_info.return_buffer_info) == 0, | ||
| 299 | "Aux buffers tried to update"); | ||
| 300 | ASSERT_MSG(Memory::Read32(info.aux_info.send_buffer_info) == 0, | ||
| 301 | "Aux buffers tried to update"); | ||
| 302 | ASSERT_MSG(Memory::Read32(info.aux_info.return_buffer_base) == 0, | ||
| 303 | "Aux buffers tried to update"); | ||
| 304 | ASSERT_MSG(Memory::Read32(info.aux_info.send_buffer_base) == 0, | ||
| 305 | "Aux buffers tried to update"); | ||
| 306 | } | ||
| 307 | } | ||
| 308 | } | ||
| 309 | |||
| 252 | static constexpr s16 ClampToS16(s32 value) { | 310 | static constexpr s16 ClampToS16(s32 value) { |
| 253 | return static_cast<s16>(std::clamp(value, -32768, 32767)); | 311 | return static_cast<s16>(std::clamp(value, -32768, 32767)); |
| 254 | } | 312 | } |