command_buffer.h 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <span>
  5. #include "audio_core/renderer/command/commands.h"
  6. #include "audio_core/renderer/effect/light_limiter.h"
  7. #include "audio_core/renderer/performance/performance_manager.h"
  8. #include "common/common_types.h"
  9. namespace AudioCore::AudioRenderer {
  10. struct UpsamplerInfo;
  11. struct VoiceState;
  12. class EffectInfoBase;
  13. class ICommandProcessingTimeEstimator;
  14. class MixInfo;
  15. class MemoryPoolInfo;
  16. class SinkInfoBase;
  17. class VoiceInfo;
  18. /**
  19. * Utility functions to generate and add commands into the current command list.
  20. */
  21. class CommandBuffer {
  22. public:
  23. /**
  24. * Generate a PCM s16 version 1 command, adding it to the command list.
  25. *
  26. * @param node_id - Node id of the voice this command is generated for.
  27. * @param memory_pool - Memory pool for translating buffer addresses to the DSP.
  28. * @param voice_info - The voice info this command is generated from.
  29. * @param voice_state - The voice state the DSP will use for this command.
  30. * @param buffer_count - Number of mix buffers in use,
  31. * data will be read into this index + channel.
  32. * @param channel - Channel index for this command.
  33. */
  34. void GeneratePcmInt16Version1Command(s32 node_id, const MemoryPoolInfo& memory_pool,
  35. VoiceInfo& voice_info, const VoiceState& voice_state,
  36. s16 buffer_count, s8 channel);
  37. /**
  38. * Generate a PCM s16 version 2 command, adding it to the command list.
  39. *
  40. * @param node_id - Node id of the voice this command is generated for.
  41. * @param voice_info - The voice info this command is generated from.
  42. * @param voice_state - The voice state the DSP will use for this command.
  43. * @param buffer_count - Number of mix buffers in use,
  44. * data will be read into this index + channel.
  45. * @param channel - Channel index for this command.
  46. */
  47. void GeneratePcmInt16Version2Command(s32 node_id, VoiceInfo& voice_info,
  48. const VoiceState& voice_state, s16 buffer_count,
  49. s8 channel);
  50. /**
  51. * Generate a PCM f32 version 1 command, adding it to the command list.
  52. *
  53. * @param node_id - Node id of the voice this command is generated for.
  54. * @param memory_pool - Memory pool for translating buffer addresses to the DSP.
  55. * @param voice_info - The voice info this command is generated from.
  56. * @param voice_state - The voice state the DSP will use for this command.
  57. * @param buffer_count - Number of mix buffers in use,
  58. * data will be read into this index + channel.
  59. * @param channel - Channel index for this command.
  60. */
  61. void GeneratePcmFloatVersion1Command(s32 node_id, const MemoryPoolInfo& memory_pool,
  62. VoiceInfo& voice_info, const VoiceState& voice_state,
  63. s16 buffer_count, s8 channel);
  64. /**
  65. * Generate a PCM f32 version 2 command, adding it to the command list.
  66. *
  67. * @param node_id - Node id of the voice this command is generated for.
  68. * @param voice_info - The voice info this command is generated from.
  69. * @param voice_state - The voice state the DSP will use for this command.
  70. * @param buffer_count - Number of mix buffers in use,
  71. * data will be read into this index + channel.
  72. * @param channel - Channel index for this command.
  73. */
  74. void GeneratePcmFloatVersion2Command(s32 node_id, VoiceInfo& voice_info,
  75. const VoiceState& voice_state, s16 buffer_count,
  76. s8 channel);
  77. /**
  78. * Generate an ADPCM version 1 command, adding it to the command list.
  79. *
  80. * @param node_id - Node id of the voice this command is generated for.
  81. * @param memory_pool - Memory pool for translating buffer addresses to the DSP.
  82. * @param voice_info - The voice info this command is generated from.
  83. * @param voice_state - The voice state the DSP will use for this command.
  84. * @param buffer_count - Number of mix buffers in use,
  85. * data will be read into this index + channel.
  86. * @param channel - Channel index for this command.
  87. */
  88. void GenerateAdpcmVersion1Command(s32 node_id, const MemoryPoolInfo& memory_pool,
  89. VoiceInfo& voice_info, const VoiceState& voice_state,
  90. s16 buffer_count, s8 channel);
  91. /**
  92. * Generate an ADPCM version 2 command, adding it to the command list.
  93. *
  94. * @param node_id - Node id of the voice this command is generated for.
  95. * @param voice_info - The voice info this command is generated from.
  96. * @param voice_state - The voice state the DSP will use for this command.
  97. * @param buffer_count - Number of mix buffers in use,
  98. * data will be read into this index + channel.
  99. * @param channel - Channel index for this command.
  100. */
  101. void GenerateAdpcmVersion2Command(s32 node_id, VoiceInfo& voice_info,
  102. const VoiceState& voice_state, s16 buffer_count, s8 channel);
  103. /**
  104. * Generate a volume command, adding it to the command list.
  105. *
  106. * @param node_id - Node id of the voice this command is generated for.
  107. * @param buffer_offset - Base mix buffer index to generate this command at.
  108. * @param input_index - Channel index and mix buffer offset for this command.
  109. * @param volume - Mix volume added to the input samples.
  110. * @param precision - Number of decimal bits for fixed point operations.
  111. */
  112. void GenerateVolumeCommand(s32 node_id, s16 buffer_offset, s16 input_index, f32 volume,
  113. u8 precision);
  114. /**
  115. * Generate a volume ramp command, adding it to the command list.
  116. *
  117. * @param node_id - Node id of the voice this command is generated for.
  118. * @param voice_info - The voice info this command takes its volumes from.
  119. * @param buffer_count - Number of active mix buffers, command will generate at this index.
  120. * @param precision - Number of decimal bits for fixed point operations.
  121. */
  122. void GenerateVolumeRampCommand(s32 node_id, VoiceInfo& voice_info, s16 buffer_count,
  123. u8 precision);
  124. /**
  125. * Generate a biquad filter command from a voice, adding it to the command list.
  126. *
  127. * @param node_id - Node id of the voice this command is generated for.
  128. * @param voice_info - The voice info this command takes biquad parameters from.
  129. * @param voice_state - Used by the AudioRenderer to track previous samples.
  130. * @param buffer_count - Number of active mix buffers,
  131. * command will generate at this index + channel.
  132. * @param channel - Channel index for this filter to work on.
  133. * @param biquad_index - Which biquad filter to use for this command (0-1).
  134. * @param use_float_processing - Should int or float processing be used?
  135. */
  136. void GenerateBiquadFilterCommand(s32 node_id, VoiceInfo& voice_info,
  137. const VoiceState& voice_state, s16 buffer_count, s8 channel,
  138. u32 biquad_index, bool use_float_processing);
  139. /**
  140. * Generate a biquad filter effect command, adding it to the command list.
  141. *
  142. * @param node_id - Node id of the voice this command is generated for.
  143. * @param effect_info - The effect info this command takes biquad parameters from.
  144. * @param buffer_offset - Mix buffer offset this command will use,
  145. * command will generate at this index + channel.
  146. * @param channel - Channel index for this filter to work on.
  147. * @param needs_init - True if the biquad state needs initialisation.
  148. * @param use_float_processing - Should int or float processing be used?
  149. */
  150. void GenerateBiquadFilterCommand(s32 node_id, EffectInfoBase& effect_info, s16 buffer_offset,
  151. s8 channel, bool needs_init, bool use_float_processing);
  152. /**
  153. * Generate a mix command, adding it to the command list.
  154. *
  155. * @param node_id - Node id of the voice this command is generated for.
  156. * @param input_index - Input mix buffer index for this command.
  157. * Added to the buffer offset.
  158. * @param output_index - Output mix buffer index for this command.
  159. * Added to the buffer offset.
  160. * @param buffer_offset - Mix buffer offset this command will use.
  161. * @param volume - Volume to be applied to the input.
  162. * @param precision - Number of decimal bits for fixed point operations.
  163. */
  164. void GenerateMixCommand(s32 node_id, s16 input_index, s16 output_index, s16 buffer_offset,
  165. f32 volume, u8 precision);
  166. /**
  167. * Generate a mix ramp command, adding it to the command list.
  168. *
  169. * @param node_id - Node id of the voice this command is generated for.
  170. * @param buffer_count - Number of active mix buffers.
  171. * @param input_index - Input mix buffer index for this command.
  172. * Added to buffer_count.
  173. * @param output_index - Output mix buffer index for this command.
  174. * Added to buffer_count.
  175. * @param volume - Current mix volume used for calculating the ramp.
  176. * @param prev_volume - Previous mix volume, used for calculating the ramp,
  177. * also applied to the input.
  178. * @param prev_samples - Previous sample buffer. Used for depopping.
  179. * @param precision - Number of decimal bits for fixed point operations.
  180. */
  181. void GenerateMixRampCommand(s32 node_id, s16 buffer_count, s16 input_index, s16 output_index,
  182. f32 volume, f32 prev_volume, CpuAddr prev_samples, u8 precision);
  183. /**
  184. * Generate a mix ramp grouped command, adding it to the command list.
  185. *
  186. * @param node_id - Node id of the voice this command is generated for.
  187. * @param buffer_count - Number of active mix buffers.
  188. * @param input_index - Input mix buffer index for this command.
  189. * Added to buffer_count.
  190. * @param output_index - Output mix buffer index for this command.
  191. * Added to buffer_count.
  192. * @param volumes - Current mix volumes used for calculating the ramp.
  193. * @param prev_volumes - Previous mix volumes, used for calculating the ramp,
  194. * also applied to the input.
  195. * @param prev_samples - Previous sample buffer. Used for depopping.
  196. * @param precision - Number of decimal bits for fixed point operations.
  197. */
  198. void GenerateMixRampGroupedCommand(s32 node_id, s16 buffer_count, s16 input_index,
  199. s16 output_index, std::span<const f32> volumes,
  200. std::span<const f32> prev_volumes, CpuAddr prev_samples,
  201. u8 precision);
  202. /**
  203. * Generate a depop prepare command, adding it to the command list.
  204. *
  205. * @param node_id - Node id of the voice this command is generated for.
  206. * @param voice_state - State to track the previous depop samples for each mix buffer.
  207. * @param buffer - State to track the current depop samples for each mix buffer.
  208. * @param buffer_count - Number of active mix buffers.
  209. * @param buffer_offset - Base mix buffer index to generate the channel depops at.
  210. * @param was_playing - Command only needs to work if the voice was previously playing.
  211. */
  212. void GenerateDepopPrepareCommand(s32 node_id, const VoiceState& voice_state,
  213. std::span<const s32> buffer, s16 buffer_count,
  214. s16 buffer_offset, bool was_playing);
  215. /**
  216. * Generate a depop command, adding it to the command list.
  217. *
  218. * @param node_id - Node id of the voice this command is generated for.
  219. * @param mix_info - Mix info to get the buffer count and base offsets from.
  220. * @param depop_buffer - Buffer of current depop sample values to be added to the input
  221. * channels.
  222. */
  223. void GenerateDepopForMixBuffersCommand(s32 node_id, const MixInfo& mix_info,
  224. std::span<const s32> depop_buffer);
  225. /**
  226. * Generate a delay command, adding it to the command list.
  227. *
  228. * @param node_id - Node id of the voice this command is generated for.
  229. * @param effect_info - Delay effect info to generate this command from.
  230. * @param buffer_offset - Base mix buffer offset to apply the apply the delay.
  231. */
  232. void GenerateDelayCommand(s32 node_id, EffectInfoBase& effect_info, s16 buffer_offset);
  233. /**
  234. * Generate an upsample command, adding it to the command list.
  235. *
  236. * @param node_id - Node id of the voice this command is generated for.
  237. * @param buffer_offset - Base mix buffer offset to upsample.
  238. * @param upsampler_info - Upsampler info to control the upsampling.
  239. * @param input_count - Number of input channels to upsample.
  240. * @param inputs - Input mix buffer indexes.
  241. * @param buffer_count - Number of active mix buffers.
  242. * @param sample_count - Source sample count of the input.
  243. * @param sample_rate - Source sample rate of the input.
  244. */
  245. void GenerateUpsampleCommand(s32 node_id, s16 buffer_offset, UpsamplerInfo& upsampler_info,
  246. u32 input_count, std::span<const s8> inputs, s16 buffer_count,
  247. u32 sample_count, u32 sample_rate);
  248. /**
  249. * Generate a downmix 6 -> 2 command, adding it to the command list.
  250. *
  251. * @param node_id - Node id of the voice this command is generated for.
  252. * @param inputs - Input mix buffer indexes.
  253. * @param buffer_offset - Base mix buffer offset of the channels to downmix.
  254. * @param downmix_coeff - Downmixing coefficients.
  255. */
  256. void GenerateDownMix6chTo2chCommand(s32 node_id, std::span<const s8> inputs, s16 buffer_offset,
  257. std::span<const f32> downmix_coeff);
  258. /**
  259. * Generate an aux buffer command, adding it to the command list.
  260. *
  261. * @param node_id - Node id of the voice this command is generated for.
  262. * @param effect_info - Aux effect info to generate this command from.
  263. * @param input_index - Input mix buffer index for this command.
  264. * Added to buffer_offset.
  265. * @param output_index - Output mix buffer index for this command.
  266. * Added to buffer_offset.
  267. * @param buffer_offset - Base mix buffer offset to use.
  268. * @param update_count - Number of samples to write back to the game as updated, can be 0.
  269. * @param count_max - Maximum number of samples to read or write.
  270. * @param write_offset - Current read or write offset within the buffer.
  271. */
  272. void GenerateAuxCommand(s32 node_id, EffectInfoBase& effect_info, s16 input_index,
  273. s16 output_index, s16 buffer_offset, u32 update_count, u32 count_max,
  274. u32 write_offset);
  275. /**
  276. * Generate a device sink command, adding it to the command list.
  277. *
  278. * @param node_id - Node id of the voice this command is generated for.
  279. * @param buffer_offset - Base mix buffer offset to use.
  280. * @param sink_info - The sink_info to generate this command from.
  281. * @param session_id - System session id this command is generated from.
  282. * @param samples_buffer - The buffer to be sent to the sink if upsampling is not used.
  283. */
  284. void GenerateDeviceSinkCommand(s32 node_id, s16 buffer_offset, SinkInfoBase& sink_info,
  285. u32 session_id, std::span<s32> samples_buffer);
  286. /**
  287. * Generate a circular buffer sink command, adding it to the command list.
  288. *
  289. * @param node_id - Node id of the voice this command is generated for.
  290. * @param sink_info - The sink_info to generate this command from.
  291. * @param buffer_offset - Base mix buffer offset to use.
  292. */
  293. void GenerateCircularBufferSinkCommand(s32 node_id, SinkInfoBase& sink_info, s16 buffer_offset);
  294. /**
  295. * Generate a reverb command, adding it to the command list.
  296. *
  297. * @param node_id - Node id of the voice this command is generated for.
  298. * @param effect_info - Reverb effect info to generate this command from.
  299. * @param buffer_offset - Base mix buffer offset to use.
  300. * @param long_size_pre_delay_supported - Should a longer pre-delay time be used before reverb
  301. * begins?
  302. */
  303. void GenerateReverbCommand(s32 node_id, EffectInfoBase& effect_info, s16 buffer_offset,
  304. bool long_size_pre_delay_supported);
  305. /**
  306. * Generate an I3DL2 reverb command, adding it to the command list.
  307. *
  308. * @param node_id - Node id of the voice this command is generated for.
  309. * @param effect_info - I3DL2Reverb effect info to generate this command from.
  310. * @param buffer_offset - Base mix buffer offset to use.
  311. */
  312. void GenerateI3dl2ReverbCommand(s32 node_id, EffectInfoBase& effect_info, s16 buffer_offset);
  313. /**
  314. * Generate a performance command, adding it to the command list.
  315. *
  316. * @param node_id - Node id of the voice this command is generated for.
  317. * @param state - State of the performance.
  318. * @param entry_addresses - The addresses to be filled in by the AudioRenderer.
  319. */
  320. void GeneratePerformanceCommand(s32 node_id, PerformanceState state,
  321. const PerformanceEntryAddresses& entry_addresses);
  322. /**
  323. * Generate a clear mix command, adding it to the command list.
  324. *
  325. * @param node_id - Node id of the voice this command is generated for.
  326. */
  327. void GenerateClearMixCommand(s32 node_id);
  328. /**
  329. * Generate a copy mix command, adding it to the command list.
  330. *
  331. * @param node_id - Node id of the voice this command is generated for.
  332. * @param effect_info - BiquadFilter effect info to generate this command from.
  333. * @param buffer_offset - Base mix buffer offset to use.
  334. * @param channel - Index to the effect's parameters input indexes for this command.
  335. */
  336. void GenerateCopyMixBufferCommand(s32 node_id, EffectInfoBase& effect_info, s16 buffer_offset,
  337. s8 channel);
  338. /**
  339. * Generate a light limiter version 1 command, adding it to the command list.
  340. *
  341. * @param node_id - Node id of the voice this command is generated for.
  342. * @param buffer_offset - Base mix buffer offset to use.
  343. * @param parameter - Effect parameter to generate from.
  344. * @param state - State used by the AudioRenderer between commands.
  345. * @param enabled - Is this command enabled?
  346. * @param workbuffer - Game-supplied memory for the state.
  347. */
  348. void GenerateLightLimiterCommand(s32 node_id, s16 buffer_offset,
  349. const LightLimiterInfo::ParameterVersion1& parameter,
  350. const LightLimiterInfo::State& state, bool enabled,
  351. CpuAddr workbuffer);
  352. /**
  353. * Generate a light limiter version 2 command, adding it to the command list.
  354. *
  355. * @param node_id - Node id of the voice this command is generated for.
  356. * @param buffer_offset - Base mix buffer offset to use.
  357. * @param parameter - Effect parameter to generate from.
  358. * @param statistics - Statistics reported by the AudioRenderer on the limiter's state.
  359. * @param state - State used by the AudioRenderer between commands.
  360. * @param enabled - Is this command enabled?
  361. * @param workbuffer - Game-supplied memory for the state.
  362. */
  363. void GenerateLightLimiterCommand(s32 node_id, s16 buffer_offset,
  364. const LightLimiterInfo::ParameterVersion2& parameter,
  365. const LightLimiterInfo::StatisticsInternal& statistics,
  366. const LightLimiterInfo::State& state, bool enabled,
  367. CpuAddr workbuffer);
  368. /**
  369. * Generate a multitap biquad filter command, adding it to the command list.
  370. *
  371. * @param node_id - Node id of the voice this command is generated for.
  372. * @param voice_info - The voice info this command takes biquad parameters from.
  373. * @param voice_state - Used by the AudioRenderer to track previous samples.
  374. * @param buffer_count - Number of active mix buffers,
  375. * command will generate at this index + channel.
  376. * @param channel - Channel index for this filter to work on.
  377. */
  378. void GenerateMultitapBiquadFilterCommand(s32 node_id, VoiceInfo& voice_info,
  379. const VoiceState& voice_state, s16 buffer_count,
  380. s8 channel);
  381. /**
  382. * Generate a capture command, adding it to the command list.
  383. *
  384. * @param node_id - Node id of the voice this command is generated for.
  385. * @param effect_info - Capture effect info to generate this command from.
  386. * @param input_index - Input mix buffer index for this command.
  387. * Added to buffer_offset.
  388. * @param output_index - Output mix buffer index for this command (unused).
  389. * Added to buffer_offset.
  390. * @param buffer_offset - Base mix buffer offset to use.
  391. * @param update_count - Number of samples to write back to the game as updated, can be 0.
  392. * @param count_max - Maximum number of samples to read or write.
  393. * @param write_offset - Current read or write offset within the buffer.
  394. */
  395. void GenerateCaptureCommand(s32 node_id, EffectInfoBase& effect_info, s16 input_index,
  396. s16 output_index, s16 buffer_offset, u32 update_count,
  397. u32 count_max, u32 write_offset);
  398. /**
  399. * Generate a compressor command, adding it to the command list.
  400. *
  401. * @param buffer_offset - Base mix buffer offset to use.
  402. * @param effect_info - Capture effect info to generate this command from.
  403. * @param node_id - Node id of the voice this command is generated for.
  404. */
  405. void GenerateCompressorCommand(s16 buffer_offset, EffectInfoBase& effect_info, s32 node_id);
  406. /// Command list buffer generated commands will be added to
  407. std::span<u8> command_list{};
  408. /// Input sample count, unused
  409. u32 sample_count{};
  410. /// Input sample rate, unused
  411. u32 sample_rate{};
  412. /// Current size of the command buffer
  413. u64 size{};
  414. /// Current number of commands added
  415. u32 count{};
  416. /// Current estimated processing time for all commands
  417. u32 estimated_process_time{};
  418. /// Used for mapping buffers for the AudioRenderer
  419. MemoryPoolInfo* memory_pool{};
  420. /// Used for estimating command process times
  421. ICommandProcessingTimeEstimator* time_estimator{};
  422. /// Used to check which rendering features are currently enabled
  423. BehaviorInfo* behavior{};
  424. private:
  425. template <typename T, CommandId Id>
  426. T& GenerateStart(const s32 node_id);
  427. template <typename T>
  428. void GenerateEnd(T& cmd);
  429. };
  430. } // namespace AudioCore::AudioRenderer