@ -21,6 +21,15 @@
namespace AudioCore : : Renderer {
namespace AudioCore : : Renderer {
namespace {
constexpr f32 BiquadParameterFixedScaleQ14 = 16384.0f ; // 1 << 14
[[nodiscard]] inline s16 ToQ14Clamped ( f32 v ) {
const f32 scaled = std : : clamp ( v * BiquadParameterFixedScaleQ14 , - 32768.0f , 32767.0f ) ;
return static_cast < s16 > ( scaled ) ;
}
} // namespace
template < typename T , CommandId Id >
template < typename T , CommandId Id >
T & CommandBuffer : : GenerateStart ( const s32 node_id ) {
T & CommandBuffer : : GenerateStart ( const s32 node_id ) {
if ( size + sizeof ( T ) > = command_list . size_bytes ( ) ) {
if ( size + sizeof ( T ) > = command_list . size_bytes ( ) ) {
@ -259,18 +268,42 @@ void CommandBuffer::GenerateBiquadFilterCommand(const s32 node_id, EffectInfoBas
const bool use_float_processing ) {
const bool use_float_processing ) {
auto & cmd { GenerateStart < BiquadFilterCommand , CommandId : : BiquadFilter > ( node_id ) } ;
auto & cmd { GenerateStart < BiquadFilterCommand , CommandId : : BiquadFilter > ( node_id ) } ;
const auto & parameter {
* reinterpret_cast < BiquadFilterInfo : : ParameterVersion1 * > ( effect_info . GetParameter ( ) ) } ;
const auto state { reinterpret_cast < VoiceState : : BiquadFilterState * > (
const auto state { reinterpret_cast < VoiceState : : BiquadFilterState * > (
effect_info . GetStateBuffer ( ) + channel * sizeof ( VoiceState : : BiquadFilterState ) ) } ;
effect_info . GetStateBuffer ( ) + channel * sizeof ( VoiceState : : BiquadFilterState ) ) } ;
cmd . input = buffer_offset + parameter . inputs [ channel ] ;
cmd . output = buffer_offset + parameter . outputs [ channel ] ;
if ( behavior - > IsEffectInfoVersion2Supported ( ) ) {
const auto & p {
* reinterpret_cast < BiquadFilterInfo : : ParameterVersion2 * > ( effect_info . GetParameter ( ) ) } ;
cmd . biquad . b = parameter . b ;
cmd . biquad . a = parameter . a ;
if ( ! IsChannelCountValid ( p . channel_count ) | | channel < 0 | | channel > = p . channel_count ) {
return ;
}
cmd . input = buffer_offset + p . inputs [ channel ] ;
cmd . output = buffer_offset + p . outputs [ channel ] ;
// Convert float coefficients to Q2.14 fixed-point as expected by the legacy DSP path.
cmd . biquad . b [ 0 ] = ToQ14Clamped ( p . b [ 0 ] ) ;
cmd . biquad . b [ 1 ] = ToQ14Clamped ( p . b [ 1 ] ) ;
cmd . biquad . b [ 2 ] = ToQ14Clamped ( p . b [ 2 ] ) ;
cmd . biquad . a [ 0 ] = ToQ14Clamped ( p . a [ 0 ] ) ;
cmd . biquad . a [ 1 ] = ToQ14Clamped ( p . a [ 1 ] ) ;
} else {
const auto & p {
* reinterpret_cast < BiquadFilterInfo : : ParameterVersion1 * > ( effect_info . GetParameter ( ) ) } ;
// Effects use legacy fixed-point format
if ( ! IsChannelCountValid ( p . channel_count ) | | channel < 0 | | channel > = p . channel_count ) {
return ;
}
cmd . input = buffer_offset + p . inputs [ channel ] ;
cmd . output = buffer_offset + p . outputs [ channel ] ;
cmd . biquad . b = p . b ;
cmd . biquad . a = p . a ;
}
// Effects always use the fixed-point coefficient path on the DSP.
cmd . use_float_coefficients = false ;
cmd . use_float_coefficients = false ;
cmd . state = memory_pool - > Translate ( CpuAddr ( state ) ,
cmd . state = memory_pool - > Translate ( CpuAddr ( state ) ,
@ -595,6 +628,15 @@ void CommandBuffer::GenerateCopyMixBufferCommand(const s32 node_id, EffectInfoBa
const s16 buffer_offset , const s8 channel ) {
const s16 buffer_offset , const s8 channel ) {
auto & cmd { GenerateStart < CopyMixBufferCommand , CommandId : : CopyMixBuffer > ( node_id ) } ;
auto & cmd { GenerateStart < CopyMixBufferCommand , CommandId : : CopyMixBuffer > ( node_id ) } ;
if ( behavior - > IsEffectInfoVersion2Supported ( ) ) {
const auto & parameter_v2 {
* reinterpret_cast < BiquadFilterInfo : : ParameterVersion2 * > ( effect_info . GetParameter ( ) ) } ;
cmd . input_index = buffer_offset + parameter_v2 . inputs [ channel ] ;
cmd . output_index = buffer_offset + parameter_v2 . outputs [ channel ] ;
GenerateEnd < CopyMixBufferCommand > ( cmd ) ;
return ;
}
const auto & parameter {
const auto & parameter {
* reinterpret_cast < BiquadFilterInfo : : ParameterVersion1 * > ( effect_info . GetParameter ( ) ) } ;
* reinterpret_cast < BiquadFilterInfo : : ParameterVersion1 * > ( effect_info . GetParameter ( ) ) } ;
cmd . input_index = buffer_offset + parameter . inputs [ channel ] ;
cmd . input_index = buffer_offset + parameter . inputs [ channel ] ;