summaryrefslogtreecommitdiffstats
path: root/src/audio_core/renderer/command/command_buffer.h
blob: 12e8c2c8175e0f73a1b04aa9d914efa3c4a7c381 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <span>

#include "audio_core/renderer/command/commands.h"
#include "audio_core/renderer/effect/light_limiter.h"
#include "audio_core/renderer/performance/performance_manager.h"
#include "common/common_types.h"

namespace AudioCore::Renderer {
struct UpsamplerInfo;
struct VoiceState;
class EffectInfoBase;
class ICommandProcessingTimeEstimator;
class MixInfo;
class MemoryPoolInfo;
class SinkInfoBase;
class VoiceInfo;

/**
 * Utility functions to generate and add commands into the current command list.
 */
class CommandBuffer {
public:
    /**
     * Generate a PCM s16 version 1 command, adding it to the command list.
     *
     * @param node_id      - Node id of the voice this command is generated for.
     * @param memory_pool  - Memory pool for translating buffer addresses to the DSP.
     * @param voice_info   - The voice info this command is generated from.
     * @param voice_state  - The voice state the DSP will use for this command.
     * @param buffer_count - Number of mix buffers in use,
     *                       data will be read into this index + channel.
     * @param channel      - Channel index for this command.
     */
    void GeneratePcmInt16Version1Command(s32 node_id, const MemoryPoolInfo& memory_pool,
                                         VoiceInfo& voice_info, const VoiceState& voice_state,
                                         s16 buffer_count, s8 channel);

    /**
     * Generate a PCM s16 version 2 command, adding it to the command list.
     *
     * @param node_id      - Node id of the voice this command is generated for.
     * @param voice_info   - The voice info this command is generated from.
     * @param voice_state  - The voice state the DSP will use for this command.
     * @param buffer_count - Number of mix buffers in use,
     *                       data will be read into this index + channel.
     * @param channel      - Channel index for this command.
     */
    void GeneratePcmInt16Version2Command(s32 node_id, VoiceInfo& voice_info,
                                         const VoiceState& voice_state, s16 buffer_count,
                                         s8 channel);

    /**
     * Generate a PCM f32 version 1 command, adding it to the command list.
     *
     * @param node_id      - Node id of the voice this command is generated for.
     * @param memory_pool  - Memory pool for translating buffer addresses to the DSP.
     * @param voice_info   - The voice info this command is generated from.
     * @param voice_state  - The voice state the DSP will use for this command.
     * @param buffer_count - Number of mix buffers in use,
     *                       data will be read into this index + channel.
     * @param channel      - Channel index for this command.
     */
    void GeneratePcmFloatVersion1Command(s32 node_id, const MemoryPoolInfo& memory_pool,
                                         VoiceInfo& voice_info, const VoiceState& voice_state,
                                         s16 buffer_count, s8 channel);

    /**
     * Generate a PCM f32 version 2 command, adding it to the command list.
     *
     * @param node_id      - Node id of the voice this command is generated for.
     * @param voice_info   - The voice info this command is generated from.
     * @param voice_state  - The voice state the DSP will use for this command.
     * @param buffer_count - Number of mix buffers in use,
     *                       data will be read into this index + channel.
     * @param channel      - Channel index for this command.
     */
    void GeneratePcmFloatVersion2Command(s32 node_id, VoiceInfo& voice_info,
                                         const VoiceState& voice_state, s16 buffer_count,
                                         s8 channel);

    /**
     * Generate an ADPCM version 1 command, adding it to the command list.
     *
     * @param node_id      - Node id of the voice this command is generated for.
     * @param memory_pool  - Memory pool for translating buffer addresses to the DSP.
     * @param voice_info   - The voice info this command is generated from.
     * @param voice_state  - The voice state the DSP will use for this command.
     * @param buffer_count - Number of mix buffers in use,
     *                       data will be read into this index + channel.
     * @param channel      - Channel index for this command.
     */
    void GenerateAdpcmVersion1Command(s32 node_id, const MemoryPoolInfo& memory_pool,
                                      VoiceInfo& voice_info, const VoiceState& voice_state,
                                      s16 buffer_count, s8 channel);

    /**
     * Generate an ADPCM version 2 command, adding it to the command list.
     *
     * @param node_id      - Node id of the voice this command is generated for.
     * @param voice_info   - The voice info this command is generated from.
     * @param voice_state  - The voice state the DSP will use for this command.
     * @param buffer_count - Number of mix buffers in use,
     *                       data will be read into this index + channel.
     * @param channel      - Channel index for this command.
     */
    void GenerateAdpcmVersion2Command(s32 node_id, VoiceInfo& voice_info,
                                      const VoiceState& voice_state, s16 buffer_count, s8 channel);

    /**
     * Generate a volume command, adding it to the command list.
     *
     * @param node_id       - Node id of the voice this command is generated for.
     * @param buffer_offset - Base mix buffer index to generate this command at.
     * @param input_index   - Channel index and mix buffer offset for this command.
     * @param volume        - Mix volume added to the input samples.
     * @param precision     - Number of decimal bits for fixed point operations.
     */
    void GenerateVolumeCommand(s32 node_id, s16 buffer_offset, s16 input_index, f32 volume,
                               u8 precision);

    /**
     * Generate a volume ramp command, adding it to the command list.
     *
     * @param node_id      - Node id of the voice this command is generated for.
     * @param voice_info   - The voice info this command takes its volumes from.
     * @param buffer_count - Number of active mix buffers, command will generate at this index.
     * @param precision    - Number of decimal bits for fixed point operations.
     */
    void GenerateVolumeRampCommand(s32 node_id, VoiceInfo& voice_info, s16 buffer_count,
                                   u8 precision);

    /**
     * Generate a biquad filter command from a voice, adding it to the command list.
     *
     * @param node_id              - Node id of the voice this command is generated for.
     * @param voice_info           - The voice info this command takes biquad parameters from.
     * @param voice_state          - Used by the AudioRenderer to track previous samples.
     * @param buffer_count         - Number of active mix buffers,
     *                               command will generate at this index + channel.
     * @param channel              - Channel index for this filter to work on.
     * @param biquad_index         - Which biquad filter to use for this command (0-1).
     * @param use_float_processing - Should int or float processing be used?
     */
    void GenerateBiquadFilterCommand(s32 node_id, VoiceInfo& voice_info,
                                     const VoiceState& voice_state, s16 buffer_count, s8 channel,
                                     u32 biquad_index, bool use_float_processing);

    /**
     * Generate a biquad filter effect command, adding it to the command list.
     *
     * @param node_id              - Node id of the voice this command is generated for.
     * @param effect_info          - The effect info this command takes biquad parameters from.
     * @param buffer_offset        - Mix buffer offset this command will use,
     *                               command will generate at this index + channel.
     * @param channel              - Channel index for this filter to work on.
     * @param needs_init           - True if the biquad state needs initialisation.
     * @param use_float_processing - Should int or float processing be used?
     */
    void GenerateBiquadFilterCommand(s32 node_id, EffectInfoBase& effect_info, s16 buffer_offset,
                                     s8 channel, bool needs_init, bool use_float_processing);

    /**
     * Generate a mix command, adding it to the command list.
     *
     * @param node_id       - Node id of the voice this command is generated for.
     * @param input_index   - Input mix buffer index for this command.
     *                        Added to the buffer offset.
     * @param output_index  - Output mix buffer index for this command.
     *                        Added to the buffer offset.
     * @param buffer_offset - Mix buffer offset this command will use.
     * @param volume        - Volume to be applied to the input.
     * @param precision     - Number of decimal bits for fixed point operations.
     */
    void GenerateMixCommand(s32 node_id, s16 input_index, s16 output_index, s16 buffer_offset,
                            f32 volume, u8 precision);

    /**
     * Generate a mix ramp command, adding it to the command list.
     *
     * @param node_id      - Node id of the voice this command is generated for.
     * @param buffer_count - Number of active mix buffers.
     * @param input_index  - Input mix buffer index for this command.
     *                       Added to buffer_count.
     * @param output_index - Output mix buffer index for this command.
     *                       Added to buffer_count.
     * @param volume       - Current mix volume used for calculating the ramp.
     * @param prev_volume  - Previous mix volume, used for calculating the ramp,
     *                       also applied to the input.
     * @param prev_samples - Previous sample buffer. Used for depopping.
     * @param precision    - Number of decimal bits for fixed point operations.
     */
    void GenerateMixRampCommand(s32 node_id, s16 buffer_count, s16 input_index, s16 output_index,
                                f32 volume, f32 prev_volume, CpuAddr prev_samples, u8 precision);

    /**
     * Generate a mix ramp grouped command, adding it to the command list.
     *
     * @param node_id      - Node id of the voice this command is generated for.
     * @param buffer_count - Number of active mix buffers.
     * @param input_index  - Input mix buffer index for this command.
     *                       Added to buffer_count.
     * @param output_index - Output mix buffer index for this command.
     *                       Added to buffer_count.
     * @param volumes      - Current mix volumes used for calculating the ramp.
     * @param prev_volumes - Previous mix volumes, used for calculating the ramp,
     *                       also applied to the input.
     * @param prev_samples - Previous sample buffer. Used for depopping.
     * @param precision    - Number of decimal bits for fixed point operations.
     */
    void GenerateMixRampGroupedCommand(s32 node_id, s16 buffer_count, s16 input_index,
                                       s16 output_index, std::span<const f32> volumes,
                                       std::span<const f32> prev_volumes, CpuAddr prev_samples,
                                       u8 precision);

    /**
     * Generate a depop prepare command, adding it to the command list.
     *
     * @param node_id       - Node id of the voice this command is generated for.
     * @param voice_state   - State to track the previous depop samples for each mix buffer.
     * @param buffer        - State to track the current depop samples for each mix buffer.
     * @param buffer_count  - Number of active mix buffers.
     * @param buffer_offset - Base mix buffer index to generate the channel depops at.
     * @param was_playing   - Command only needs to work if the voice was previously playing.
     */
    void GenerateDepopPrepareCommand(s32 node_id, const VoiceState& voice_state,
                                     std::span<const s32> buffer, s16 buffer_count,
                                     s16 buffer_offset, bool was_playing);

    /**
     * Generate a depop command, adding it to the command list.
     *
     * @param node_id      - Node id of the voice this command is generated for.
     * @param mix_info     - Mix info to get the buffer count and base offsets from.
     * @param depop_buffer - Buffer of current depop sample values to be added to the input
     *                       channels.
     */
    void GenerateDepopForMixBuffersCommand(s32 node_id, const MixInfo& mix_info,
                                           std::span<const s32> depop_buffer);

    /**
     * Generate a delay command, adding it to the command list.
     *
     * @param node_id       - Node id of the voice this command is generated for.
     * @param effect_info   - Delay effect info to generate this command from.
     * @param buffer_offset - Base mix buffer offset to apply the apply the delay.
     */
    void GenerateDelayCommand(s32 node_id, EffectInfoBase& effect_info, s16 buffer_offset);

    /**
     * Generate an upsample command, adding it to the command list.
     *
     * @param node_id        - Node id of the voice this command is generated for.
     * @param buffer_offset  - Base mix buffer offset to upsample.
     * @param upsampler_info - Upsampler info to control the upsampling.
     * @param input_count    - Number of input channels to upsample.
     * @param inputs         - Input mix buffer indexes.
     * @param buffer_count   - Number of active mix buffers.
     * @param sample_count   - Source sample count of the input.
     * @param sample_rate    - Source sample rate of the input.
     */
    void GenerateUpsampleCommand(s32 node_id, s16 buffer_offset, UpsamplerInfo& upsampler_info,
                                 u32 input_count, std::span<const s8> inputs, s16 buffer_count,
                                 u32 sample_count, u32 sample_rate);

    /**
     * Generate a downmix 6 -> 2 command, adding it to the command list.
     *
     * @param node_id       - Node id of the voice this command is generated for.
     * @param inputs        - Input mix buffer indexes.
     * @param buffer_offset - Base mix buffer offset of the channels to downmix.
     * @param downmix_coeff - Downmixing coefficients.
     */
    void GenerateDownMix6chTo2chCommand(s32 node_id, std::span<const s8> inputs, s16 buffer_offset,
                                        std::span<const f32> downmix_coeff);

    /**
     * Generate an aux buffer command, adding it to the command list.
     *
     * @param node_id       - Node id of the voice this command is generated for.
     * @param effect_info   - Aux effect info to generate this command from.
     * @param input_index   - Input mix buffer index for this command.
     *                        Added to buffer_offset.
     * @param output_index  - Output mix buffer index for this command.
     *                        Added to buffer_offset.
     * @param buffer_offset - Base mix buffer offset to use.
     * @param update_count  - Number of samples to write back to the game as updated, can be 0.
     * @param count_max     - Maximum number of samples to read or write.
     * @param write_offset  - Current read or write offset within the buffer.
     */
    void GenerateAuxCommand(s32 node_id, EffectInfoBase& effect_info, s16 input_index,
                            s16 output_index, s16 buffer_offset, u32 update_count, u32 count_max,
                            u32 write_offset);

    /**
     * Generate a device sink command, adding it to the command list.
     *
     * @param node_id        - Node id of the voice this command is generated for.
     * @param buffer_offset  - Base mix buffer offset to use.
     * @param sink_info      - The sink_info to generate this command from.
     * @param session_id     - System session id this command is generated from.
     * @param samples_buffer - The buffer to be sent to the sink if upsampling is not used.
     */
    void GenerateDeviceSinkCommand(s32 node_id, s16 buffer_offset, SinkInfoBase& sink_info,
                                   u32 session_id, std::span<s32> samples_buffer);

    /**
     * Generate a circular buffer sink command, adding it to the command list.
     *
     * @param node_id       - Node id of the voice this command is generated for.
     * @param sink_info     - The sink_info to generate this command from.
     * @param buffer_offset - Base mix buffer offset to use.
     */
    void GenerateCircularBufferSinkCommand(s32 node_id, SinkInfoBase& sink_info, s16 buffer_offset);

    /**
     * Generate a reverb command, adding it to the command list.
     *
     * @param node_id                       - Node id of the voice this command is generated for.
     * @param effect_info                   - Reverb effect info to generate this command from.
     * @param buffer_offset                 - Base mix buffer offset to use.
     * @param long_size_pre_delay_supported - Should a longer pre-delay time be used before reverb
     *                                        begins?
     */
    void GenerateReverbCommand(s32 node_id, EffectInfoBase& effect_info, s16 buffer_offset,
                               bool long_size_pre_delay_supported);

    /**
     * Generate an I3DL2 reverb command, adding it to the command list.
     *
     * @param node_id                       - Node id of the voice this command is generated for.
     * @param effect_info                   - I3DL2Reverb effect info to generate this command from.
     * @param buffer_offset                 - Base mix buffer offset to use.
     */
    void GenerateI3dl2ReverbCommand(s32 node_id, EffectInfoBase& effect_info, s16 buffer_offset);

    /**
     * Generate a performance command, adding it to the command list.
     *
     * @param node_id         - Node id of the voice this command is generated for.
     * @param state           - State of the performance.
     * @param entry_addresses - The addresses to be filled in by the AudioRenderer.
     */
    void GeneratePerformanceCommand(s32 node_id, PerformanceState state,
                                    const PerformanceEntryAddresses& entry_addresses);

    /**
     * Generate a clear mix command, adding it to the command list.
     *
     * @param node_id         - Node id of the voice this command is generated for.
     */
    void GenerateClearMixCommand(s32 node_id);

    /**
     * Generate a copy mix command, adding it to the command list.
     *
     * @param node_id       - Node id of the voice this command is generated for.
     * @param effect_info   - BiquadFilter effect info to generate this command from.
     * @param buffer_offset - Base mix buffer offset to use.
     * @param channel       - Index to the effect's parameters input indexes for this command.
     */
    void GenerateCopyMixBufferCommand(s32 node_id, EffectInfoBase& effect_info, s16 buffer_offset,
                                      s8 channel);

    /**
     * Generate a light limiter version 1 command, adding it to the command list.
     *
     * @param node_id       - Node id of the voice this command is generated for.
     * @param buffer_offset - Base mix buffer offset to use.
     * @param parameter     - Effect parameter to generate from.
     * @param state         - State used by the AudioRenderer between commands.
     * @param enabled       - Is this command enabled?
     * @param workbuffer    - Game-supplied memory for the state.
     */
    void GenerateLightLimiterCommand(s32 node_id, s16 buffer_offset,
                                     const LightLimiterInfo::ParameterVersion1& parameter,
                                     const LightLimiterInfo::State& state, bool enabled,
                                     CpuAddr workbuffer);

    /**
     * Generate a light limiter version 2 command, adding it to the command list.
     *
     * @param node_id       - Node id of the voice this command is generated for.
     * @param buffer_offset - Base mix buffer offset to use.
     * @param parameter     - Effect parameter to generate from.
     * @param statistics    - Statistics reported by the AudioRenderer on the limiter's state.
     * @param state         - State used by the AudioRenderer between commands.
     * @param enabled       - Is this command enabled?
     * @param workbuffer    - Game-supplied memory for the state.
     */
    void GenerateLightLimiterCommand(s32 node_id, s16 buffer_offset,
                                     const LightLimiterInfo::ParameterVersion2& parameter,
                                     const LightLimiterInfo::StatisticsInternal& statistics,
                                     const LightLimiterInfo::State& state, bool enabled,
                                     CpuAddr workbuffer);

    /**
     * Generate a multitap biquad filter command, adding it to the command list.
     *
     * @param node_id      - Node id of the voice this command is generated for.
     * @param voice_info   - The voice info this command takes biquad parameters from.
     * @param voice_state  - Used by the AudioRenderer to track previous samples.
     * @param buffer_count - Number of active mix buffers,
     *                       command will generate at this index + channel.
     * @param channel      - Channel index for this filter to work on.
     */
    void GenerateMultitapBiquadFilterCommand(s32 node_id, VoiceInfo& voice_info,
                                             const VoiceState& voice_state, s16 buffer_count,
                                             s8 channel);

    /**
     * Generate a capture command, adding it to the command list.
     *
     * @param node_id       - Node id of the voice this command is generated for.
     * @param effect_info   - Capture effect info to generate this command from.
     * @param input_index   - Input mix buffer index for this command.
     *                        Added to buffer_offset.
     * @param output_index  - Output mix buffer index for this command (unused).
     *                        Added to buffer_offset.
     * @param buffer_offset - Base mix buffer offset to use.
     * @param update_count  - Number of samples to write back to the game as updated, can be 0.
     * @param count_max     - Maximum number of samples to read or write.
     * @param write_offset  - Current read or write offset within the buffer.
     */
    void GenerateCaptureCommand(s32 node_id, EffectInfoBase& effect_info, s16 input_index,
                                s16 output_index, s16 buffer_offset, u32 update_count,
                                u32 count_max, u32 write_offset);

    /**
     * Generate a compressor command, adding it to the command list.
     *
     * @param buffer_offset - Base mix buffer offset to use.
     * @param effect_info   - Capture effect info to generate this command from.
     * @param node_id       - Node id of the voice this command is generated for.
     */
    void GenerateCompressorCommand(s16 buffer_offset, EffectInfoBase& effect_info, s32 node_id);

    /// Command list buffer generated commands will be added to
    std::span<u8> command_list{};
    /// Input sample count, unused
    u32 sample_count{};
    /// Input sample rate, unused
    u32 sample_rate{};
    /// Current size of the command buffer
    u64 size{};
    /// Current number of commands added
    u32 count{};
    /// Current estimated processing time for all commands
    u32 estimated_process_time{};
    /// Used for mapping buffers for the AudioRenderer
    MemoryPoolInfo* memory_pool{};
    /// Used for estimating command process times
    ICommandProcessingTimeEstimator* time_estimator{};
    /// Used to check which rendering features are currently enabled
    BehaviorInfo* behavior{};

private:
    template <typename T, CommandId Id>
    T& GenerateStart(const s32 node_id);
    template <typename T>
    void GenerateEnd(T& cmd);
};

} // namespace AudioCore::Renderer