diff options
| author | 2018-07-04 03:09:11 +1000 | |
|---|---|---|
| committer | 2018-07-03 13:09:10 -0400 | |
| commit | 3dab0e284b2969d8f52a1bd6863428fe626c6c7e (patch) | |
| tree | 54c7e96d9dd01549b72953796106c083fc8eb5af /src | |
| parent | Merge pull request #607 from jroweboy/logging (diff) | |
| download | yuzu-3dab0e284b2969d8f52a1bd6863428fe626c6c7e.tar.gz yuzu-3dab0e284b2969d8f52a1bd6863428fe626c6c7e.tar.xz yuzu-3dab0e284b2969d8f52a1bd6863428fe626c6c7e.zip | |
Update AudioRenderer Voice Sections (#614)
* voice section updating
* fixed slight offset miscalculation
* fixed overflow
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index e62372cb4..2da936b27 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -47,6 +47,7 @@ public: | |||
| 47 | 47 | ||
| 48 | // Start the audio event | 48 | // Start the audio event |
| 49 | CoreTiming::ScheduleEvent(audio_ticks, audio_event); | 49 | CoreTiming::ScheduleEvent(audio_ticks, audio_event); |
| 50 | voice_status_list.reserve(worker_params.voice_count); | ||
| 50 | } | 51 | } |
| 51 | ~IAudioRenderer() { | 52 | ~IAudioRenderer() { |
| 52 | CoreTiming::UnscheduleEvent(audio_event, 0); | 53 | CoreTiming::UnscheduleEvent(audio_event, 0); |
| @@ -68,6 +69,12 @@ private: | |||
| 68 | buf.data() + sizeof(UpdateDataHeader) + config.behavior_size, | 69 | buf.data() + sizeof(UpdateDataHeader) + config.behavior_size, |
| 69 | memory_pool_count * sizeof(MemoryPoolInfo)); | 70 | memory_pool_count * sizeof(MemoryPoolInfo)); |
| 70 | 71 | ||
| 72 | std::vector<VoiceInfo> voice_info(worker_params.voice_count); | ||
| 73 | std::memcpy(voice_info.data(), | ||
| 74 | buf.data() + sizeof(UpdateDataHeader) + config.behavior_size + | ||
| 75 | config.memory_pools_size + config.voice_resource_size, | ||
| 76 | worker_params.voice_count * sizeof(VoiceInfo)); | ||
| 77 | |||
| 71 | UpdateDataHeader response_data{worker_params}; | 78 | UpdateDataHeader response_data{worker_params}; |
| 72 | 79 | ||
| 73 | ASSERT(ctx.GetWriteBufferSize() == response_data.total_size); | 80 | ASSERT(ctx.GetWriteBufferSize() == response_data.total_size); |
| @@ -86,6 +93,23 @@ private: | |||
| 86 | std::memcpy(output.data() + sizeof(UpdateDataHeader), memory_pool.data(), | 93 | std::memcpy(output.data() + sizeof(UpdateDataHeader), memory_pool.data(), |
| 87 | response_data.memory_pools_size); | 94 | response_data.memory_pools_size); |
| 88 | 95 | ||
| 96 | for (unsigned i = 0; i < voice_info.size(); i++) { | ||
| 97 | if (voice_info[i].is_new) { | ||
| 98 | voice_status_list[i].played_sample_count = 0; | ||
| 99 | voice_status_list[i].wave_buffer_consumed = 0; | ||
| 100 | } else if (voice_info[i].play_state == (u8)PlayStates::Started) { | ||
| 101 | for (u32 buff_idx = 0; buff_idx < voice_info[i].wave_buffer_count; buff_idx++) { | ||
| 102 | voice_status_list[i].played_sample_count += | ||
| 103 | (voice_info[i].wave_buffer[buff_idx].end_sample_offset - | ||
| 104 | voice_info[i].wave_buffer[buff_idx].start_sample_offset) / | ||
| 105 | 2; | ||
| 106 | voice_status_list[i].wave_buffer_consumed++; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | } | ||
| 110 | std::memcpy(output.data() + sizeof(UpdateDataHeader) + response_data.memory_pools_size, | ||
| 111 | voice_status_list.data(), response_data.voices_size); | ||
| 112 | |||
| 89 | ctx.WriteBuffer(output); | 113 | ctx.WriteBuffer(output); |
| 90 | 114 | ||
| 91 | IPC::ResponseBuilder rb{ctx, 2}; | 115 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -130,6 +154,11 @@ private: | |||
| 130 | Released = 0x6, | 154 | Released = 0x6, |
| 131 | }; | 155 | }; |
| 132 | 156 | ||
| 157 | enum class PlayStates : u8 { | ||
| 158 | Started = 0, | ||
| 159 | Stopped = 1, | ||
| 160 | }; | ||
| 161 | |||
| 133 | struct MemoryPoolEntry { | 162 | struct MemoryPoolEntry { |
| 134 | MemoryPoolStates state; | 163 | MemoryPoolStates state; |
| 135 | u32_le unknown_4; | 164 | u32_le unknown_4; |
| @@ -175,11 +204,69 @@ private: | |||
| 175 | }; | 204 | }; |
| 176 | static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size"); | 205 | static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size"); |
| 177 | 206 | ||
| 207 | struct BiquadFilter { | ||
| 208 | u8 enable; | ||
| 209 | INSERT_PADDING_BYTES(1); | ||
| 210 | s16_le numerator[3]; | ||
| 211 | s16_le denominator[2]; | ||
| 212 | }; | ||
| 213 | static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size"); | ||
| 214 | |||
| 215 | struct WaveBuffer { | ||
| 216 | u64_le buffer_addr; | ||
| 217 | u64_le buffer_sz; | ||
| 218 | s32_le start_sample_offset; | ||
| 219 | s32_le end_sample_offset; | ||
| 220 | u8 loop; | ||
| 221 | u8 end_of_stream; | ||
| 222 | u8 sent_to_server; | ||
| 223 | INSERT_PADDING_BYTES(5); | ||
| 224 | u64 context_addr; | ||
| 225 | u64 context_sz; | ||
| 226 | INSERT_PADDING_BYTES(8); | ||
| 227 | }; | ||
| 228 | static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size"); | ||
| 229 | |||
| 230 | struct VoiceInfo { | ||
| 231 | u32_le id; | ||
| 232 | u32_le node_id; | ||
| 233 | u8 is_new; | ||
| 234 | u8 is_in_use; | ||
| 235 | u8 play_state; | ||
| 236 | u8 sample_format; | ||
| 237 | u32_le sample_rate; | ||
| 238 | u32_le priority; | ||
| 239 | u32_le sorting_order; | ||
| 240 | u32_le channel_count; | ||
| 241 | float_le pitch; | ||
| 242 | float_le volume; | ||
| 243 | BiquadFilter biquad_filter[2]; | ||
| 244 | u32_le wave_buffer_count; | ||
| 245 | u16_le wave_buffer_head; | ||
| 246 | INSERT_PADDING_BYTES(6); | ||
| 247 | u64_le additional_params_addr; | ||
| 248 | u64_le additional_params_sz; | ||
| 249 | u32_le mix_id; | ||
| 250 | u32_le splitter_info_id; | ||
| 251 | WaveBuffer wave_buffer[4]; | ||
| 252 | u32_le voice_channel_resource_ids[6]; | ||
| 253 | INSERT_PADDING_BYTES(24); | ||
| 254 | }; | ||
| 255 | static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size"); | ||
| 256 | |||
| 257 | struct VoiceOutStatus { | ||
| 258 | u64_le played_sample_count; | ||
| 259 | u32_le wave_buffer_consumed; | ||
| 260 | INSERT_PADDING_WORDS(1); | ||
| 261 | }; | ||
| 262 | static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size"); | ||
| 263 | |||
| 178 | /// This is used to trigger the audio event callback. | 264 | /// This is used to trigger the audio event callback. |
| 179 | CoreTiming::EventType* audio_event; | 265 | CoreTiming::EventType* audio_event; |
| 180 | 266 | ||
| 181 | Kernel::SharedPtr<Kernel::Event> system_event; | 267 | Kernel::SharedPtr<Kernel::Event> system_event; |
| 182 | AudioRendererParameter worker_params; | 268 | AudioRendererParameter worker_params; |
| 269 | std::vector<VoiceOutStatus> voice_status_list; | ||
| 183 | }; | 270 | }; |
| 184 | 271 | ||
| 185 | class IAudioDevice final : public ServiceFramework<IAudioDevice> { | 272 | class IAudioDevice final : public ServiceFramework<IAudioDevice> { |