summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar David Marcec2018-10-07 14:14:09 +1100
committerGravatar David Marcec2018-10-07 14:14:09 +1100
commit2de52e3af65e71df8a1ef00c9bcfcaa9f67330c3 (patch)
tree9b6e8edf522ccd2b29bcfa26bd357ffa632e29d2
parentMerge pull request #1452 from FearlessTobi/port-4313 (diff)
downloadyuzu-2de52e3af65e71df8a1ef00c9bcfcaa9f67330c3.tar.gz
yuzu-2de52e3af65e71df8a1ef00c9bcfcaa9f67330c3.tar.xz
yuzu-2de52e3af65e71df8a1ef00c9bcfcaa9f67330c3.zip
Fixed smo softlock
-rw-r--r--src/audio_core/audio_renderer.cpp84
-rw-r--r--src/audio_core/audio_renderer.h49
2 files changed, 120 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
54class AudioRenderer::EffectState {
55public:
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
70private:
71 EffectOutStatus out_status{};
72 EffectInStatus info{};
73};
54AudioRenderer::AudioRenderer(AudioRendererParameter params, 74AudioRenderer::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
293void 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
252static constexpr s16 ClampToS16(s32 value) { 310static 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}
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h
index dfef89e1d..a2caeb118 100644
--- a/src/audio_core/audio_renderer.h
+++ b/src/audio_core/audio_renderer.h
@@ -28,6 +28,16 @@ enum class PlayState : u8 {
28 Paused = 2, 28 Paused = 2,
29}; 29};
30 30
31enum class Effect : u8 {
32 None = 0,
33 Aux = 2,
34};
35
36enum class EffectStatus : u8 {
37 None = 0,
38 New = 1,
39};
40
31struct AudioRendererParameter { 41struct AudioRendererParameter {
32 u32_le sample_rate; 42 u32_le sample_rate;
33 u32_le sample_count; 43 u32_le sample_count;
@@ -128,6 +138,43 @@ struct VoiceOutStatus {
128}; 138};
129static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size"); 139static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size");
130 140
141struct AuxInfo {
142 std::array<u8, 24> input_mix_buffers;
143 std::array<u8, 24> output_mix_buffers;
144 u32_le mix_buffer_count;
145 u32_le sample_rate; // Stored in the aux buffer currently
146 u32_le sampe_count;
147 u64_le send_buffer_info;
148 u64_le send_buffer_base;
149
150 u64_le return_buffer_info;
151 u64_le return_buffer_base;
152};
153static_assert(sizeof(AuxInfo) == 0x60, "AuxInfo is an invalid size");
154
155struct EffectInStatus {
156 Effect type;
157 u8 is_new;
158 u8 is_enabled;
159 INSERT_PADDING_BYTES(1);
160 u32_le mix_id;
161 u64_le buffer_base;
162 u64_le buffer_sz;
163 s32_le priority;
164 INSERT_PADDING_BYTES(4);
165 union {
166 std::array<u8, 0xa0> raw;
167 AuxInfo aux_info;
168 };
169};
170static_assert(sizeof(EffectInStatus) == 0xc0, "EffectInStatus is an invalid size");
171
172struct EffectOutStatus {
173 EffectStatus state;
174 INSERT_PADDING_BYTES(15);
175};
176static_assert(sizeof(EffectOutStatus) == 0x10, "EffectOutStatus is an invalid size");
177
131struct UpdateDataHeader { 178struct UpdateDataHeader {
132 UpdateDataHeader() {} 179 UpdateDataHeader() {}
133 180
@@ -174,10 +221,12 @@ public:
174 221
175private: 222private:
176 class VoiceState; 223 class VoiceState;
224 class EffectState;
177 225
178 AudioRendererParameter worker_params; 226 AudioRendererParameter worker_params;
179 Kernel::SharedPtr<Kernel::Event> buffer_event; 227 Kernel::SharedPtr<Kernel::Event> buffer_event;
180 std::vector<VoiceState> voices; 228 std::vector<VoiceState> voices;
229 std::vector<EffectState> effects;
181 std::unique_ptr<AudioOut> audio_out; 230 std::unique_ptr<AudioOut> audio_out;
182 AudioCore::StreamPtr stream; 231 AudioCore::StreamPtr stream;
183}; 232};