audio_core\hle\shared_memory.h: Update struct member names based on FE:Fates Symbols (#6995)
This commit is contained in:
parent
270d3eb7eb
commit
d19fe9aa4c
|
@ -33,34 +33,34 @@ void Mixers::ParseConfig(DspConfiguration& config) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.mixer1_enabled_dirty) {
|
if (config.aux_bus_enable[0]) {
|
||||||
config.mixer1_enabled_dirty.Assign(0);
|
config.aux_bus_enable_0_dirty.Assign(0);
|
||||||
state.mixer1_enabled = config.mixer1_enabled != 0;
|
state.aux_bus_enable[0] = config.aux_bus_enable[0] != 0;
|
||||||
LOG_TRACE(Audio_DSP, "mixers mixer1_enabled = {}", config.mixer1_enabled);
|
LOG_TRACE(Audio_DSP, "mixers aux_bus_enable[0] = {}", config.aux_bus_enable[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.mixer2_enabled_dirty) {
|
if (config.aux_bus_enable[1]) {
|
||||||
config.mixer2_enabled_dirty.Assign(0);
|
config.aux_bus_enable_1_dirty.Assign(0);
|
||||||
state.mixer2_enabled = config.mixer2_enabled != 0;
|
state.aux_bus_enable[1] = config.aux_bus_enable[1] != 0;
|
||||||
LOG_TRACE(Audio_DSP, "mixers mixer2_enabled = {}", config.mixer2_enabled);
|
LOG_TRACE(Audio_DSP, "mixers aux_bus_enable[1] = {}", config.aux_bus_enable[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.volume_0_dirty) {
|
if (config.master_volume) {
|
||||||
config.volume_0_dirty.Assign(0);
|
config.master_volume_dirty.Assign(0);
|
||||||
state.intermediate_mixer_volume[0] = config.volume[0];
|
state.intermediate_mixer_volume[0] = config.master_volume;
|
||||||
LOG_TRACE(Audio_DSP, "mixers volume[0] = {}", config.volume[0]);
|
LOG_TRACE(Audio_DSP, "mixers master_volume = {}", config.master_volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.volume_1_dirty) {
|
if (config.aux_return_volume[0]) {
|
||||||
config.volume_1_dirty.Assign(0);
|
config.aux_return_volume_0_dirty.Assign(0);
|
||||||
state.intermediate_mixer_volume[1] = config.volume[1];
|
state.intermediate_mixer_volume[1] = config.aux_return_volume[0];
|
||||||
LOG_TRACE(Audio_DSP, "mixers volume[1] = {}", config.volume[1]);
|
LOG_TRACE(Audio_DSP, "mixers aux_return_volume[0] = {}", config.aux_return_volume[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.volume_2_dirty) {
|
if (config.aux_return_volume[1]) {
|
||||||
config.volume_2_dirty.Assign(0);
|
config.aux_return_volume_1_dirty.Assign(0);
|
||||||
state.intermediate_mixer_volume[2] = config.volume[2];
|
state.intermediate_mixer_volume[2] = config.aux_return_volume[1];
|
||||||
LOG_TRACE(Audio_DSP, "mixers volume[2] = {}", config.volume[2]);
|
LOG_TRACE(Audio_DSP, "mixers aux_return_volume[1] = {}", config.aux_return_volume[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.output_format_dirty) {
|
if (config.output_format_dirty) {
|
||||||
|
@ -137,7 +137,7 @@ void Mixers::AuxReturn(const IntermediateMixSamples& read_samples) {
|
||||||
// NOTE: read_samples.mix{1,2}.pcm32 annoyingly have their dimensions in reverse order to
|
// NOTE: read_samples.mix{1,2}.pcm32 annoyingly have their dimensions in reverse order to
|
||||||
// QuadFrame32.
|
// QuadFrame32.
|
||||||
|
|
||||||
if (state.mixer1_enabled) {
|
if (state.aux_bus_enable[0]) {
|
||||||
for (std::size_t sample = 0; sample < samples_per_frame; sample++) {
|
for (std::size_t sample = 0; sample < samples_per_frame; sample++) {
|
||||||
for (std::size_t channel = 0; channel < 4; channel++) {
|
for (std::size_t channel = 0; channel < 4; channel++) {
|
||||||
state.intermediate_mix_buffer[1][sample][channel] =
|
state.intermediate_mix_buffer[1][sample][channel] =
|
||||||
|
@ -146,7 +146,7 @@ void Mixers::AuxReturn(const IntermediateMixSamples& read_samples) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.mixer2_enabled) {
|
if (state.aux_bus_enable[1]) {
|
||||||
for (std::size_t sample = 0; sample < samples_per_frame; sample++) {
|
for (std::size_t sample = 0; sample < samples_per_frame; sample++) {
|
||||||
for (std::size_t channel = 0; channel < 4; channel++) {
|
for (std::size_t channel = 0; channel < 4; channel++) {
|
||||||
state.intermediate_mix_buffer[2][sample][channel] =
|
state.intermediate_mix_buffer[2][sample][channel] =
|
||||||
|
@ -163,7 +163,7 @@ void Mixers::AuxSend(IntermediateMixSamples& write_samples,
|
||||||
|
|
||||||
state.intermediate_mix_buffer[0] = input[0];
|
state.intermediate_mix_buffer[0] = input[0];
|
||||||
|
|
||||||
if (state.mixer1_enabled) {
|
if (state.aux_bus_enable[0]) {
|
||||||
for (std::size_t sample = 0; sample < samples_per_frame; sample++) {
|
for (std::size_t sample = 0; sample < samples_per_frame; sample++) {
|
||||||
for (std::size_t channel = 0; channel < 4; channel++) {
|
for (std::size_t channel = 0; channel < 4; channel++) {
|
||||||
write_samples.mix1.pcm32[channel][sample] = input[1][sample][channel];
|
write_samples.mix1.pcm32[channel][sample] = input[1][sample][channel];
|
||||||
|
@ -173,7 +173,7 @@ void Mixers::AuxSend(IntermediateMixSamples& write_samples,
|
||||||
state.intermediate_mix_buffer[1] = input[1];
|
state.intermediate_mix_buffer[1] = input[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.mixer2_enabled) {
|
if (state.aux_bus_enable[1]) {
|
||||||
for (std::size_t sample = 0; sample < samples_per_frame; sample++) {
|
for (std::size_t sample = 0; sample < samples_per_frame; sample++) {
|
||||||
for (std::size_t channel = 0; channel < 4; channel++) {
|
for (std::size_t channel = 0; channel < 4; channel++) {
|
||||||
write_samples.mix2.pcm32[channel][sample] = input[2][sample][channel];
|
write_samples.mix2.pcm32[channel][sample] = input[2][sample][channel];
|
||||||
|
@ -187,6 +187,8 @@ void Mixers::AuxSend(IntermediateMixSamples& write_samples,
|
||||||
void Mixers::MixCurrentFrame() {
|
void Mixers::MixCurrentFrame() {
|
||||||
current_frame.fill({});
|
current_frame.fill({});
|
||||||
|
|
||||||
|
// TODO(SachinV): This is probably not accurate, based on symbols from FE:Fates,
|
||||||
|
// state.intermediate_mixer_volume[0] represents the master volume
|
||||||
for (std::size_t mix = 0; mix < 3; mix++) {
|
for (std::size_t mix = 0; mix < 3; mix++) {
|
||||||
DownmixAndMixIntoCurrentFrame(state.intermediate_mixer_volume[mix],
|
DownmixAndMixIntoCurrentFrame(state.intermediate_mixer_volume[mix],
|
||||||
state.intermediate_mix_buffer[mix]);
|
state.intermediate_mix_buffer[mix]);
|
||||||
|
|
|
@ -34,8 +34,7 @@ private:
|
||||||
struct {
|
struct {
|
||||||
std::array<float, 3> intermediate_mixer_volume = {};
|
std::array<float, 3> intermediate_mixer_volume = {};
|
||||||
|
|
||||||
bool mixer1_enabled = false;
|
std::array<bool, 2> aux_bus_enable = {};
|
||||||
bool mixer2_enabled = false;
|
|
||||||
std::array<QuadFrame32, 3> intermediate_mix_buffer = {};
|
std::array<QuadFrame32, 3> intermediate_mix_buffer = {};
|
||||||
|
|
||||||
OutputFormat output_format = OutputFormat::Stereo;
|
OutputFormat output_format = OutputFormat::Stereo;
|
||||||
|
@ -60,8 +59,7 @@ private:
|
||||||
void serialize(Archive& ar, const unsigned int) {
|
void serialize(Archive& ar, const unsigned int) {
|
||||||
ar& current_frame;
|
ar& current_frame;
|
||||||
ar& state.intermediate_mixer_volume;
|
ar& state.intermediate_mixer_volume;
|
||||||
ar& state.mixer1_enabled;
|
ar& state.aux_bus_enable;
|
||||||
ar& state.mixer2_enabled;
|
|
||||||
ar& state.intermediate_mix_buffer;
|
ar& state.intermediate_mix_buffer;
|
||||||
ar& state.output_format;
|
ar& state.output_format;
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ struct SourceConfiguration {
|
||||||
BitField<25, 1, u32> gain_0_dirty;
|
BitField<25, 1, u32> gain_0_dirty;
|
||||||
BitField<26, 1, u32> gain_1_dirty;
|
BitField<26, 1, u32> gain_1_dirty;
|
||||||
BitField<27, 1, u32> gain_2_dirty;
|
BitField<27, 1, u32> gain_2_dirty;
|
||||||
BitField<28, 1, u32> sync_dirty;
|
BitField<28, 1, u32> sync_count_dirty;
|
||||||
BitField<29, 1, u32> reset_flag;
|
BitField<29, 1, u32> reset_flag;
|
||||||
BitField<30, 1, u32> embedded_buffer_dirty;
|
BitField<30, 1, u32> embedded_buffer_dirty;
|
||||||
};
|
};
|
||||||
|
@ -251,7 +251,7 @@ struct SourceConfiguration {
|
||||||
u32_dsp loop_related;
|
u32_dsp loop_related;
|
||||||
u8 enable;
|
u8 enable;
|
||||||
INSERT_PADDING_BYTES(1);
|
INSERT_PADDING_BYTES(1);
|
||||||
u16_le sync; ///< Application-side sync (See also: SourceStatus::sync)
|
u16_le sync_count; ///< Application-side sync count (See also: SourceStatus::sync_count)
|
||||||
u32_dsp play_position; ///< Position. (Units: number of samples)
|
u32_dsp play_position; ///< Position. (Units: number of samples)
|
||||||
INSERT_PADDING_DSPWORDS(2);
|
INSERT_PADDING_DSPWORDS(2);
|
||||||
|
|
||||||
|
@ -313,9 +313,9 @@ struct SourceStatus {
|
||||||
struct Status {
|
struct Status {
|
||||||
u8 is_enabled; ///< Is this channel enabled? (Doesn't have to be playing anything.)
|
u8 is_enabled; ///< Is this channel enabled? (Doesn't have to be playing anything.)
|
||||||
u8 current_buffer_id_dirty; ///< Non-zero when current_buffer_id changes
|
u8 current_buffer_id_dirty; ///< Non-zero when current_buffer_id changes
|
||||||
u16_le sync; ///< Is set by the DSP to the value of SourceConfiguration::sync
|
u16_le sync_count; ///< Is set by the DSP to the value of SourceConfiguration::sync_count
|
||||||
u32_dsp buffer_position; ///< Number of samples into the current buffer
|
u32_dsp buffer_position; ///< Number of samples into the current buffer
|
||||||
u16_le current_buffer_id; ///< Updated when a buffer finishes playing
|
u16_le current_buffer_id; ///< Updated when a buffer finishes playing
|
||||||
INSERT_PADDING_DSPWORDS(1);
|
INSERT_PADDING_DSPWORDS(1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -329,27 +329,35 @@ struct DspConfiguration {
|
||||||
union {
|
union {
|
||||||
u32_le dirty_raw;
|
u32_le dirty_raw;
|
||||||
|
|
||||||
BitField<8, 1, u32> mixer1_enabled_dirty;
|
BitField<6, 1, u32> aux_front_bypass_0_dirty;
|
||||||
BitField<9, 1, u32> mixer2_enabled_dirty;
|
BitField<7, 1, u32> aux_front_bypass_1_dirty;
|
||||||
|
BitField<8, 1, u32> aux_bus_enable_0_dirty;
|
||||||
|
BitField<9, 1, u32> aux_bus_enable_1_dirty;
|
||||||
BitField<10, 1, u32> delay_effect_0_dirty;
|
BitField<10, 1, u32> delay_effect_0_dirty;
|
||||||
BitField<11, 1, u32> delay_effect_1_dirty;
|
BitField<11, 1, u32> delay_effect_1_dirty;
|
||||||
BitField<12, 1, u32> reverb_effect_0_dirty;
|
BitField<12, 1, u32> reverb_effect_0_dirty;
|
||||||
BitField<13, 1, u32> reverb_effect_1_dirty;
|
BitField<13, 1, u32> reverb_effect_1_dirty;
|
||||||
|
|
||||||
BitField<16, 1, u32> volume_0_dirty;
|
BitField<15, 1, u32> output_buffer_count_dirty;
|
||||||
|
BitField<16, 1, u32> master_volume_dirty;
|
||||||
|
|
||||||
BitField<24, 1, u32> volume_1_dirty;
|
BitField<24, 1, u32> aux_return_volume_0_dirty;
|
||||||
BitField<25, 1, u32> volume_2_dirty;
|
BitField<25, 1, u32> aux_return_volume_1_dirty;
|
||||||
BitField<26, 1, u32> output_format_dirty;
|
BitField<26, 1, u32> output_format_dirty;
|
||||||
BitField<27, 1, u32> limiter_enabled_dirty;
|
BitField<27, 1, u32> clipping_mode_dirty;
|
||||||
BitField<28, 1, u32> headphones_connected_dirty;
|
BitField<28, 1, u32> headphones_connected_dirty;
|
||||||
|
BitField<29, 1, u32> surround_depth_dirty;
|
||||||
|
BitField<30, 1, u32> surround_speaker_position_dirty;
|
||||||
|
BitField<31, 1, u32> rear_ratio_dirty;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The DSP has three intermediate audio mixers. This controls the volume level (0.0-1.0) for
|
/// The DSP has three intermediate audio mixers. This controls the volume level (0.0-1.0) for
|
||||||
/// each at the final mixer.
|
/// each at the final mixer.
|
||||||
float_le volume[3];
|
float_le master_volume;
|
||||||
|
std::array<float_le, 2> aux_return_volume;
|
||||||
|
|
||||||
INSERT_PADDING_DSPWORDS(3);
|
u16_le output_buffer_count;
|
||||||
|
INSERT_PADDING_DSPWORDS(2);
|
||||||
|
|
||||||
enum class OutputFormat : u16_le {
|
enum class OutputFormat : u16_le {
|
||||||
Mono = 0,
|
Mono = 0,
|
||||||
|
@ -359,12 +367,15 @@ struct DspConfiguration {
|
||||||
|
|
||||||
OutputFormat output_format;
|
OutputFormat output_format;
|
||||||
|
|
||||||
u16_le limiter_enabled; ///< Not sure of the exact gain equation for the limiter.
|
u16_le clipping_mode; ///< Not sure of the exact gain equation for the limiter.
|
||||||
u16_le headphones_connected; ///< Application updates the DSP on headphone status.
|
u16_le headphones_connected; ///< Application updates the DSP on headphone status.
|
||||||
INSERT_PADDING_DSPWORDS(4); ///< TODO: Surround sound related
|
|
||||||
INSERT_PADDING_DSPWORDS(2); ///< TODO: Intermediate mixer 1/2 related
|
u16_le surround_depth;
|
||||||
u16_le mixer1_enabled;
|
u16_le surround_speaker_position;
|
||||||
u16_le mixer2_enabled;
|
INSERT_PADDING_DSPWORDS(1); ///< TODO: Surround sound related
|
||||||
|
u16_le rear_ratio;
|
||||||
|
std::array<u16_le, 2> aux_front_bypass;
|
||||||
|
std::array<u16_le, 2> aux_bus_enable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is delay with feedback.
|
* This is delay with feedback.
|
||||||
|
@ -406,11 +417,19 @@ struct DspConfiguration {
|
||||||
|
|
||||||
ReverbEffect reverb_effect[2];
|
ReverbEffect reverb_effect[2];
|
||||||
|
|
||||||
INSERT_PADDING_DSPWORDS(4);
|
u16_le sync_mode;
|
||||||
|
INSERT_PADDING_DSPWORDS(1);
|
||||||
|
union {
|
||||||
|
u32_le dirty2_raw;
|
||||||
|
|
||||||
|
BitField<16, 1, u32> sync_mode_dirty;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
ASSERT_DSP_STRUCT(DspConfiguration, 196);
|
ASSERT_DSP_STRUCT(DspConfiguration, 196);
|
||||||
ASSERT_DSP_STRUCT(DspConfiguration::DelayEffect, 20);
|
ASSERT_DSP_STRUCT(DspConfiguration::DelayEffect, 20);
|
||||||
ASSERT_DSP_STRUCT(DspConfiguration::ReverbEffect, 52);
|
ASSERT_DSP_STRUCT(DspConfiguration::ReverbEffect, 52);
|
||||||
|
static_assert(offsetof(DspConfiguration, sync_mode) == 0xBC);
|
||||||
|
static_assert(offsetof(DspConfiguration, dirty2_raw) == 0xC0);
|
||||||
|
|
||||||
struct AdpcmCoefficients {
|
struct AdpcmCoefficients {
|
||||||
/// Coefficients are signed fixed point with 11 fractional bits.
|
/// Coefficients are signed fixed point with 11 fractional bits.
|
||||||
|
|
|
@ -72,10 +72,10 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config,
|
||||||
LOG_TRACE(Audio_DSP, "source_id={} enable={}", source_id, state.enabled);
|
LOG_TRACE(Audio_DSP, "source_id={} enable={}", source_id, state.enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.sync_dirty) {
|
if (config.sync_count_dirty) {
|
||||||
config.sync_dirty.Assign(0);
|
config.sync_count_dirty.Assign(0);
|
||||||
state.sync = config.sync;
|
state.sync_count = config.sync_count;
|
||||||
LOG_TRACE(Audio_DSP, "source_id={} sync={}", source_id, state.sync);
|
LOG_TRACE(Audio_DSP, "source_id={} sync={}", source_id, state.sync_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.rate_multiplier_dirty) {
|
if (config.rate_multiplier_dirty) {
|
||||||
|
@ -432,7 +432,7 @@ SourceStatus::Status Source::GetCurrentStatus() {
|
||||||
state.buffer_update = false;
|
state.buffer_update = false;
|
||||||
ret.current_buffer_id = state.current_buffer_id;
|
ret.current_buffer_id = state.current_buffer_id;
|
||||||
ret.buffer_position = state.current_sample_number;
|
ret.buffer_position = state.current_sample_number;
|
||||||
ret.sync = state.sync;
|
ret.sync_count = state.sync_count;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,7 @@ private:
|
||||||
// State variables
|
// State variables
|
||||||
|
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
u16 sync = 0;
|
u16 sync_count = 0;
|
||||||
|
|
||||||
// Mixing
|
// Mixing
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ private:
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void serialize(Archive& ar, const unsigned int) {
|
void serialize(Archive& ar, const unsigned int) {
|
||||||
ar& enabled;
|
ar& enabled;
|
||||||
ar& sync;
|
ar& sync_count;
|
||||||
ar& gain;
|
ar& gain;
|
||||||
ar& input_queue;
|
ar& input_queue;
|
||||||
ar& mono_or_stereo;
|
ar& mono_or_stereo;
|
||||||
|
|
Reference in New Issue