Browse Source

add rev12 support

pull/2719/head
unknown 5 months ago
parent
commit
0acb3ded9f
  1. 2
      src/audio_core/common/feature_support.h
  2. 4
      src/audio_core/renderer/behavior/behavior_info.cpp
  3. 7
      src/audio_core/renderer/behavior/behavior_info.h
  4. 52
      src/audio_core/renderer/splitter/splitter_context.cpp
  5. 2
      src/audio_core/renderer/splitter/splitter_context.h
  6. 34
      src/audio_core/renderer/splitter/splitter_destinations_data.h

2
src/audio_core/common/feature_support.h

@ -48,6 +48,7 @@ enum class SupportTags {
ReverbChannelMappingChange, ReverbChannelMappingChange,
I3dl2ReverbChannelMappingChange, I3dl2ReverbChannelMappingChange,
SplitterPrevVolumeReset, SplitterPrevVolumeReset,
SplitterBiquadFilterParameter,
SplitterDestinationV2b, SplitterDestinationV2b,
VoiceInParameterV2, VoiceInParameterV2,
@ -94,6 +95,7 @@ constexpr bool CheckFeatureSupported(SupportTags tag, u32 user_revision) {
{SupportTags::DelayChannelMappingChange, 11}, {SupportTags::DelayChannelMappingChange, 11},
{SupportTags::ReverbChannelMappingChange, 11}, {SupportTags::ReverbChannelMappingChange, 11},
{SupportTags::I3dl2ReverbChannelMappingChange, 11}, {SupportTags::I3dl2ReverbChannelMappingChange, 11},
{SupportTags::SplitterBiquadFilterParameter, 12},
{SupportTags::SplitterPrevVolumeReset, 13}, {SupportTags::SplitterPrevVolumeReset, 13},
{SupportTags::SplitterDestinationV2b, 15}, {SupportTags::SplitterDestinationV2b, 15},
{SupportTags::VoiceInParameterV2, 15}, {SupportTags::VoiceInParameterV2, 15},

4
src/audio_core/renderer/behavior/behavior_info.cpp

@ -205,4 +205,8 @@ bool BehaviorInfo::IsVoiceInParameterV2Supported() const {
return CheckFeatureSupported(SupportTags::VoiceInParameterV2, user_revision); return CheckFeatureSupported(SupportTags::VoiceInParameterV2, user_revision);
} }
bool BehaviorInfo::IsBiquadFilterParameterForSplitterEnabled() const {
return CheckFeatureSupported(SupportTags::SplitterBiquadFilterParameter, user_revision);
}
} // namespace AudioCore::Renderer } // namespace AudioCore::Renderer

7
src/audio_core/renderer/behavior/behavior_info.h

@ -389,6 +389,13 @@ public:
*/ */
bool IsVoiceInParameterV2Supported() const; bool IsVoiceInParameterV2Supported() const;
/**
* Check if splitter destinations can carry biquad filter parameters (revision 12+).
*
* @return True if supported, otherwise false.
*/
bool IsBiquadFilterParameterForSplitterEnabled() const;
/// Host version /// Host version
u32 process_revision; u32 process_revision;
/// User version /// User version

52
src/audio_core/renderer/splitter/splitter_context.cpp

@ -43,6 +43,7 @@ void SplitterContext::Setup(std::span<SplitterInfo> splitter_infos_, const u32 s
destinations_count = destination_count_; destinations_count = destination_count_;
splitter_bug_fixed = splitter_bug_fixed_; splitter_bug_fixed = splitter_bug_fixed_;
splitter_prev_volume_reset_supported = behavior.IsSplitterPrevVolumeResetSupported(); splitter_prev_volume_reset_supported = behavior.IsSplitterPrevVolumeResetSupported();
splitter_biquad_param_supported = behavior.IsBiquadFilterParameterForSplitterEnabled();
splitter_float_coeff_supported = behavior.IsSplitterDestinationV2bSupported(); splitter_float_coeff_supported = behavior.IsSplitterDestinationV2bSupported();
} }
@ -140,8 +141,11 @@ u32 SplitterContext::UpdateInfo(const u8* input, u32 offset, const u32 splitter_
u32 SplitterContext::UpdateData(const u8* input, u32 offset, const u32 count) { u32 SplitterContext::UpdateData(const u8* input, u32 offset, const u32 count) {
for (u32 i = 0; i < count; i++) { for (u32 i = 0; i < count; i++) {
// Version selection based on float coeff/biquad v2b support.
if (!splitter_float_coeff_supported) {
// Version selection based on feature flags:
// - REV12: integer biquad params (Version2a)
// - REV15: float coeff/biquad v2b
// - older: no biquad fields
if (!splitter_biquad_param_supported) {
const auto* data_header = const auto* data_header =
reinterpret_cast<const SplitterDestinationData::InParameter*>(input + offset); reinterpret_cast<const SplitterDestinationData::InParameter*>(input + offset);
@ -158,8 +162,50 @@ u32 SplitterContext::UpdateData(const u8* input, u32 offset, const u32 count) {
} }
splitter_destinations[data_header->id].Update(modified_params); splitter_destinations[data_header->id].Update(modified_params);
offset += sizeof(SplitterDestinationData::InParameter); offset += sizeof(SplitterDestinationData::InParameter);
} else if (!splitter_float_coeff_supported) {
// Version 2a: struct contains legacy fixed-point biquad filter fields (REV12+)
const auto* data_header_v2a =
reinterpret_cast<const SplitterDestinationData::InParameterVersion2a*>(input +
offset);
if (data_header_v2a->magic != GetSplitterSendDataMagic()) {
continue;
}
if (data_header_v2a->id < 0 || data_header_v2a->id > destinations_count) {
continue;
}
// Map common fields to the base format
SplitterDestinationData::InParameter mapped{};
mapped.magic = data_header_v2a->magic;
mapped.id = data_header_v2a->id;
mapped.mix_volumes = data_header_v2a->mix_volumes;
mapped.mix_id = data_header_v2a->mix_id;
mapped.in_use = data_header_v2a->in_use;
mapped.reset_prev_volume =
splitter_prev_volume_reset_supported ? data_header_v2a->reset_prev_volume : false;
auto& destination = splitter_destinations[data_header_v2a->id];
destination.Update(mapped);
// Convert legacy fixed-point biquad params into float representation
auto biquad_filters = destination.GetBiquadFilters();
for (size_t filter_idx = 0; filter_idx < MaxBiquadFilters; filter_idx++) {
const auto& legacy = data_header_v2a->biquad_filters[filter_idx];
auto& out = biquad_filters[filter_idx];
out.enabled = legacy.enabled;
// s16 fixed-point scale: use Q14 like voices (b and a are s16, 1.0 ~= 1<<14)
constexpr float scale = 1.0f / static_cast<float>(1 << 14);
out.numerator[0] = static_cast<float>(legacy.b[0]) * scale;
out.numerator[1] = static_cast<float>(legacy.b[1]) * scale;
out.numerator[2] = static_cast<float>(legacy.b[2]) * scale;
out.denominator[0] = static_cast<float>(legacy.a[0]) * scale;
out.denominator[1] = static_cast<float>(legacy.a[1]) * scale;
}
offset += static_cast<u32>(sizeof(SplitterDestinationData::InParameterVersion2a));
} else { } else {
// Version 2b: struct contains extra biquad filter fields
// Version 2b: struct contains extra biquad filter fields with float coeffs
const auto* data_header_v2b = const auto* data_header_v2b =
reinterpret_cast<const SplitterDestinationData::InParameterVersion2b*>(input + reinterpret_cast<const SplitterDestinationData::InParameterVersion2b*>(input +
offset); offset);

2
src/audio_core/renderer/splitter/splitter_context.h

@ -189,6 +189,8 @@ private:
bool splitter_bug_fixed{}; bool splitter_bug_fixed{};
/// Is explicit previous mix volume reset supported? /// Is explicit previous mix volume reset supported?
bool splitter_prev_volume_reset_supported{}; bool splitter_prev_volume_reset_supported{};
/// Is biquad filter parameter for splitter (REV12) supported?
bool splitter_biquad_param_supported{};
/// Is float coefficient/biquad filter v2b parameter supported? /// Is float coefficient/biquad filter v2b parameter supported?
bool splitter_float_coeff_supported{}; bool splitter_float_coeff_supported{};
}; };

34
src/audio_core/renderer/splitter/splitter_destinations_data.h

@ -34,6 +34,18 @@ public:
static_assert(sizeof(BiquadFilterParameter2) == 0x18, static_assert(sizeof(BiquadFilterParameter2) == 0x18,
"BiquadFilterParameter2 has the wrong size!"); "BiquadFilterParameter2 has the wrong size!");
/**
* Legacy biquad filter parameter with fixed-point coefficients (SDK REV12+ for splitters).
* Matches the old voice biquad format.
*/
struct BiquadFilterParameterLegacy {
/* 0x00 */ bool enabled;
/* 0x02 */ std::array<s16, 3> b; // numerator
/* 0x08 */ std::array<s16, 2> a; // denominator (a0 = 1)
};
static_assert(sizeof(BiquadFilterParameterLegacy) == 0xC,
"BiquadFilterParameterLegacy has the wrong size!");
struct InParameter { struct InParameter {
/* 0x00 */ u32 magic; // 'SNDD' /* 0x00 */ u32 magic; // 'SNDD'
/* 0x04 */ s32 id; /* 0x04 */ s32 id;
@ -45,6 +57,20 @@ public:
static_assert(sizeof(InParameter) == 0x70, static_assert(sizeof(InParameter) == 0x70,
"SplitterDestinationData::InParameter has the wrong size!"); "SplitterDestinationData::InParameter has the wrong size!");
struct InParameterVersion2a {
/* 0x00 */ u32 magic; // 'SNDD'
/* 0x04 */ s32 id;
/* 0x08 */ std::array<f32, MaxMixBuffers> mix_volumes;
/* 0x68 */ u32 mix_id;
/* 0x6C */ std::array<SplitterDestinationData::BiquadFilterParameterLegacy, MaxBiquadFilters>
biquad_filters;
/* 0x84 */ bool in_use;
/* 0x85 */ bool reset_prev_volume; // only effective if supported
/* 0x86 */ u8 reserved[10];
};
static_assert(sizeof(InParameterVersion2a) == 0x90,
"SplitterDestinationData::InParameterVersion2a has the wrong size!");
struct InParameterVersion2b { struct InParameterVersion2b {
/* 0x00 */ u32 magic; // 'SNDD' /* 0x00 */ u32 magic; // 'SNDD'
/* 0x04 */ s32 id; /* 0x04 */ s32 id;
@ -111,7 +137,7 @@ public:
f32 GetMixVolumePrev(u32 index) const; f32 GetMixVolumePrev(u32 index) const;
/** /**
* Get the previous mix volumes for all mix buffers in this destination.
* Get the previous mix volumes for all mix buffers.
* *
* @return Span of previous mix buffer volumes. * @return Span of previous mix buffer volumes.
*/ */
@ -149,14 +175,14 @@ public:
void SetNext(SplitterDestinationData* next); void SetNext(SplitterDestinationData* next);
/** /**
* Get biquad filter parameters for this destination (REV15+).
* Get biquad filter parameters for this destination (REV15+ or mapped from REV12).
* *
* @return Span of biquad filter parameters. * @return Span of biquad filter parameters.
*/ */
std::span<BiquadFilterParameter2> GetBiquadFilters(); std::span<BiquadFilterParameter2> GetBiquadFilters();
/** /**
* Get const biquad filter parameters for this destination (REV15+).
* Get const biquad filter parameters for this destination (REV15+ or mapped from REV12).
* *
* @return Const span of biquad filter parameters. * @return Const span of biquad filter parameters.
*/ */
@ -171,7 +197,7 @@ private:
std::array<f32, MaxMixBuffers> mix_volumes{0.0f}; std::array<f32, MaxMixBuffers> mix_volumes{0.0f};
/// Previous mix volumes /// Previous mix volumes
std::array<f32, MaxMixBuffers> prev_mix_volumes{0.0f}; std::array<f32, MaxMixBuffers> prev_mix_volumes{0.0f};
/// Biquad filter parameters (REV15+)
/// Biquad filter parameters (REV15+ or mapped from REV12)
std::array<BiquadFilterParameter2, MaxBiquadFilters> biquad_filters{}; std::array<BiquadFilterParameter2, MaxBiquadFilters> biquad_filters{};
/// Next destination in the mix chain /// Next destination in the mix chain
SplitterDestinationData* next{}; SplitterDestinationData* next{};

Loading…
Cancel
Save