summaryrefslogtreecommitdiff
path: root/src/audio_core/audio_renderer.h
diff options
context:
space:
mode:
authorGravatar bunnei2018-08-04 17:45:14 -0400
committerGravatar bunnei2018-08-04 21:54:30 -0400
commitb46df98e935552ea48ed86360e8c8b34b294982d (patch)
tree95a17bc97a704c5e3dfb41d11c3579b88141dbe2 /src/audio_core/audio_renderer.h
parentaudio_core: Use s16 where possible for audio samples. (diff)
downloadyuzu-b46df98e935552ea48ed86360e8c8b34b294982d.tar.gz
yuzu-b46df98e935552ea48ed86360e8c8b34b294982d.tar.xz
yuzu-b46df98e935552ea48ed86360e8c8b34b294982d.zip
audio_core: Implement audren_u audio playback.
Diffstat (limited to 'src/audio_core/audio_renderer.h')
-rw-r--r--src/audio_core/audio_renderer.h206
1 files changed, 206 insertions, 0 deletions
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h
new file mode 100644
index 000000000..6950a4681
--- /dev/null
+++ b/src/audio_core/audio_renderer.h
@@ -0,0 +1,206 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <memory>
9#include <vector>
10
11#include "audio_core/audio_out.h"
12#include "audio_core/codec.h"
13#include "audio_core/stream.h"
14#include "common/common_types.h"
15#include "common/swap.h"
16#include "core/hle/kernel/event.h"
17
18namespace AudioCore {
19
20enum class PlayState : u8 {
21 Started = 0,
22 Stopped = 1,
23 Paused = 2,
24};
25
26struct AudioRendererParameter {
27 u32_le sample_rate;
28 u32_le sample_count;
29 u32_le unknown_8;
30 u32_le unknown_c;
31 u32_le voice_count;
32 u32_le sink_count;
33 u32_le effect_count;
34 u32_le unknown_1c;
35 u8 unknown_20;
36 INSERT_PADDING_BYTES(3);
37 u32_le splitter_count;
38 u32_le unknown_2c;
39 INSERT_PADDING_WORDS(1);
40 u32_le revision;
41};
42static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size");
43
44enum class MemoryPoolStates : u32 { // Should be LE
45 Invalid = 0x0,
46 Unknown = 0x1,
47 RequestDetach = 0x2,
48 Detached = 0x3,
49 RequestAttach = 0x4,
50 Attached = 0x5,
51 Released = 0x6,
52};
53
54struct MemoryPoolEntry {
55 MemoryPoolStates state;
56 u32_le unknown_4;
57 u32_le unknown_8;
58 u32_le unknown_c;
59};
60static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size");
61
62struct MemoryPoolInfo {
63 u64_le pool_address;
64 u64_le pool_size;
65 MemoryPoolStates pool_state;
66 INSERT_PADDING_WORDS(3); // Unknown
67};
68static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size");
69struct BiquadFilter {
70 u8 enable;
71 INSERT_PADDING_BYTES(1);
72 std::array<s16_le, 3> numerator;
73 std::array<s16_le, 2> denominator;
74};
75static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size");
76
77struct WaveBuffer {
78 u64_le buffer_addr;
79 u64_le buffer_sz;
80 s32_le start_sample_offset;
81 s32_le end_sample_offset;
82 u8 is_looping;
83 u8 end_of_stream;
84 u8 sent_to_server;
85 INSERT_PADDING_BYTES(5);
86 u64 context_addr;
87 u64 context_sz;
88 INSERT_PADDING_BYTES(8);
89};
90static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size");
91
92struct VoiceInfo {
93 u32_le id;
94 u32_le node_id;
95 u8 is_new;
96 u8 is_in_use;
97 PlayState play_state;
98 u8 sample_format;
99 u32_le sample_rate;
100 u32_le priority;
101 u32_le sorting_order;
102 u32_le channel_count;
103 float_le pitch;
104 float_le volume;
105 std::array<BiquadFilter, 2> biquad_filter;
106 u32_le wave_buffer_count;
107 u32_le wave_buffer_head;
108 INSERT_PADDING_WORDS(1);
109 u64_le additional_params_addr;
110 u64_le additional_params_sz;
111 u32_le mix_id;
112 u32_le splitter_info_id;
113 std::array<WaveBuffer, 4> wave_buffer;
114 std::array<u32_le, 6> voice_channel_resource_ids;
115 INSERT_PADDING_BYTES(24);
116};
117static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size");
118
119struct VoiceOutStatus {
120 u64_le played_sample_count;
121 u32_le wave_buffer_consumed;
122 u32_le voice_drops_count;
123};
124static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size");
125
126struct UpdateDataHeader {
127 UpdateDataHeader() {}
128
129 explicit UpdateDataHeader(const AudioRendererParameter& config) {
130 revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision
131 behavior_size = 0xb0;
132 memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10;
133 voices_size = config.voice_count * 0x10;
134 voice_resource_size = 0x0;
135 effects_size = config.effect_count * 0x10;
136 mixes_size = 0x0;
137 sinks_size = config.sink_count * 0x20;
138 performance_manager_size = 0x10;
139 total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size +
140 effects_size + sinks_size + performance_manager_size;
141 }
142
143 u32_le revision;
144 u32_le behavior_size;
145 u32_le memory_pools_size;
146 u32_le voices_size;
147 u32_le voice_resource_size;
148 u32_le effects_size;
149 u32_le mixes_size;
150 u32_le sinks_size;
151 u32_le performance_manager_size;
152 INSERT_PADDING_WORDS(6);
153 u32_le total_size;
154};
155static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size");
156
157class AudioRenderer {
158public:
159 AudioRenderer(AudioRendererParameter params, Kernel::SharedPtr<Kernel::Event> buffer_event);
160 std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params);
161 void QueueMixedBuffer(Buffer::Tag tag);
162 void ReleaseAndQueueBuffers();
163
164private:
165 class VoiceState {
166 public:
167 bool IsPlaying() const {
168 return is_in_use && info.play_state == PlayState::Started;
169 }
170
171 const VoiceOutStatus& GetOutStatus() const {
172 return out_status;
173 }
174
175 const VoiceInfo& GetInfo() const {
176 return info;
177 }
178
179 VoiceInfo& Info() {
180 return info;
181 }
182
183 void SetWaveIndex(size_t index);
184 std::vector<s16> DequeueSamples(size_t sample_count);
185 void UpdateState();
186 void RefreshBuffer();
187
188 private:
189 bool is_in_use{};
190 bool is_refresh_pending{};
191 size_t wave_index{};
192 size_t offset{};
193 Codec::ADPCMState adpcm_state{};
194 std::vector<s16> samples;
195 VoiceOutStatus out_status{};
196 VoiceInfo info{};
197 };
198
199 AudioRendererParameter worker_params;
200 Kernel::SharedPtr<Kernel::Event> buffer_event;
201 std::vector<VoiceState> voices;
202 std::unique_ptr<AudioCore::AudioOut> audio_core;
203 AudioCore::StreamPtr stream;
204};
205
206} // namespace AudioCore