diff --git a/Source/Core/AudioCommon/Mixer.cpp b/Source/Core/AudioCommon/Mixer.cpp index 31c30e76af..2d2fdbf50f 100644 --- a/Source/Core/AudioCommon/Mixer.cpp +++ b/Source/Core/AudioCommon/Mixer.cpp @@ -66,7 +66,7 @@ void Mixer::MixerFifo::Mix(s16* samples, std::size_t num_samples) constexpr DT_s FADE_OUT_RC = DT_s(0.064); const u64 out_sample_rate = m_mixer->m_output_sample_rate; - u64 in_sample_rate = FIXED_SAMPLE_RATE_DIVIDEND / m_input_sample_rate_divisor; + u64 in_sample_rate = m_input_sample_rate; const float emulation_speed = m_mixer->m_config_emulation_speed; if (0 < emulation_speed && emulation_speed != 1.0) @@ -225,10 +225,10 @@ void Mixer::PushSamples(const s16* samples, std::size_t num_samples) m_dma_mixer.PushSamples(samples, num_samples); if (m_log_dsp_audio) { - const s32 sample_rate_divisor = m_dma_mixer.GetInputSampleRateDivisor(); + const s32 sample_rate = m_dma_mixer.GetInputSampleRate(); auto volume = m_dma_mixer.GetVolume(); - m_wave_writer_dsp.AddStereoSamplesBE(samples, static_cast(num_samples), - sample_rate_divisor, volume.first, volume.second); + m_wave_writer_dsp.AddStereoSamplesBE(samples, static_cast(num_samples), sample_rate, + volume.first, volume.second); } } @@ -237,15 +237,14 @@ void Mixer::PushStreamingSamples(const s16* samples, std::size_t num_samples) m_streaming_mixer.PushSamples(samples, num_samples); if (m_log_dtk_audio) { - const s32 sample_rate_divisor = m_streaming_mixer.GetInputSampleRateDivisor(); + const s32 sample_rate = m_streaming_mixer.GetInputSampleRate(); auto volume = m_streaming_mixer.GetVolume(); - m_wave_writer_dtk.AddStereoSamplesBE(samples, static_cast(num_samples), - sample_rate_divisor, volume.first, volume.second); + m_wave_writer_dtk.AddStereoSamplesBE(samples, static_cast(num_samples), sample_rate, + volume.first, volume.second); } } -void Mixer::PushWiimoteSpeakerSamples(const s16* samples, std::size_t num_samples, - u32 sample_rate_divisor) +void Mixer::PushWiimoteSpeakerSamples(const s16* samples, std::size_t num_samples, u32 sample_rate) { // Max 20 bytes/speaker report, may be 4-bit ADPCM so multiply by 2 static constexpr std::size_t MAX_SPEAKER_SAMPLES = 20 * 2; @@ -256,7 +255,7 @@ void Mixer::PushWiimoteSpeakerSamples(const s16* samples, std::size_t num_sample MAX_SPEAKER_SAMPLES); if (num_samples <= MAX_SPEAKER_SAMPLES) { - m_wiimote_speaker_mixer.SetInputSampleRateDivisor(sample_rate_divisor); + m_wiimote_speaker_mixer.SetInputSampleRate(sample_rate); for (std::size_t i = 0; i < num_samples; ++i) { @@ -297,19 +296,19 @@ void Mixer::PushGBASamples(std::size_t device_number, const s16* samples, std::s m_gba_mixers[device_number].PushSamples(samples, num_samples); } -void Mixer::SetDMAInputSampleRateDivisor(u32 rate_divisor) +void Mixer::SetDMAInputSampleRate(u32 sample_rate) { - m_dma_mixer.SetInputSampleRateDivisor(rate_divisor); + m_dma_mixer.SetInputSampleRate(sample_rate); } -void Mixer::SetStreamInputSampleRateDivisor(u32 rate_divisor) +void Mixer::SetStreamInputSampleRate(u32 sample_rate) { - m_streaming_mixer.SetInputSampleRateDivisor(rate_divisor); + m_streaming_mixer.SetInputSampleRate(sample_rate); } -void Mixer::SetGBAInputSampleRateDivisors(std::size_t device_number, u32 rate_divisor) +void Mixer::SetGBAInputSampleRate(std::size_t device_number, u32 sample_rate) { - m_gba_mixers[device_number].SetInputSampleRateDivisor(rate_divisor); + m_gba_mixers[device_number].SetInputSampleRate(sample_rate); } void Mixer::SetStreamingVolume(u32 lvolume, u32 rvolume) @@ -332,7 +331,7 @@ void Mixer::StartLogDTKAudio(const std::string& filename) { if (!m_log_dtk_audio) { - bool success = m_wave_writer_dtk.Start(filename, m_streaming_mixer.GetInputSampleRateDivisor()); + bool success = m_wave_writer_dtk.Start(filename, m_streaming_mixer.GetInputSampleRate()); if (success) { m_log_dtk_audio = true; @@ -369,7 +368,7 @@ void Mixer::StartLogDSPAudio(const std::string& filename) { if (!m_log_dsp_audio) { - bool success = m_wave_writer_dsp.Start(filename, m_dma_mixer.GetInputSampleRateDivisor()); + bool success = m_wave_writer_dsp.Start(filename, m_dma_mixer.GetInputSampleRate()); if (success) { m_log_dsp_audio = true; @@ -411,19 +410,19 @@ void Mixer::RefreshConfig() void Mixer::MixerFifo::DoState(PointerWrap& p) { - p.Do(m_input_sample_rate_divisor); + p.Do(m_input_sample_rate); p.Do(m_LVolume); p.Do(m_RVolume); } -void Mixer::MixerFifo::SetInputSampleRateDivisor(u32 rate_divisor) +void Mixer::MixerFifo::SetInputSampleRate(u32 sample_rate) { - m_input_sample_rate_divisor = rate_divisor; + m_input_sample_rate = sample_rate; } -u32 Mixer::MixerFifo::GetInputSampleRateDivisor() const +u32 Mixer::MixerFifo::GetInputSampleRate() const { - return m_input_sample_rate_divisor; + return m_input_sample_rate; } void Mixer::MixerFifo::SetVolume(u32 lvolume, u32 rvolume) diff --git a/Source/Core/AudioCommon/Mixer.h b/Source/Core/AudioCommon/Mixer.h index ba74c3d71b..55f543cece 100644 --- a/Source/Core/AudioCommon/Mixer.h +++ b/Source/Core/AudioCommon/Mixer.h @@ -3,7 +3,6 @@ #pragma once -#include #include #include #include @@ -31,16 +30,15 @@ public: // Called from main thread void PushSamples(const s16* samples, std::size_t num_samples); void PushStreamingSamples(const s16* samples, std::size_t num_samples); - void PushWiimoteSpeakerSamples(const s16* samples, std::size_t num_samples, - u32 sample_rate_divisor); + void PushWiimoteSpeakerSamples(const s16* samples, std::size_t num_samples, u32 sample_rate); void PushSkylanderPortalSamples(const u8* samples, std::size_t num_samples); void PushGBASamples(std::size_t device_number, const s16* samples, std::size_t num_samples); u32 GetSampleRate() const { return m_output_sample_rate; } - void SetDMAInputSampleRateDivisor(u32 rate_divisor); - void SetStreamInputSampleRateDivisor(u32 rate_divisor); - void SetGBAInputSampleRateDivisors(std::size_t device_number, u32 rate_divisor); + void SetDMAInputSampleRate(u32 sample_rate); + void SetStreamInputSampleRate(u32 sample_rate); + void SetGBAInputSampleRate(std::size_t device_number, u32 sample_rate); void SetStreamingVolume(u32 lvolume, u32 rvolume); void SetWiimoteSpeakerVolume(u32 lvolume, u32 rvolume); @@ -52,9 +50,6 @@ public: void StartLogDSPAudio(const std::string& filename); void StopLogDSPAudio(); - // 54000000 doesn't work here as it doesn't evenly divide with 32000, but 108000000 does - static constexpr u64 FIXED_SAMPLE_RATE_DIVIDEND = 54000000 * 2; - private: const std::size_t SURROUND_CHANNELS = 6; @@ -98,22 +93,21 @@ private: using Granule = std::array; public: - MixerFifo(Mixer* mixer, u32 sample_rate_divisor, bool little_endian) - : m_mixer(mixer), m_input_sample_rate_divisor(sample_rate_divisor), - m_little_endian(little_endian) + MixerFifo(Mixer* mixer, u32 sample_rate, bool little_endian) + : m_mixer(mixer), m_input_sample_rate(sample_rate), m_little_endian(little_endian) { } void DoState(PointerWrap& p); void PushSamples(const s16* samples, std::size_t num_samples); void Mix(s16* samples, std::size_t num_samples); - void SetInputSampleRateDivisor(u32 rate_divisor); - u32 GetInputSampleRateDivisor() const; + void SetInputSampleRate(u32 sample_rate); + u32 GetInputSampleRate() const; void SetVolume(u32 lvolume, u32 rvolume); std::pair GetVolume() const; private: Mixer* m_mixer; - u32 m_input_sample_rate_divisor; + u32 m_input_sample_rate; bool m_little_endian; Granule m_next_buffer{}; @@ -141,14 +135,12 @@ private: void RefreshConfig(); - MixerFifo m_dma_mixer{this, FIXED_SAMPLE_RATE_DIVIDEND / 32000, false}; - MixerFifo m_streaming_mixer{this, FIXED_SAMPLE_RATE_DIVIDEND / 48000, false}; - MixerFifo m_wiimote_speaker_mixer{this, FIXED_SAMPLE_RATE_DIVIDEND / 3000, true}; - MixerFifo m_skylander_portal_mixer{this, FIXED_SAMPLE_RATE_DIVIDEND / 8000, true}; - std::array m_gba_mixers{MixerFifo{this, FIXED_SAMPLE_RATE_DIVIDEND / 48000, true}, - MixerFifo{this, FIXED_SAMPLE_RATE_DIVIDEND / 48000, true}, - MixerFifo{this, FIXED_SAMPLE_RATE_DIVIDEND / 48000, true}, - MixerFifo{this, FIXED_SAMPLE_RATE_DIVIDEND / 48000, true}}; + MixerFifo m_dma_mixer{this, 32000, false}; + MixerFifo m_streaming_mixer{this, 48000, false}; + MixerFifo m_wiimote_speaker_mixer{this, 3000, true}; + MixerFifo m_skylander_portal_mixer{this, 8000, true}; + std::array m_gba_mixers{MixerFifo{this, 48000, true}, MixerFifo{this, 48000, true}, + MixerFifo{this, 48000, true}, MixerFifo{this, 48000, true}}; u32 m_output_sample_rate; AudioCommon::SurroundDecoder m_surround_decoder; diff --git a/Source/Core/AudioCommon/WaveFile.cpp b/Source/Core/AudioCommon/WaveFile.cpp index 3c74bd0cc4..7c5461aa26 100644 --- a/Source/Core/AudioCommon/WaveFile.cpp +++ b/Source/Core/AudioCommon/WaveFile.cpp @@ -7,7 +7,6 @@ #include -#include "AudioCommon/Mixer.h" #include "Common/CommonTypes.h" #include "Common/FileUtil.h" #include "Common/IOFile.h" @@ -16,7 +15,6 @@ #include "Common/StringUtil.h" #include "Common/Swap.h" #include "Core/Config/MainSettings.h" -#include "Core/ConfigManager.h" constexpr size_t WaveFileWriter::BUFFER_SIZE; @@ -29,7 +27,7 @@ WaveFileWriter::~WaveFileWriter() Stop(); } -bool WaveFileWriter::Start(const std::string& filename, u32 sample_rate_divisor) +bool WaveFileWriter::Start(const std::string& filename, u32 sample_rate) { // Ask to delete file if (File::Exists(filename)) @@ -68,7 +66,7 @@ bool WaveFileWriter::Start(const std::string& filename, u32 sample_rate_divisor) if (basename.empty()) SplitPath(filename, nullptr, &basename, nullptr); - current_sample_rate_divisor = sample_rate_divisor; + current_sample_rate = sample_rate; // ----------------- // Write file header @@ -81,7 +79,6 @@ bool WaveFileWriter::Start(const std::string& filename, u32 sample_rate_divisor) Write(16); // size of fmt block Write(0x00020001); // two channels, uncompressed - const u32 sample_rate = Mixer::FIXED_SAMPLE_RATE_DIVIDEND / sample_rate_divisor; Write(sample_rate); Write(sample_rate * 2 * 2); // two channels, 16bit @@ -117,8 +114,8 @@ void WaveFileWriter::Write4(const char* ptr) file.WriteBytes(ptr, 4); } -void WaveFileWriter::AddStereoSamplesBE(const short* sample_data, u32 count, - u32 sample_rate_divisor, int l_volume, int r_volume) +void WaveFileWriter::AddStereoSamplesBE(const short* sample_data, u32 count, u32 sample_rate, + int l_volume, int r_volume) { if (!file) { @@ -157,14 +154,14 @@ void WaveFileWriter::AddStereoSamplesBE(const short* sample_data, u32 count, conv_buffer[2 * i + 1] = conv_buffer[2 * i + 1] * r_volume / 256; } - if (sample_rate_divisor != current_sample_rate_divisor) + if (sample_rate != current_sample_rate) { Stop(); file_index++; const std::string filename = fmt::format("{}{}{}.wav", File::GetUserPath(D_DUMPAUDIO_IDX), basename, file_index); - Start(filename, sample_rate_divisor); - current_sample_rate_divisor = sample_rate_divisor; + Start(filename, sample_rate); + current_sample_rate = sample_rate; } file.WriteBytes(conv_buffer.data(), count * 4); diff --git a/Source/Core/AudioCommon/WaveFile.h b/Source/Core/AudioCommon/WaveFile.h index 350e1da9af..ced9485819 100644 --- a/Source/Core/AudioCommon/WaveFile.h +++ b/Source/Core/AudioCommon/WaveFile.h @@ -30,13 +30,13 @@ public: WaveFileWriter(WaveFileWriter&&) = delete; WaveFileWriter& operator=(WaveFileWriter&&) = delete; - bool Start(const std::string& filename, u32 sample_rate_divisor); + bool Start(const std::string& filename, u32 sample_rate); void Stop(); void SetSkipSilence(bool skip) { skip_silence = skip; } // big endian - void AddStereoSamplesBE(const short* sample_data, u32 count, u32 sample_rate_divisor, - int l_volume, int r_volume); + void AddStereoSamplesBE(const short* sample_data, u32 count, u32 sample_rate, int l_volume, + int r_volume); u32 GetAudioSize() const { return audio_size; } private: @@ -50,7 +50,7 @@ private: u32 file_index = 0; u32 audio_size = 0; - u32 current_sample_rate_divisor; + u32 current_sample_rate; std::array conv_buffer{}; bool skip_silence = false; diff --git a/Source/Core/Core/HW/AudioInterface.cpp b/Source/Core/Core/HW/AudioInterface.cpp index 7e1a997e0c..6d4f82393c 100644 --- a/Source/Core/Core/HW/AudioInterface.cpp +++ b/Source/Core/Core/HW/AudioInterface.cpp @@ -71,8 +71,8 @@ enum }; AudioInterfaceManager::AudioInterfaceManager(Core::System& system) - : m_ais_sample_rate_divisor(Mixer::FIXED_SAMPLE_RATE_DIVIDEND / 48000), - m_aid_sample_rate_divisor(Mixer::FIXED_SAMPLE_RATE_DIVIDEND / 32000), m_system(system) + : m_ais_sample_rate_divisor(FIXED_SAMPLE_RATE_DIVIDEND / 48000), + m_aid_sample_rate_divisor(FIXED_SAMPLE_RATE_DIVIDEND / 32000), m_system(system) { } @@ -125,8 +125,7 @@ void AudioInterfaceManager::IncreaseSampleCount(const u32 amount) int AudioInterfaceManager::GetAIPeriod() const { u64 period = m_cpu_cycles_per_sample * (m_interrupt_timing - m_sample_counter); - u64 s_period = - m_cpu_cycles_per_sample * Mixer::FIXED_SAMPLE_RATE_DIVIDEND / m_ais_sample_rate_divisor; + u64 s_period = m_cpu_cycles_per_sample * FIXED_SAMPLE_RATE_DIVIDEND / m_ais_sample_rate_divisor; if (period == 0) return static_cast(s_period); return static_cast(std::min(period, s_period)); @@ -168,7 +167,8 @@ void AudioInterfaceManager::SetAIDSampleRate(SampleRate sample_rate) } SoundStream* sound_stream = m_system.GetSoundStream(); - sound_stream->GetMixer()->SetDMAInputSampleRateDivisor(m_aid_sample_rate_divisor); + sound_stream->GetMixer()->SetDMAInputSampleRate(FIXED_SAMPLE_RATE_DIVIDEND / + m_aid_sample_rate_divisor); } void AudioInterfaceManager::SetAISSampleRate(SampleRate sample_rate) @@ -185,9 +185,10 @@ void AudioInterfaceManager::SetAISSampleRate(SampleRate sample_rate) } m_cpu_cycles_per_sample = static_cast(m_system.GetSystemTimers().GetTicksPerSecond()) * - m_ais_sample_rate_divisor / Mixer::FIXED_SAMPLE_RATE_DIVIDEND; + m_ais_sample_rate_divisor / FIXED_SAMPLE_RATE_DIVIDEND; SoundStream* sound_stream = m_system.GetSoundStream(); - sound_stream->GetMixer()->SetStreamInputSampleRateDivisor(m_ais_sample_rate_divisor); + sound_stream->GetMixer()->SetStreamInputSampleRate(FIXED_SAMPLE_RATE_DIVIDEND / + m_ais_sample_rate_divisor); } void AudioInterfaceManager::Init() diff --git a/Source/Core/Core/HW/AudioInterface.h b/Source/Core/Core/HW/AudioInterface.h index 10fbb11c1c..b65dda126a 100644 --- a/Source/Core/Core/HW/AudioInterface.h +++ b/Source/Core/Core/HW/AudioInterface.h @@ -23,6 +23,9 @@ class Mapping; namespace AudioInterface { +// 54000000 doesn't work here as it doesn't evenly divide with 32000, but 108000000 does +static constexpr u64 FIXED_SAMPLE_RATE_DIVIDEND = 54000000 * 2; + enum class SampleRate { AI32KHz, diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp index babb500902..97b6ba3424 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp @@ -237,7 +237,7 @@ void DVDInterface::DTKStreamingCallback(DIInterruptType interrupt_type, // Read the next chunk of audio data asynchronously. s64 ticks_to_dtk = m_system.GetSystemTimers().GetTicksPerSecond() * s64(m_pending_blocks) * StreamADPCM::SAMPLES_PER_BLOCK * sample_rate_divisor / - Mixer::FIXED_SAMPLE_RATE_DIVIDEND; + AudioInterface::FIXED_SAMPLE_RATE_DIVIDEND; ticks_to_dtk -= cycles_late; if (read_length > 0) { diff --git a/Source/Core/Core/HW/GBACore.cpp b/Source/Core/Core/HW/GBACore.cpp index 9e81914524..1639e79460 100644 --- a/Source/Core/Core/HW/GBACore.cpp +++ b/Source/Core/Core/HW/GBACore.cpp @@ -407,8 +407,7 @@ void Core::SetSampleRates() blip_set_rates(m_core->getAudioChannel(m_core, 1), m_core->frequency(m_core), SAMPLE_RATE); SoundStream* sound_stream = m_system.GetSoundStream(); - sound_stream->GetMixer()->SetGBAInputSampleRateDivisors( - m_device_number, Mixer::FIXED_SAMPLE_RATE_DIVIDEND / SAMPLE_RATE); + sound_stream->GetMixer()->SetGBAInputSampleRate(m_device_number, SAMPLE_RATE); } void Core::AddCallbacks() diff --git a/Source/Core/Core/HW/SystemTimers.cpp b/Source/Core/Core/HW/SystemTimers.cpp index 508b445288..9c4af65558 100644 --- a/Source/Core/Core/HW/SystemTimers.cpp +++ b/Source/Core/Core/HW/SystemTimers.cpp @@ -85,7 +85,7 @@ static int GetAudioDMACallbackPeriod(u32 cpu_core_clock, u32 aid_sample_rate_div { // System internal sample rate is fixed at 32KHz * 4 (16bit Stereo) / 32 bytes DMA return static_cast(cpu_core_clock) * aid_sample_rate_divisor / - (Mixer::FIXED_SAMPLE_RATE_DIVIDEND * 4 / 32); + (AudioInterface::FIXED_SAMPLE_RATE_DIVIDEND * 4 / 32); } void SystemTimersManager::AudioDMACallback(Core::System& system, u64 userdata, s64 cycles_late) diff --git a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp index 3b308891c6..cd7249c247 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp @@ -133,8 +133,8 @@ void SpeakerLogic::SpeakerData(const u8* data, int length, float speaker_pan) // ADPCM sample rate is thought to be x2.(3000 x2 = 6000). const unsigned int sample_rate = sample_rate_dividend / reg_data.sample_rate; - sound_stream->GetMixer()->PushWiimoteSpeakerSamples( - samples.data(), sample_length, Mixer::FIXED_SAMPLE_RATE_DIVIDEND / (sample_rate * 2)); + sound_stream->GetMixer()->PushWiimoteSpeakerSamples(samples.data(), sample_length, + sample_rate * 2); } void SpeakerLogic::Reset()