summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar David2018-07-04 03:09:11 +1000
committerGravatar bunnei2018-07-03 13:09:10 -0400
commit3dab0e284b2969d8f52a1bd6863428fe626c6c7e (patch)
tree54c7e96d9dd01549b72953796106c083fc8eb5af /src
parentMerge pull request #607 from jroweboy/logging (diff)
downloadyuzu-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.cpp87
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
185class IAudioDevice final : public ServiceFramework<IAudioDevice> { 272class IAudioDevice final : public ServiceFramework<IAudioDevice> {