diff --git a/Source/Core/AudioCommon/Mixer.cpp b/Source/Core/AudioCommon/Mixer.cpp index e0b7f28768..5baa02d25e 100644 --- a/Source/Core/AudioCommon/Mixer.cpp +++ b/Source/Core/AudioCommon/Mixer.cpp @@ -76,16 +76,18 @@ unsigned int Mixer::MixerFifo::Mix(short* samples, unsigned int numSamples, // advance indexR with sample position // remember fractional offset - float aid_sample_rate = static_cast(m_input_sample_rate); + float aid_sample_rate = + FIXED_SAMPLE_RATE_DIVIDEND / static_cast(m_input_sample_rate_divisor); if (consider_framelimit && emulationspeed > 0.0f) { float numLeft = static_cast(((indexW - indexR) & INDEX_MASK) / 2); - u32 low_waterwark = m_input_sample_rate * timing_variance / 1000; - low_waterwark = std::min(low_waterwark, MAX_SAMPLES / 2); + u32 low_watermark = (FIXED_SAMPLE_RATE_DIVIDEND * timing_variance) / + (static_cast(m_input_sample_rate_divisor) * 1000); + low_watermark = std::min(low_watermark, MAX_SAMPLES / 2); m_numLeftI = (numLeft + m_numLeftI * (CONTROL_AVG - 1)) / CONTROL_AVG; - float offset = (m_numLeftI - low_waterwark) * CONTROL_FACTOR; + float offset = (m_numLeftI - low_watermark) * CONTROL_FACTOR; if (offset > MAX_FREQ_SHIFT) offset = MAX_FREQ_SHIFT; if (offset < -MAX_FREQ_SHIFT) @@ -258,9 +260,9 @@ void Mixer::PushSamples(const short* samples, unsigned int num_samples) m_dma_mixer.PushSamples(samples, num_samples); if (m_log_dsp_audio) { - int sample_rate = m_dma_mixer.GetInputSampleRate(); + int sample_rate_divisor = m_dma_mixer.GetInputSampleRateDivisor(); auto volume = m_dma_mixer.GetVolume(); - m_wave_writer_dsp.AddStereoSamplesBE(samples, num_samples, sample_rate, volume.first, + m_wave_writer_dsp.AddStereoSamplesBE(samples, num_samples, sample_rate_divisor, volume.first, volume.second); } } @@ -270,21 +272,21 @@ void Mixer::PushStreamingSamples(const short* samples, unsigned int num_samples) m_streaming_mixer.PushSamples(samples, num_samples); if (m_log_dtk_audio) { - int sample_rate = m_streaming_mixer.GetInputSampleRate(); + int sample_rate_divisor = m_streaming_mixer.GetInputSampleRateDivisor(); auto volume = m_streaming_mixer.GetVolume(); - m_wave_writer_dtk.AddStereoSamplesBE(samples, num_samples, sample_rate, volume.first, + m_wave_writer_dtk.AddStereoSamplesBE(samples, num_samples, sample_rate_divisor, volume.first, volume.second); } } void Mixer::PushWiimoteSpeakerSamples(const short* samples, unsigned int num_samples, - unsigned int sample_rate) + unsigned int sample_rate_divisor) { short samples_stereo[MAX_SAMPLES * 2]; if (num_samples < MAX_SAMPLES) { - m_wiimote_speaker_mixer.SetInputSampleRate(sample_rate); + m_wiimote_speaker_mixer.SetInputSampleRateDivisor(sample_rate_divisor); for (unsigned int i = 0; i < num_samples; ++i) { @@ -301,19 +303,19 @@ void Mixer::PushGBASamples(int device_number, const short* samples, unsigned int m_gba_mixers[device_number].PushSamples(samples, num_samples); } -void Mixer::SetDMAInputSampleRate(unsigned int rate) +void Mixer::SetDMAInputSampleRateDivisor(unsigned int rate_divisor) { - m_dma_mixer.SetInputSampleRate(rate); + m_dma_mixer.SetInputSampleRateDivisor(rate_divisor); } -void Mixer::SetStreamInputSampleRate(unsigned int rate) +void Mixer::SetStreamInputSampleRateDivisor(unsigned int rate_divisor) { - m_streaming_mixer.SetInputSampleRate(rate); + m_streaming_mixer.SetInputSampleRateDivisor(rate_divisor); } -void Mixer::SetGBAInputSampleRates(int device_number, unsigned int rate) +void Mixer::SetGBAInputSampleRateDivisors(int device_number, unsigned int rate_divisor) { - m_gba_mixers[device_number].SetInputSampleRate(rate); + m_gba_mixers[device_number].SetInputSampleRateDivisor(rate_divisor); } void Mixer::SetStreamingVolume(unsigned int lvolume, unsigned int rvolume) @@ -335,7 +337,7 @@ void Mixer::StartLogDTKAudio(const std::string& filename) { if (!m_log_dtk_audio) { - bool success = m_wave_writer_dtk.Start(filename, m_streaming_mixer.GetInputSampleRate()); + bool success = m_wave_writer_dtk.Start(filename, m_streaming_mixer.GetInputSampleRateDivisor()); if (success) { m_log_dtk_audio = true; @@ -372,7 +374,7 @@ void Mixer::StartLogDSPAudio(const std::string& filename) { if (!m_log_dsp_audio) { - bool success = m_wave_writer_dsp.Start(filename, m_dma_mixer.GetInputSampleRate()); + bool success = m_wave_writer_dsp.Start(filename, m_dma_mixer.GetInputSampleRateDivisor()); if (success) { m_log_dsp_audio = true; @@ -414,19 +416,19 @@ void Mixer::RefreshConfig() void Mixer::MixerFifo::DoState(PointerWrap& p) { - p.Do(m_input_sample_rate); + p.Do(m_input_sample_rate_divisor); p.Do(m_LVolume); p.Do(m_RVolume); } -void Mixer::MixerFifo::SetInputSampleRate(unsigned int rate) +void Mixer::MixerFifo::SetInputSampleRateDivisor(unsigned int rate_divisor) { - m_input_sample_rate = rate; + m_input_sample_rate_divisor = rate_divisor; } -unsigned int Mixer::MixerFifo::GetInputSampleRate() const +unsigned int Mixer::MixerFifo::GetInputSampleRateDivisor() const { - return m_input_sample_rate; + return m_input_sample_rate_divisor; } void Mixer::MixerFifo::SetVolume(unsigned int lvolume, unsigned int rvolume) @@ -445,5 +447,6 @@ unsigned int Mixer::MixerFifo::AvailableSamples() const unsigned int samples_in_fifo = ((m_indexW.load() - m_indexR.load()) & INDEX_MASK) / 2; if (samples_in_fifo <= 1) return 0; // Mixer::MixerFifo::Mix always keeps one sample in the buffer. - return (samples_in_fifo - 1) * m_mixer->m_sampleRate / m_input_sample_rate; + return (samples_in_fifo - 1) * static_cast(m_mixer->m_sampleRate) * + m_input_sample_rate_divisor / FIXED_SAMPLE_RATE_DIVIDEND; } diff --git a/Source/Core/AudioCommon/Mixer.h b/Source/Core/AudioCommon/Mixer.h index f58c25f98a..7191fd6ab0 100644 --- a/Source/Core/AudioCommon/Mixer.h +++ b/Source/Core/AudioCommon/Mixer.h @@ -29,14 +29,14 @@ public: void PushSamples(const short* samples, unsigned int num_samples); void PushStreamingSamples(const short* samples, unsigned int num_samples); void PushWiimoteSpeakerSamples(const short* samples, unsigned int num_samples, - unsigned int sample_rate); + unsigned int sample_rate_divisor); void PushGBASamples(int device_number, const short* samples, unsigned int num_samples); unsigned int GetSampleRate() const { return m_sampleRate; } - void SetDMAInputSampleRate(unsigned int rate); - void SetStreamInputSampleRate(unsigned int rate); - void SetGBAInputSampleRates(int device_number, unsigned int rate); + void SetDMAInputSampleRateDivisor(unsigned int rate_divisor); + void SetStreamInputSampleRateDivisor(unsigned int rate_divisor); + void SetGBAInputSampleRateDivisors(int device_number, unsigned int rate_divisor); void SetStreamingVolume(unsigned int lvolume, unsigned int rvolume); void SetWiimoteSpeakerVolume(unsigned int lvolume, unsigned int rvolume); @@ -51,6 +51,9 @@ public: float GetCurrentSpeed() const { return m_speed.load(); } void UpdateSpeed(float val) { m_speed.store(val); } + // 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: static constexpr u32 MAX_SAMPLES = 1024 * 4; // 128 ms static constexpr u32 INDEX_MASK = MAX_SAMPLES * 2 - 1; @@ -63,23 +66,24 @@ private: class MixerFifo final { public: - MixerFifo(Mixer* mixer, unsigned sample_rate, bool little_endian) - : m_mixer(mixer), m_input_sample_rate(sample_rate), m_little_endian(little_endian) + MixerFifo(Mixer* mixer, unsigned sample_rate_divisor, bool little_endian) + : m_mixer(mixer), m_input_sample_rate_divisor(sample_rate_divisor), + m_little_endian(little_endian) { } void DoState(PointerWrap& p); void PushSamples(const short* samples, unsigned int num_samples); unsigned int Mix(short* samples, unsigned int numSamples, bool consider_framelimit, float emulationspeed, int timing_variance); - void SetInputSampleRate(unsigned int rate); - unsigned int GetInputSampleRate() const; + void SetInputSampleRateDivisor(unsigned int rate_divisor); + unsigned int GetInputSampleRateDivisor() const; void SetVolume(unsigned int lvolume, unsigned int rvolume); std::pair GetVolume() const; unsigned int AvailableSamples() const; private: Mixer* m_mixer; - unsigned m_input_sample_rate; + unsigned m_input_sample_rate_divisor; bool m_little_endian; std::array m_buffer{}; std::atomic m_indexW{0}; @@ -93,11 +97,13 @@ private: void RefreshConfig(); - MixerFifo m_dma_mixer{this, 32000, false}; - MixerFifo m_streaming_mixer{this, 48000, false}; - MixerFifo m_wiimote_speaker_mixer{this, 3000, true}; - std::array m_gba_mixers{MixerFifo{this, 48000, true}, MixerFifo{this, 48000, true}, - MixerFifo{this, 48000, true}, MixerFifo{this, 48000, true}}; + 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}; + 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}}; unsigned int m_sampleRate; bool m_is_stretching = false; diff --git a/Source/Core/AudioCommon/WaveFile.cpp b/Source/Core/AudioCommon/WaveFile.cpp index befcf6bfbd..dc689e74dd 100644 --- a/Source/Core/AudioCommon/WaveFile.cpp +++ b/Source/Core/AudioCommon/WaveFile.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "AudioCommon/WaveFile.h" +#include "AudioCommon/Mixer.h" #include @@ -26,7 +27,7 @@ WaveFileWriter::~WaveFileWriter() Stop(); } -bool WaveFileWriter::Start(const std::string& filename, unsigned int HLESampleRate) +bool WaveFileWriter::Start(const std::string& filename, u32 sample_rate_divisor) { // Ask to delete file if (File::Exists(filename)) @@ -65,7 +66,7 @@ bool WaveFileWriter::Start(const std::string& filename, unsigned int HLESampleRa if (basename.empty()) SplitPath(filename, nullptr, &basename, nullptr); - current_sample_rate = HLESampleRate; + current_sample_rate_divisor = sample_rate_divisor; // ----------------- // Write file header @@ -78,7 +79,7 @@ bool WaveFileWriter::Start(const std::string& filename, unsigned int HLESampleRa Write(16); // size of fmt block Write(0x00020001); // two channels, uncompressed - const u32 sample_rate = HLESampleRate; + const u32 sample_rate = Mixer::FIXED_SAMPLE_RATE_DIVIDEND / sample_rate_divisor; Write(sample_rate); Write(sample_rate * 2 * 2); // two channels, 16bit @@ -114,8 +115,8 @@ void WaveFileWriter::Write4(const char* ptr) file.WriteBytes(ptr, 4); } -void WaveFileWriter::AddStereoSamplesBE(const short* sample_data, u32 count, int sample_rate, - int l_volume, int r_volume) +void WaveFileWriter::AddStereoSamplesBE(const short* sample_data, u32 count, + u32 sample_rate_divisor, int l_volume, int r_volume) { if (!file) ERROR_LOG_FMT(AUDIO, "WaveFileWriter - file not open."); @@ -148,14 +149,14 @@ void WaveFileWriter::AddStereoSamplesBE(const short* sample_data, u32 count, int conv_buffer[2 * i + 1] = conv_buffer[2 * i + 1] * r_volume / 256; } - if (sample_rate != current_sample_rate) + if (sample_rate_divisor != current_sample_rate_divisor) { Stop(); file_index++; std::ostringstream filename; filename << File::GetUserPath(D_DUMPAUDIO_IDX) << basename << file_index << ".wav"; - Start(filename.str(), sample_rate); - current_sample_rate = sample_rate; + Start(filename.str(), sample_rate_divisor); + current_sample_rate_divisor = sample_rate_divisor; } file.WriteBytes(conv_buffer.data(), count * 4); diff --git a/Source/Core/AudioCommon/WaveFile.h b/Source/Core/AudioCommon/WaveFile.h index e95ed8eb73..350e1da9af 100644 --- a/Source/Core/AudioCommon/WaveFile.h +++ b/Source/Core/AudioCommon/WaveFile.h @@ -30,24 +30,28 @@ public: WaveFileWriter(WaveFileWriter&&) = delete; WaveFileWriter& operator=(WaveFileWriter&&) = delete; - bool Start(const std::string& filename, unsigned int HLESampleRate); + bool Start(const std::string& filename, u32 sample_rate_divisor); void Stop(); void SetSkipSilence(bool skip) { skip_silence = skip; } - void AddStereoSamplesBE(const short* sample_data, u32 count, int sample_rate, int l_volume, - int r_volume); // big endian + // big endian + void AddStereoSamplesBE(const short* sample_data, u32 count, u32 sample_rate_divisor, + int l_volume, int r_volume); u32 GetAudioSize() const { return audio_size; } private: static constexpr size_t BUFFER_SIZE = 32 * 1024; - File::IOFile file; - bool skip_silence = false; - u32 audio_size = 0; - std::array conv_buffer{}; void Write(u32 value); void Write4(const char* ptr); + + File::IOFile file; std::string basename; - int current_sample_rate; - int file_index = 0; + u32 file_index = 0; + u32 audio_size = 0; + + u32 current_sample_rate_divisor; + 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 bdcb5d47d6..de7590390e 100644 --- a/Source/Core/Core/HW/AudioInterface.cpp +++ b/Source/Core/Core/HW/AudioInterface.cpp @@ -112,8 +112,8 @@ static u32 s_interrupt_timing = 0; static u64 s_last_cpu_time = 0; static u64 s_cpu_cycles_per_sample = 0; -static u32 s_ais_sample_rate = 48000; -static u32 s_aid_sample_rate = 32000; +static u32 s_ais_sample_rate_divisor = Mixer::FIXED_SAMPLE_RATE_DIVIDEND / 48000; +static u32 s_aid_sample_rate_divisor = Mixer::FIXED_SAMPLE_RATE_DIVIDEND / 32000; void DoState(PointerWrap& p) { @@ -122,8 +122,8 @@ void DoState(PointerWrap& p) p.Do(s_sample_counter); p.Do(s_interrupt_timing); p.Do(s_last_cpu_time); - p.Do(s_ais_sample_rate); - p.Do(s_aid_sample_rate); + p.Do(s_ais_sample_rate_divisor); + p.Do(s_aid_sample_rate_divisor); p.Do(s_cpu_cycles_per_sample); g_sound_stream->GetMixer()->DoState(p); @@ -148,14 +148,15 @@ void Init() s_last_cpu_time = 0; - s_ais_sample_rate = Get48KHzSampleRate(); - s_aid_sample_rate = Get32KHzSampleRate(); - s_cpu_cycles_per_sample = SystemTimers::GetTicksPerSecond() / s_ais_sample_rate; + s_ais_sample_rate_divisor = Get48KHzSampleRateDivisor(); + s_aid_sample_rate_divisor = Get32KHzSampleRateDivisor(); + s_cpu_cycles_per_sample = static_cast(SystemTimers::GetTicksPerSecond()) * + s_ais_sample_rate_divisor / Mixer::FIXED_SAMPLE_RATE_DIVIDEND; event_type_ai = CoreTiming::RegisterEvent("AICallback", Update); - g_sound_stream->GetMixer()->SetDMAInputSampleRate(GetAIDSampleRate()); - g_sound_stream->GetMixer()->SetStreamInputSampleRate(GetAISSampleRate()); + g_sound_stream->GetMixer()->SetDMAInputSampleRateDivisor(GetAIDSampleRateDivisor()); + g_sound_stream->GetMixer()->SetStreamInputSampleRateDivisor(GetAISSampleRateDivisor()); } void Shutdown() @@ -188,9 +189,11 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) DEBUG_LOG_FMT(AUDIO_INTERFACE, "Change AISFR to {}", tmp_ai_ctrl.AISFR ? "48khz" : "32khz"); s_control.AISFR = tmp_ai_ctrl.AISFR; - s_ais_sample_rate = tmp_ai_ctrl.AISFR ? Get48KHzSampleRate() : Get32KHzSampleRate(); - g_sound_stream->GetMixer()->SetStreamInputSampleRate(s_ais_sample_rate); - s_cpu_cycles_per_sample = SystemTimers::GetTicksPerSecond() / s_ais_sample_rate; + s_ais_sample_rate_divisor = + tmp_ai_ctrl.AISFR ? Get48KHzSampleRateDivisor() : Get32KHzSampleRateDivisor(); + g_sound_stream->GetMixer()->SetStreamInputSampleRateDivisor(s_ais_sample_rate_divisor); + s_cpu_cycles_per_sample = static_cast(SystemTimers::GetTicksPerSecond()) * + s_ais_sample_rate_divisor / Mixer::FIXED_SAMPLE_RATE_DIVIDEND; } // Set frequency of DMA if (tmp_ai_ctrl.AIDFR != s_control.AIDFR) @@ -198,8 +201,9 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) DEBUG_LOG_FMT(AUDIO_INTERFACE, "Change AIDFR to {}", tmp_ai_ctrl.AIDFR ? "32khz" : "48khz"); s_control.AIDFR = tmp_ai_ctrl.AIDFR; - s_aid_sample_rate = tmp_ai_ctrl.AIDFR ? Get32KHzSampleRate() : Get48KHzSampleRate(); - g_sound_stream->GetMixer()->SetDMAInputSampleRate(s_aid_sample_rate); + s_aid_sample_rate_divisor = + tmp_ai_ctrl.AIDFR ? Get32KHzSampleRateDivisor() : Get48KHzSampleRateDivisor(); + g_sound_stream->GetMixer()->SetDMAInputSampleRateDivisor(s_aid_sample_rate_divisor); } // Streaming counter @@ -301,24 +305,24 @@ bool IsPlaying() return (s_control.PSTAT == 1); } -u32 GetAIDSampleRate() +u32 GetAIDSampleRateDivisor() { - return s_aid_sample_rate; + return s_aid_sample_rate_divisor; } -u32 GetAISSampleRate() +u32 GetAISSampleRateDivisor() { - return s_ais_sample_rate; + return s_ais_sample_rate_divisor; } -u32 Get32KHzSampleRate() +u32 Get32KHzSampleRateDivisor() { - return SConfig::GetInstance().bWii ? 32000 : 32029; + return Get48KHzSampleRateDivisor() * 3 / 2; } -u32 Get48KHzSampleRate() +u32 Get48KHzSampleRateDivisor() { - return SConfig::GetInstance().bWii ? 48000 : 48043; + return (SConfig::GetInstance().bWii ? 1125 : 1124) * 2; } static void Update(u64 userdata, s64 cycles_late) @@ -339,7 +343,8 @@ static void Update(u64 userdata, s64 cycles_late) int GetAIPeriod() { u64 period = s_cpu_cycles_per_sample * (s_interrupt_timing - s_sample_counter); - u64 s_period = s_cpu_cycles_per_sample * s_ais_sample_rate; + u64 s_period = + s_cpu_cycles_per_sample * Mixer::FIXED_SAMPLE_RATE_DIVIDEND / s_ais_sample_rate_divisor; if (period == 0) return static_cast(s_period); return static_cast(std::min(period, s_period)); diff --git a/Source/Core/Core/HW/AudioInterface.h b/Source/Core/Core/HW/AudioInterface.h index b3799e2140..afab8c769a 100644 --- a/Source/Core/Core/HW/AudioInterface.h +++ b/Source/Core/Core/HW/AudioInterface.h @@ -22,12 +22,13 @@ bool IsPlaying(); void RegisterMMIO(MMIO::Mapping* mmio, u32 base); -// Get the audio rates (48000 or 32000 only) -u32 GetAIDSampleRate(); -u32 GetAISSampleRate(); +// Get the audio rate divisors (divisors for 48KHz or 32KHz only) +// Mixer::FIXED_SAMPLE_RATE_DIVIDEND will be the dividend used for these divisors +u32 GetAIDSampleRateDivisor(); +u32 GetAISSampleRateDivisor(); -u32 Get32KHzSampleRate(); -u32 Get48KHzSampleRate(); +u32 Get32KHzSampleRateDivisor(); +u32 Get48KHzSampleRateDivisor(); void GenerateAISInterrupt(); diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp index bbd1d27e3e..857c6edb91 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp @@ -294,12 +294,16 @@ static u32 AdvanceDTK(u32 maximum_samples, u32* samples_to_process) static void DTKStreamingCallback(DIInterruptType interrupt_type, const std::vector& audio_data, s64 cycles_late) { - // TODO: Should we use GetAISSampleRate instead of a fixed 48 KHz? The audio mixer is using - // GetAISSampleRate. (This doesn't affect any actual games, since they all set it to 48 KHz.) - const u32 sample_rate = AudioInterface::Get48KHzSampleRate(); + // Actual games always set this to 48 KHz + // but let's make sure to use GetAISSampleRateDivisor() + // just in case it changes to 32 KHz + const u32 sample_rate_divisor = AudioInterface::GetAISSampleRateDivisor(); // Determine which audio data to read next. - const u32 maximum_samples = sample_rate / 2000 * 7; // 3.5 ms of samples + + // 3.5 ms of samples + const u32 maximum_samples = + ((Mixer::FIXED_SAMPLE_RATE_DIVIDEND / 2000) * 7) / sample_rate_divisor; u64 read_offset = 0; u32 read_length = 0; @@ -328,7 +332,8 @@ static void DTKStreamingCallback(DIInterruptType interrupt_type, const std::vect } // Read the next chunk of audio data asynchronously. - s64 ticks_to_dtk = SystemTimers::GetTicksPerSecond() * s64(s_pending_samples) / sample_rate; + s64 ticks_to_dtk = SystemTimers::GetTicksPerSecond() * s64(s_pending_samples) * + sample_rate_divisor / Mixer::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 f755345807..54da03092e 100644 --- a/Source/Core/Core/HW/GBACore.cpp +++ b/Source/Core/Core/HW/GBACore.cpp @@ -405,7 +405,8 @@ void Core::SetSampleRates() m_core->setAudioBufferSize(m_core, SAMPLES); blip_set_rates(m_core->getAudioChannel(m_core, 0), m_core->frequency(m_core), SAMPLE_RATE); blip_set_rates(m_core->getAudioChannel(m_core, 1), m_core->frequency(m_core), SAMPLE_RATE); - g_sound_stream->GetMixer()->SetGBAInputSampleRates(m_device_number, SAMPLE_RATE); + g_sound_stream->GetMixer()->SetGBAInputSampleRateDivisors( + m_device_number, Mixer::FIXED_SAMPLE_RATE_DIVIDEND / SAMPLE_RATE); } void Core::AddCallbacks() diff --git a/Source/Core/Core/HW/SystemTimers.cpp b/Source/Core/Core/HW/SystemTimers.cpp index ca96006fa9..00a1fb9f36 100644 --- a/Source/Core/Core/HW/SystemTimers.cpp +++ b/Source/Core/Core/HW/SystemTimers.cpp @@ -48,6 +48,7 @@ IPC_HLE_PERIOD: For the Wii Remote this is the call schedule: #include #include +#include "AudioCommon/Mixer.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" #include "Common/Thread.h" @@ -110,7 +111,8 @@ void DSPCallback(u64 userdata, s64 cyclesLate) int GetAudioDMACallbackPeriod() { // System internal sample rate is fixed at 32KHz * 4 (16bit Stereo) / 32 bytes DMA - return s_cpu_core_clock / (AudioInterface::GetAIDSampleRate() * 4 / 32); + return static_cast(s_cpu_core_clock) * AudioInterface::GetAIDSampleRateDivisor() / + (Mixer::FIXED_SAMPLE_RATE_DIVIDEND * 4 / 32); } void AudioDMACallback(u64 userdata, s64 cyclesLate) diff --git a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp index e09c991419..0862fcba76 100644 --- a/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/Speaker.cpp @@ -145,8 +145,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; - g_sound_stream->GetMixer()->PushWiimoteSpeakerSamples(samples.get(), sample_length, - sample_rate * 2); + g_sound_stream->GetMixer()->PushWiimoteSpeakerSamples( + samples.get(), sample_length, Mixer::FIXED_SAMPLE_RATE_DIVIDEND / (sample_rate * 2)); #ifdef WIIMOTE_SPEAKER_DUMP static int num = 0; diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index f32a57cc18..6f0f84cc21 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -74,7 +74,7 @@ static std::recursive_mutex g_save_thread_mutex; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 143; // Last changed in PR 10784 +constexpr u32 STATE_VERSION = 144; // Last changed in PR 10762 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list,