voice_context.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. // Copyright 2020 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 "audio_core/algorithm/interpolate.h"
  7. #include "audio_core/codec.h"
  8. #include "audio_core/common.h"
  9. #include "common/bit_field.h"
  10. #include "common/common_funcs.h"
  11. #include "common/common_types.h"
  12. namespace Core::Memory {
  13. class Memory;
  14. }
  15. namespace AudioCore {
  16. class BehaviorInfo;
  17. class VoiceContext;
  18. enum class SampleFormat : u8 {
  19. Invalid = 0,
  20. Pcm8 = 1,
  21. Pcm16 = 2,
  22. Pcm24 = 3,
  23. Pcm32 = 4,
  24. PcmFloat = 5,
  25. Adpcm = 6,
  26. };
  27. enum class PlayState : u8 {
  28. Started = 0,
  29. Stopped = 1,
  30. Paused = 2,
  31. };
  32. enum class ServerPlayState {
  33. Play = 0,
  34. Stop = 1,
  35. RequestStop = 2,
  36. Paused = 3,
  37. };
  38. struct BiquadFilterParameter {
  39. bool enabled{};
  40. INSERT_PADDING_BYTES(1);
  41. std::array<s16, 3> numerator{};
  42. std::array<s16, 2> denominator{};
  43. };
  44. static_assert(sizeof(BiquadFilterParameter) == 0xc, "BiquadFilterParameter is an invalid size");
  45. struct WaveBuffer {
  46. u64_le buffer_address{};
  47. u64_le buffer_size{};
  48. s32_le start_sample_offset{};
  49. s32_le end_sample_offset{};
  50. u8 is_looping{};
  51. u8 end_of_stream{};
  52. u8 sent_to_server{};
  53. INSERT_PADDING_BYTES(5);
  54. u64 context_address{};
  55. u64 context_size{};
  56. INSERT_PADDING_BYTES(8);
  57. };
  58. static_assert(sizeof(WaveBuffer) == 0x38, "WaveBuffer is an invalid size");
  59. struct ServerWaveBuffer {
  60. VAddr buffer_address{};
  61. std::size_t buffer_size{};
  62. s32 start_sample_offset{};
  63. s32 end_sample_offset{};
  64. bool is_looping{};
  65. bool end_of_stream{};
  66. VAddr context_address{};
  67. std::size_t context_size{};
  68. bool sent_to_dsp{true};
  69. };
  70. struct BehaviorFlags {
  71. BitField<0, 1, u16> is_played_samples_reset_at_loop_point;
  72. BitField<1, 1, u16> is_pitch_and_src_skipped;
  73. };
  74. static_assert(sizeof(BehaviorFlags) == 0x4, "BehaviorFlags is an invalid size");
  75. struct ADPCMContext {
  76. u16 header{};
  77. s16 yn1{};
  78. s16 yn2{};
  79. };
  80. static_assert(sizeof(ADPCMContext) == 0x6, "ADPCMContext is an invalid size");
  81. struct VoiceState {
  82. s64 played_sample_count{};
  83. s32 offset{};
  84. s32 wave_buffer_index{};
  85. std::array<bool, AudioCommon::MAX_WAVE_BUFFERS> is_wave_buffer_valid{};
  86. s32 wave_buffer_consumed{};
  87. std::array<s32, AudioCommon::MAX_SAMPLE_HISTORY> sample_history{};
  88. s32 fraction{};
  89. VAddr context_address{};
  90. Codec::ADPCM_Coeff coeff{};
  91. ADPCMContext context{};
  92. std::array<s64, 2> biquad_filter_state{};
  93. std::array<s32, AudioCommon::MAX_MIX_BUFFERS> previous_samples{};
  94. u32 external_context_size{};
  95. bool is_external_context_used{};
  96. bool voice_dropped{};
  97. };
  98. class VoiceChannelResource {
  99. public:
  100. struct InParams {
  101. s32_le id{};
  102. std::array<float_le, AudioCommon::MAX_MIX_BUFFERS> mix_volume{};
  103. bool in_use{};
  104. INSERT_PADDING_BYTES(11);
  105. };
  106. static_assert(sizeof(VoiceChannelResource::InParams) == 0x70, "InParams is an invalid size");
  107. };
  108. class ServerVoiceChannelResource {
  109. public:
  110. explicit ServerVoiceChannelResource(s32 id);
  111. ~ServerVoiceChannelResource();
  112. bool InUse() const;
  113. float GetCurrentMixVolumeAt(std::size_t i) const;
  114. float GetLastMixVolumeAt(std::size_t i) const;
  115. void Update(VoiceChannelResource::InParams& in_params);
  116. void UpdateLastMixVolumes();
  117. const std::array<float, AudioCommon::MAX_MIX_BUFFERS>& GetCurrentMixVolume() const;
  118. const std::array<float, AudioCommon::MAX_MIX_BUFFERS>& GetLastMixVolume() const;
  119. private:
  120. s32 id{};
  121. std::array<float, AudioCommon::MAX_MIX_BUFFERS> mix_volume{};
  122. std::array<float, AudioCommon::MAX_MIX_BUFFERS> last_mix_volume{};
  123. bool in_use{};
  124. };
  125. class VoiceInfo {
  126. public:
  127. struct InParams {
  128. s32_le id{};
  129. u32_le node_id{};
  130. u8 is_new{};
  131. u8 is_in_use{};
  132. PlayState play_state{};
  133. SampleFormat sample_format{};
  134. s32_le sample_rate{};
  135. s32_le priority{};
  136. s32_le sorting_order{};
  137. s32_le channel_count{};
  138. float_le pitch{};
  139. float_le volume{};
  140. std::array<BiquadFilterParameter, 2> biquad_filter{};
  141. s32_le wave_buffer_count{};
  142. s16_le wave_buffer_head{};
  143. INSERT_PADDING_BYTES(6);
  144. u64_le additional_params_address{};
  145. u64_le additional_params_size{};
  146. s32_le mix_id{};
  147. s32_le splitter_info_id{};
  148. std::array<WaveBuffer, 4> wave_buffer{};
  149. std::array<u32_le, 6> voice_channel_resource_ids{};
  150. // TODO(ogniK): Remaining flags
  151. u8 is_voice_drop_flag_clear_requested{};
  152. u8 wave_buffer_flush_request_count{};
  153. INSERT_PADDING_BYTES(2);
  154. BehaviorFlags behavior_flags{};
  155. INSERT_PADDING_BYTES(16);
  156. };
  157. static_assert(sizeof(VoiceInfo::InParams) == 0x170, "InParams is an invalid size");
  158. struct OutParams {
  159. u64_le played_sample_count{};
  160. u32_le wave_buffer_consumed{};
  161. u8 voice_dropped{};
  162. INSERT_PADDING_BYTES(3);
  163. };
  164. static_assert(sizeof(VoiceInfo::OutParams) == 0x10, "OutParams is an invalid size");
  165. };
  166. class ServerVoiceInfo {
  167. public:
  168. struct InParams {
  169. bool in_use{};
  170. bool is_new{};
  171. bool should_depop{};
  172. SampleFormat sample_format{};
  173. s32 sample_rate{};
  174. s32 channel_count{};
  175. s32 id{};
  176. s32 node_id{};
  177. s32 mix_id{};
  178. ServerPlayState current_playstate{};
  179. ServerPlayState last_playstate{};
  180. s32 priority{};
  181. s32 sorting_order{};
  182. float pitch{};
  183. float volume{};
  184. float last_volume{};
  185. std::array<BiquadFilterParameter, AudioCommon::MAX_BIQUAD_FILTERS> biquad_filter{};
  186. s32 wave_buffer_count{};
  187. s16 wave_bufffer_head{};
  188. INSERT_PADDING_BYTES(2);
  189. BehaviorFlags behavior_flags{};
  190. VAddr additional_params_address{};
  191. std::size_t additional_params_size{};
  192. std::array<ServerWaveBuffer, AudioCommon::MAX_WAVE_BUFFERS> wave_buffer{};
  193. std::array<s32, AudioCommon::MAX_CHANNEL_COUNT> voice_channel_resource_id{};
  194. s32 splitter_info_id{};
  195. u8 wave_buffer_flush_request_count{};
  196. bool voice_drop_flag{};
  197. bool buffer_mapped{};
  198. std::array<bool, AudioCommon::MAX_BIQUAD_FILTERS> was_biquad_filter_enabled{};
  199. };
  200. struct OutParams {
  201. s64 played_sample_count{};
  202. s32 wave_buffer_consumed{};
  203. };
  204. ServerVoiceInfo();
  205. ~ServerVoiceInfo();
  206. void Initialize();
  207. void UpdateParameters(const VoiceInfo::InParams& voice_in, BehaviorInfo& behavior_info);
  208. void UpdateWaveBuffers(const VoiceInfo::InParams& voice_in,
  209. std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT>& voice_states,
  210. BehaviorInfo& behavior_info);
  211. void UpdateWaveBuffer(ServerWaveBuffer& out_wavebuffer, const WaveBuffer& in_wave_buffer,
  212. SampleFormat sample_format, bool is_buffer_valid,
  213. BehaviorInfo& behavior_info);
  214. void WriteOutStatus(VoiceInfo::OutParams& voice_out, VoiceInfo::InParams& voice_in,
  215. std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT>& voice_states);
  216. const InParams& GetInParams() const;
  217. InParams& GetInParams();
  218. const OutParams& GetOutParams() const;
  219. OutParams& GetOutParams();
  220. bool ShouldSkip() const;
  221. bool UpdateForCommandGeneration(VoiceContext& voice_context);
  222. void ResetResources(VoiceContext& voice_context);
  223. bool UpdateParametersForCommandGeneration(
  224. std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT>& dsp_voice_states);
  225. void FlushWaveBuffers(u8 flush_count,
  226. std::array<VoiceState*, AudioCommon::MAX_CHANNEL_COUNT>& dsp_voice_states,
  227. s32 channel_count);
  228. private:
  229. std::vector<s16> stored_samples;
  230. InParams in_params{};
  231. OutParams out_params{};
  232. bool HasValidWaveBuffer(const VoiceState* state) const;
  233. };
  234. class VoiceContext {
  235. public:
  236. VoiceContext(std::size_t voice_count);
  237. ~VoiceContext();
  238. std::size_t GetVoiceCount() const;
  239. ServerVoiceChannelResource& GetChannelResource(std::size_t i);
  240. const ServerVoiceChannelResource& GetChannelResource(std::size_t i) const;
  241. VoiceState& GetState(std::size_t i);
  242. const VoiceState& GetState(std::size_t i) const;
  243. VoiceState& GetDspSharedState(std::size_t i);
  244. const VoiceState& GetDspSharedState(std::size_t i) const;
  245. ServerVoiceInfo& GetInfo(std::size_t i);
  246. const ServerVoiceInfo& GetInfo(std::size_t i) const;
  247. ServerVoiceInfo& GetSortedInfo(std::size_t i);
  248. const ServerVoiceInfo& GetSortedInfo(std::size_t i) const;
  249. s32 DecodePcm16(s32* output_buffer, ServerWaveBuffer* wave_buffer, s32 channel,
  250. s32 channel_count, s32 buffer_offset, s32 sample_count,
  251. Core::Memory::Memory& memory);
  252. void SortInfo();
  253. void UpdateStateByDspShared();
  254. private:
  255. std::size_t voice_count{};
  256. std::vector<ServerVoiceChannelResource> voice_channel_resources{};
  257. std::vector<VoiceState> voice_states{};
  258. std::vector<VoiceState> dsp_voice_states{};
  259. std::vector<ServerVoiceInfo> voice_info{};
  260. std::vector<ServerVoiceInfo*> sorted_voice_info{};
  261. };
  262. } // namespace AudioCore