voice_context.h 9.3 KB

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