citra-emu
/
citra
Archived
1
0
Fork 0

audio_core\hle\shared_memory.h: Update struct member names based on FE:Fates Symbols (#6995)

This commit is contained in:
SachinVin 2023-09-23 00:23:30 +05:30 committed by GitHub
parent 270d3eb7eb
commit d19fe9aa4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 73 additions and 54 deletions

View File

@ -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]);

View File

@ -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;
} }

View File

@ -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.

View File

@ -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;
} }

View File

@ -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;