audio_renderer.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. // Copyright 2018 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <memory>
  7. #include <vector>
  8. #include "audio_core/behavior_info.h"
  9. #include "audio_core/stream.h"
  10. #include "common/common_funcs.h"
  11. #include "common/common_types.h"
  12. #include "common/swap.h"
  13. #include "core/hle/kernel/object.h"
  14. #include "core/hle/result.h"
  15. namespace Core::Timing {
  16. class CoreTiming;
  17. }
  18. namespace Kernel {
  19. class WritableEvent;
  20. }
  21. namespace Core::Memory {
  22. class Memory;
  23. }
  24. namespace AudioCore {
  25. class AudioOut;
  26. enum class PlayState : u8 {
  27. Started = 0,
  28. Stopped = 1,
  29. Paused = 2,
  30. };
  31. enum class Effect : u8 {
  32. None = 0,
  33. Aux = 2,
  34. };
  35. enum class EffectStatus : u8 {
  36. None = 0,
  37. New = 1,
  38. };
  39. struct AudioRendererParameter {
  40. u32_le sample_rate;
  41. u32_le sample_count;
  42. u32_le mix_buffer_count;
  43. u32_le submix_count;
  44. u32_le voice_count;
  45. u32_le sink_count;
  46. u32_le effect_count;
  47. u32_le performance_frame_count;
  48. u8 is_voice_drop_enabled;
  49. u8 unknown_21;
  50. u8 unknown_22;
  51. u8 execution_mode;
  52. u32_le splitter_count;
  53. u32_le num_splitter_send_channels;
  54. u32_le unknown_30;
  55. u32_le revision;
  56. };
  57. static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size");
  58. enum class MemoryPoolStates : u32 { // Should be LE
  59. Invalid = 0x0,
  60. Unknown = 0x1,
  61. RequestDetach = 0x2,
  62. Detached = 0x3,
  63. RequestAttach = 0x4,
  64. Attached = 0x5,
  65. Released = 0x6,
  66. };
  67. struct MemoryPoolEntry {
  68. MemoryPoolStates state;
  69. u32_le unknown_4;
  70. u32_le unknown_8;
  71. u32_le unknown_c;
  72. };
  73. static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size");
  74. struct MemoryPoolInfo {
  75. u64_le pool_address;
  76. u64_le pool_size;
  77. MemoryPoolStates pool_state;
  78. INSERT_PADDING_WORDS(3); // Unknown
  79. };
  80. static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size");
  81. struct BiquadFilter {
  82. u8 enable;
  83. INSERT_PADDING_BYTES(1);
  84. std::array<s16_le, 3> numerator;
  85. std::array<s16_le, 2> denominator;
  86. };
  87. static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size");
  88. struct WaveBuffer {
  89. u64_le buffer_addr;
  90. u64_le buffer_sz;
  91. s32_le start_sample_offset;
  92. s32_le end_sample_offset;
  93. u8 is_looping;
  94. u8 end_of_stream;
  95. u8 sent_to_server;
  96. INSERT_PADDING_BYTES(5);
  97. u64 context_addr;
  98. u64 context_sz;
  99. INSERT_PADDING_BYTES(8);
  100. };
  101. static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size");
  102. struct VoiceInfo {
  103. u32_le id;
  104. u32_le node_id;
  105. u8 is_new;
  106. u8 is_in_use;
  107. PlayState play_state;
  108. u8 sample_format;
  109. u32_le sample_rate;
  110. u32_le priority;
  111. u32_le sorting_order;
  112. u32_le channel_count;
  113. float_le pitch;
  114. float_le volume;
  115. std::array<BiquadFilter, 2> biquad_filter;
  116. u32_le wave_buffer_count;
  117. u32_le wave_buffer_head;
  118. INSERT_PADDING_WORDS(1);
  119. u64_le additional_params_addr;
  120. u64_le additional_params_sz;
  121. u32_le mix_id;
  122. u32_le splitter_info_id;
  123. std::array<WaveBuffer, 4> wave_buffer;
  124. std::array<u32_le, 6> voice_channel_resource_ids;
  125. INSERT_PADDING_BYTES(24);
  126. };
  127. static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size");
  128. struct VoiceOutStatus {
  129. u64_le played_sample_count;
  130. u32_le wave_buffer_consumed;
  131. u32_le voice_drops_count;
  132. };
  133. static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size");
  134. struct AuxInfo {
  135. std::array<u8, 24> input_mix_buffers;
  136. std::array<u8, 24> output_mix_buffers;
  137. u32_le mix_buffer_count;
  138. u32_le sample_rate; // Stored in the aux buffer currently
  139. u32_le sample_count;
  140. u64_le send_buffer_info;
  141. u64_le send_buffer_base;
  142. u64_le return_buffer_info;
  143. u64_le return_buffer_base;
  144. };
  145. static_assert(sizeof(AuxInfo) == 0x60, "AuxInfo is an invalid size");
  146. struct EffectInStatus {
  147. Effect type;
  148. u8 is_new;
  149. u8 is_enabled;
  150. INSERT_PADDING_BYTES(1);
  151. u32_le mix_id;
  152. u64_le buffer_base;
  153. u64_le buffer_sz;
  154. s32_le priority;
  155. INSERT_PADDING_BYTES(4);
  156. union {
  157. std::array<u8, 0xa0> raw;
  158. AuxInfo aux_info;
  159. };
  160. };
  161. static_assert(sizeof(EffectInStatus) == 0xc0, "EffectInStatus is an invalid size");
  162. struct EffectOutStatus {
  163. EffectStatus state;
  164. INSERT_PADDING_BYTES(0xf);
  165. };
  166. static_assert(sizeof(EffectOutStatus) == 0x10, "EffectOutStatus is an invalid size");
  167. struct UpdateDataHeader {
  168. UpdateDataHeader() {}
  169. explicit UpdateDataHeader(const AudioRendererParameter& config) {
  170. revision = Common::MakeMagic('R', 'E', 'V', '8'); // 9.2.0 Revision
  171. behavior_size = 0xb0;
  172. memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10;
  173. voices_size = config.voice_count * 0x10;
  174. voice_resource_size = 0x0;
  175. effects_size = config.effect_count * 0x10;
  176. mixes_size = 0x0;
  177. sinks_size = config.sink_count * 0x20;
  178. performance_manager_size = 0x10;
  179. frame_count = 0;
  180. total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size +
  181. effects_size + sinks_size + performance_manager_size;
  182. }
  183. u32_le revision{};
  184. u32_le behavior_size{};
  185. u32_le memory_pools_size{};
  186. u32_le voices_size{};
  187. u32_le voice_resource_size{};
  188. u32_le effects_size{};
  189. u32_le mixes_size{};
  190. u32_le sinks_size{};
  191. u32_le performance_manager_size{};
  192. INSERT_PADDING_WORDS(1);
  193. u32_le frame_count{};
  194. INSERT_PADDING_WORDS(4);
  195. u32_le total_size{};
  196. };
  197. static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size");
  198. class AudioRenderer {
  199. public:
  200. AudioRenderer(Core::Timing::CoreTiming& core_timing, Core::Memory::Memory& memory_,
  201. AudioRendererParameter params,
  202. std::shared_ptr<Kernel::WritableEvent> buffer_event, std::size_t instance_number);
  203. ~AudioRenderer();
  204. ResultVal<std::vector<u8>> UpdateAudioRenderer(const std::vector<u8>& input_params);
  205. void QueueMixedBuffer(Buffer::Tag tag);
  206. void ReleaseAndQueueBuffers();
  207. u32 GetSampleRate() const;
  208. u32 GetSampleCount() const;
  209. u32 GetMixBufferCount() const;
  210. Stream::State GetStreamState() const;
  211. private:
  212. class EffectState;
  213. class VoiceState;
  214. BehaviorInfo behavior_info{};
  215. AudioRendererParameter worker_params;
  216. std::shared_ptr<Kernel::WritableEvent> buffer_event;
  217. std::vector<VoiceState> voices;
  218. std::vector<EffectState> effects;
  219. std::unique_ptr<AudioOut> audio_out;
  220. StreamPtr stream;
  221. Core::Memory::Memory& memory;
  222. };
  223. } // namespace AudioCore