audio_renderer.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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/stream.h"
  9. #include "common/common_funcs.h"
  10. #include "common/common_types.h"
  11. #include "common/swap.h"
  12. #include "core/hle/kernel/object.h"
  13. namespace Kernel {
  14. class Event;
  15. }
  16. namespace AudioCore {
  17. class AudioOut;
  18. enum class PlayState : u8 {
  19. Started = 0,
  20. Stopped = 1,
  21. Paused = 2,
  22. };
  23. enum class Effect : u8 {
  24. None = 0,
  25. Aux = 2,
  26. };
  27. enum class EffectStatus : u8 {
  28. None = 0,
  29. New = 1,
  30. };
  31. struct AudioRendererParameter {
  32. u32_le sample_rate;
  33. u32_le sample_count;
  34. u32_le mix_buffer_count;
  35. u32_le unknown_c;
  36. u32_le voice_count;
  37. u32_le sink_count;
  38. u32_le effect_count;
  39. u32_le unknown_1c;
  40. u8 unknown_20;
  41. INSERT_PADDING_BYTES(3);
  42. u32_le splitter_count;
  43. u32_le unknown_2c;
  44. INSERT_PADDING_WORDS(1);
  45. u32_le revision;
  46. };
  47. static_assert(sizeof(AudioRendererParameter) == 52, "AudioRendererParameter is an invalid size");
  48. enum class MemoryPoolStates : u32 { // Should be LE
  49. Invalid = 0x0,
  50. Unknown = 0x1,
  51. RequestDetach = 0x2,
  52. Detached = 0x3,
  53. RequestAttach = 0x4,
  54. Attached = 0x5,
  55. Released = 0x6,
  56. };
  57. struct MemoryPoolEntry {
  58. MemoryPoolStates state;
  59. u32_le unknown_4;
  60. u32_le unknown_8;
  61. u32_le unknown_c;
  62. };
  63. static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size");
  64. struct MemoryPoolInfo {
  65. u64_le pool_address;
  66. u64_le pool_size;
  67. MemoryPoolStates pool_state;
  68. INSERT_PADDING_WORDS(3); // Unknown
  69. };
  70. static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size");
  71. struct BiquadFilter {
  72. u8 enable;
  73. INSERT_PADDING_BYTES(1);
  74. std::array<s16_le, 3> numerator;
  75. std::array<s16_le, 2> denominator;
  76. };
  77. static_assert(sizeof(BiquadFilter) == 0xc, "BiquadFilter has wrong size");
  78. struct WaveBuffer {
  79. u64_le buffer_addr;
  80. u64_le buffer_sz;
  81. s32_le start_sample_offset;
  82. s32_le end_sample_offset;
  83. u8 is_looping;
  84. u8 end_of_stream;
  85. u8 sent_to_server;
  86. INSERT_PADDING_BYTES(5);
  87. u64 context_addr;
  88. u64 context_sz;
  89. INSERT_PADDING_BYTES(8);
  90. };
  91. static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer has wrong size");
  92. struct 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. };
  117. static_assert(sizeof(VoiceInfo) == 0x170, "VoiceInfo is wrong size");
  118. struct VoiceOutStatus {
  119. u64_le played_sample_count;
  120. u32_le wave_buffer_consumed;
  121. u32_le voice_drops_count;
  122. };
  123. static_assert(sizeof(VoiceOutStatus) == 0x10, "VoiceOutStatus has wrong size");
  124. struct AuxInfo {
  125. std::array<u8, 24> input_mix_buffers;
  126. std::array<u8, 24> output_mix_buffers;
  127. u32_le mix_buffer_count;
  128. u32_le sample_rate; // Stored in the aux buffer currently
  129. u32_le sampe_count;
  130. u64_le send_buffer_info;
  131. u64_le send_buffer_base;
  132. u64_le return_buffer_info;
  133. u64_le return_buffer_base;
  134. };
  135. static_assert(sizeof(AuxInfo) == 0x60, "AuxInfo is an invalid size");
  136. struct EffectInStatus {
  137. Effect type;
  138. u8 is_new;
  139. u8 is_enabled;
  140. INSERT_PADDING_BYTES(1);
  141. u32_le mix_id;
  142. u64_le buffer_base;
  143. u64_le buffer_sz;
  144. s32_le priority;
  145. INSERT_PADDING_BYTES(4);
  146. union {
  147. std::array<u8, 0xa0> raw;
  148. AuxInfo aux_info;
  149. };
  150. };
  151. static_assert(sizeof(EffectInStatus) == 0xc0, "EffectInStatus is an invalid size");
  152. struct EffectOutStatus {
  153. EffectStatus state;
  154. INSERT_PADDING_BYTES(15);
  155. };
  156. static_assert(sizeof(EffectOutStatus) == 0x10, "EffectOutStatus is an invalid size");
  157. struct UpdateDataHeader {
  158. UpdateDataHeader() {}
  159. explicit UpdateDataHeader(const AudioRendererParameter& config) {
  160. revision = Common::MakeMagic('R', 'E', 'V', '4'); // 5.1.0 Revision
  161. behavior_size = 0xb0;
  162. memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10;
  163. voices_size = config.voice_count * 0x10;
  164. voice_resource_size = 0x0;
  165. effects_size = config.effect_count * 0x10;
  166. mixes_size = 0x0;
  167. sinks_size = config.sink_count * 0x20;
  168. performance_manager_size = 0x10;
  169. total_size = sizeof(UpdateDataHeader) + behavior_size + memory_pools_size + voices_size +
  170. effects_size + sinks_size + performance_manager_size;
  171. }
  172. u32_le revision;
  173. u32_le behavior_size;
  174. u32_le memory_pools_size;
  175. u32_le voices_size;
  176. u32_le voice_resource_size;
  177. u32_le effects_size;
  178. u32_le mixes_size;
  179. u32_le sinks_size;
  180. u32_le performance_manager_size;
  181. INSERT_PADDING_WORDS(6);
  182. u32_le total_size;
  183. };
  184. static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size");
  185. class AudioRenderer {
  186. public:
  187. AudioRenderer(AudioRendererParameter params, Kernel::SharedPtr<Kernel::Event> buffer_event);
  188. ~AudioRenderer();
  189. std::vector<u8> UpdateAudioRenderer(const std::vector<u8>& input_params);
  190. void QueueMixedBuffer(Buffer::Tag tag);
  191. void ReleaseAndQueueBuffers();
  192. u32 GetSampleRate() const;
  193. u32 GetSampleCount() const;
  194. u32 GetMixBufferCount() const;
  195. Stream::State GetStreamState() const;
  196. private:
  197. class VoiceState;
  198. class EffectState;
  199. AudioRendererParameter worker_params;
  200. Kernel::SharedPtr<Kernel::Event> buffer_event;
  201. std::vector<VoiceState> voices;
  202. std::vector<EffectState> effects;
  203. std::unique_ptr<AudioOut> audio_out;
  204. AudioCore::StreamPtr stream;
  205. };
  206. } // namespace AudioCore