summaryrefslogtreecommitdiffstats
path: root/src/audio_core/renderer/behavior/behavior_info.h
blob: a4958857a4f196575bbe589c53d875b341fb4165 (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
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <array>
#include <span>

#include "audio_core/common/common.h"
#include "common/common_types.h"
#include "core/hle/service/audio/errors.h"

namespace AudioCore::Renderer {
/**
 * Holds host and user revisions, checks whether render features can be enabled, and reports errors.
 */
class BehaviorInfo {
    static constexpr u32 MaxErrors = 10;

public:
    struct ErrorInfo {
        /* 0x00 */ Result error_code{0};
        /* 0x04 */ u32 unk_04;
        /* 0x08 */ CpuAddr address;
    };
    static_assert(sizeof(ErrorInfo) == 0x10, "BehaviorInfo::ErrorInfo has the wrong size!");

    struct Flags {
        u64 IsMemoryForceMappingEnabled : 1;
    };

    struct InParameter {
        /* 0x00 */ u32 revision;
        /* 0x08 */ Flags flags;
    };
    static_assert(sizeof(InParameter) == 0x10, "BehaviorInfo::InParameter has the wrong size!");

    struct OutStatus {
        /* 0x00 */ std::array<ErrorInfo, MaxErrors> errors;
        /* 0xA0 */ u32 error_count;
        /* 0xA4 */ char unkA4[0xC];
    };
    static_assert(sizeof(OutStatus) == 0xB0, "BehaviorInfo::OutStatus has the wrong size!");

    BehaviorInfo();

    /**
     * Get the host revision as a number.
     *
     * @return The host revision.
     */
    u32 GetProcessRevisionNum() const;

    /**
     * Get the host revision in chars, e.g REV8.
     * Rev 10 and higher use the ascii characters above 9.
     * E.g:
     *     Rev 10 = REV:
     *     Rev 11 = REV;
     *
     * @return The host revision.
     */
    u32 GetProcessRevision() const;

    /**
     * Get the user revision as a number.
     *
     * @return The user revision.
     */
    u32 GetUserRevisionNum() const;

    /**
     * Get the user revision in chars, e.g REV8.
     * Rev 10 and higher use the ascii characters above 9. REV: REV; etc.
     *
     * @return The user revision.
     */
    u32 GetUserRevision() const;

    /**
     * Set the user revision.
     *
     * @param user_revision - The user's revision.
     */
    void SetUserLibRevision(u32 user_revision);

    /**
     * Clear the current error count.
     */
    void ClearError();

    /**
     * Append an error to the error list.
     *
     * @param error - The new error.
     */
    void AppendError(const ErrorInfo& error);

    /**
     * Copy errors to the given output container.
     *
     * @param out_errors - Output container to receive the errors.
     * @param out_count  - The number of errors written.
     */
    void CopyErrorInfo(std::span<ErrorInfo> out_errors, u32& out_count) const;

    /**
     * Update the behaviour flags.
     *
     * @param flags - New flags to use.
     */
    void UpdateFlags(Flags flags);

    /**
     * Check if memory pools can be forcibly mapped.
     *
     * @return True if enabled, otherwise false.
     */
    bool IsMemoryForceMappingEnabled() const;

    /**
     * Check if the ADPCM context bug is fixed.
     * The ADPCM context was not being sent to the AudioRenderer, leading to incorrect scaling being
     * used.
     *
     * @return True if fixed, otherwise false.
     */
    bool IsAdpcmLoopContextBugFixed() const;

    /**
     * Check if the splitter is supported.
     *
     * @return True if supported, otherwise false.
     */
    bool IsSplitterSupported() const;

    /**
     * Check if the splitter bug is fixed.
     * Update is given the wrong number of splitter destinations, leading to invalid data
     * being processed.
     *
     * @return True if supported, otherwise false.
     */
    bool IsSplitterBugFixed() const;

    /**
     * Check if effects version 2 are supported.
     * This gives support for returning effect states from the AudioRenderer, currently only used
     * for Limiter statistics.
     *
     * @return True if supported, otherwise false.
     */
    bool IsEffectInfoVersion2Supported() const;

    /**
     * Check if a variadic command buffer is supported.
     * As of Rev 5 with the added optional performance metric logging, the command
     * buffer can be a variable size, so take that into account for calculating its size.
     *
     * @return True if supported, otherwise false.
     */
    bool IsVariadicCommandBufferSizeSupported() const;

    /**
     * Check if wave buffers version 2 are supported.
     * See WaveBufferVersion1 and WaveBufferVersion2.
     *
     * @return True if supported, otherwise false.
     */
    bool IsWaveBufferVer2Supported() const;

    /**
     * Check if long size pre delay is supported.
     * This allows a longer initial delay time for the Reverb command.
     *
     * @return True if supported, otherwise false.
     */
    bool IsLongSizePreDelaySupported() const;

    /**
     * Check if the command time estimator version 2 is supported.
     *
     * @return True if supported, otherwise false.
     */
    bool IsCommandProcessingTimeEstimatorVersion2Supported() const;

    /**
     * Check if the command time estimator version 3 is supported.
     *
     * @return True if supported, otherwise false.
     */
    bool IsCommandProcessingTimeEstimatorVersion3Supported() const;

    /**
     * Check if the command time estimator version 4 is supported.
     *
     * @return True if supported, otherwise false.
     */
    bool IsCommandProcessingTimeEstimatorVersion4Supported() const;

    /**
     * Check if the command time estimator version 5 is supported.
     *
     * @return True if supported, otherwise false.
     */
    bool IsCommandProcessingTimeEstimatorVersion5Supported() const;

    /**
     * Check if the AudioRenderer can use up to 70% of the allocated processing timeslice.
     *
     * @return True if supported, otherwise false.
     */
    bool IsAudioRendererProcessingTimeLimit70PercentSupported() const;

    /**
     * Check if the AudioRenderer can use up to 75% of the allocated processing timeslice.
     *
     * @return True if supported, otherwise false.
     */
    bool IsAudioRendererProcessingTimeLimit75PercentSupported() const;

    /**
     * Check if the AudioRenderer can use up to 80% of the allocated processing timeslice.
     *
     * @return True if supported, otherwise false.
     */
    bool IsAudioRendererProcessingTimeLimit80PercentSupported() const;

    /**
     * Check if voice flushing is supported
     * This allowws low-priority voices to be dropped if the AudioRenderer is running behind.
     *
     * @return True if supported, otherwise false.
     */
    bool IsFlushVoiceWaveBuffersSupported() const;

    /**
     * Check if counting the number of elapsed frames is supported.
     * This adds extra output to RequestUpdate, returning the number of times the AudioRenderer
     * processed a command list.
     *
     * @return True if supported, otherwise false.
     */
    bool IsElapsedFrameCountSupported() const;

    /**
     * Check if performance metrics version 2 are supported.
     * This adds extra output to RequestUpdate, returning the number of times the AudioRenderer
     * (Unused?).
     *
     * @return True if supported, otherwise false.
     */
    bool IsPerformanceMetricsDataFormatVersion2Supported() const;

    /**
     * Get the supported performance metrics version.
     * Version 2 logs some extra fields in output, such as number of voices dropped,
     * processing start time, if the AudioRenderer exceeded its time, etc.
     *
     * @return Version supported, either 1 or 2.
     */
    size_t GetPerformanceMetricsDataFormat() const;

    /**
     * Check if skipping voice pitch and sample rate conversion is supported.
     * This speeds up the data source commands by skipping resampling if unwanted.
     * See AudioCore::Renderer::DecodeFromWaveBuffers
     *
     * @return True if supported, otherwise false.
     */
    bool IsVoicePitchAndSrcSkippedSupported() const;

    /**
     * Check if resetting played sample count at loop points is supported.
     * This resets the number of samples played in a voice state when a loop point is reached.
     * See AudioCore::Renderer::DecodeFromWaveBuffers
     *
     * @return True if supported, otherwise false.
     */
    bool IsVoicePlayedSampleCountResetAtLoopPointSupported() const;

    /**
     * Check if the clear state bug for biquad filters is fixed.
     * The biquad state was not marked as needing re-initialisation when the effect was updated, it
     * was only initialized once with a new effect.
     *
     * @return True if fixed, otherwise false.
     */
    bool IsBiquadFilterEffectStateClearBugFixed() const;

    /**
     * Check if Q23 precision is supported for fixed point.
     *
     * @return True if supported, otherwise false.
     */
    bool IsVolumeMixParameterPrecisionQ23Supported() const;

    /**
     * Check if float processing for biuad filters is supported.
     *
     * @return True if supported, otherwise false.
     */
    bool UseBiquadFilterFloatProcessing() const;

    /**
     * Check if dirty-only mix updates are supported.
     * This saves a lot of buffer size as mixes can be large and not change much.
     *
     * @return True if supported, otherwise false.
     */
    bool IsMixInParameterDirtyOnlyUpdateSupported() const;

    /**
     * Check if multi-tap biquad filters are supported.
     *
     * @return True if supported, otherwise false.
     */
    bool UseMultiTapBiquadFilterProcessing() const;

    /**
     * Check if device api version 2 is supported.
     * In the SDK but not in any sysmodule? Not sure, left here for completeness anyway.
     *
     * @return True if supported, otherwise false.
     */
    bool IsDeviceApiVersion2Supported() const;

    /**
     * Check if new channel mappings are used for Delay commands.
     * Older commands used:
     *   front left/front right/back left/back right/center/lfe
     * Whereas everywhere else in the code uses:
     *   front left/front right/center/lfe/back left/back right
     * This corrects that and makes everything standardised.
     *
     * @return True if supported, otherwise false.
     */
    bool IsDelayChannelMappingChanged() const;

    /**
     * Check if new channel mappings are used for Reverb commands.
     * Older commands used:
     *   front left/front right/back left/back right/center/lfe
     * Whereas everywhere else in the code uses:
     *   front left/front right/center/lfe/back left/back right
     * This corrects that and makes everything standardised.
     *
     * @return True if supported, otherwise false.
     */
    bool IsReverbChannelMappingChanged() const;

    /**
     * Check if new channel mappings are used for I3dl2Reverb commands.
     * Older commands used:
     *   front left/front right/back left/back right/center/lfe
     * Whereas everywhere else in the code uses:
     *   front left/front right/center/lfe/back left/back right
     * This corrects that and makes everything standardised.
     *
     * @return True if supported, otherwise false.
     */
    bool IsI3dl2ReverbChannelMappingChanged() const;

    /// Host version
    u32 process_revision;
    /// User version
    u32 user_revision{};
    /// Behaviour flags
    Flags flags{};
    /// Errors generated and reported during Update
    std::array<ErrorInfo, MaxErrors> errors{};
    /// Error count
    u32 error_count{};
};

} // namespace AudioCore::Renderer