Core/AudioCommon: Move FIXED_SAMPLE_RATE_DIVIDEND from Mixer to AudioInterface.

This commit is contained in:
Jordan Woyak 2025-04-03 14:59:31 -05:00
commit 54e32dec66
10 changed files with 64 additions and 73 deletions

View file

@ -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); constexpr DT_s FADE_OUT_RC = DT_s(0.064);
const u64 out_sample_rate = m_mixer->m_output_sample_rate; 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; const float emulation_speed = m_mixer->m_config_emulation_speed;
if (0 < emulation_speed && emulation_speed != 1.0) 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); m_dma_mixer.PushSamples(samples, num_samples);
if (m_log_dsp_audio) 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(); auto volume = m_dma_mixer.GetVolume();
m_wave_writer_dsp.AddStereoSamplesBE(samples, static_cast<u32>(num_samples), m_wave_writer_dsp.AddStereoSamplesBE(samples, static_cast<u32>(num_samples), sample_rate,
sample_rate_divisor, volume.first, volume.second); 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); m_streaming_mixer.PushSamples(samples, num_samples);
if (m_log_dtk_audio) 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(); auto volume = m_streaming_mixer.GetVolume();
m_wave_writer_dtk.AddStereoSamplesBE(samples, static_cast<u32>(num_samples), m_wave_writer_dtk.AddStereoSamplesBE(samples, static_cast<u32>(num_samples), sample_rate,
sample_rate_divisor, volume.first, volume.second); volume.first, volume.second);
} }
} }
void Mixer::PushWiimoteSpeakerSamples(const s16* samples, std::size_t num_samples, void Mixer::PushWiimoteSpeakerSamples(const s16* samples, std::size_t num_samples, u32 sample_rate)
u32 sample_rate_divisor)
{ {
// Max 20 bytes/speaker report, may be 4-bit ADPCM so multiply by 2 // Max 20 bytes/speaker report, may be 4-bit ADPCM so multiply by 2
static constexpr std::size_t MAX_SPEAKER_SAMPLES = 20 * 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); MAX_SPEAKER_SAMPLES);
if (num_samples <= 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) 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); 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) void Mixer::SetStreamingVolume(u32 lvolume, u32 rvolume)
@ -332,7 +331,7 @@ void Mixer::StartLogDTKAudio(const std::string& filename)
{ {
if (!m_log_dtk_audio) 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) if (success)
{ {
m_log_dtk_audio = true; m_log_dtk_audio = true;
@ -369,7 +368,7 @@ void Mixer::StartLogDSPAudio(const std::string& filename)
{ {
if (!m_log_dsp_audio) 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) if (success)
{ {
m_log_dsp_audio = true; m_log_dsp_audio = true;
@ -411,19 +410,19 @@ void Mixer::RefreshConfig()
void Mixer::MixerFifo::DoState(PointerWrap& p) 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_LVolume);
p.Do(m_RVolume); 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) void Mixer::MixerFifo::SetVolume(u32 lvolume, u32 rvolume)

View file

@ -3,7 +3,6 @@
#pragma once #pragma once
#include <algorithm>
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <bit> #include <bit>
@ -31,16 +30,15 @@ public:
// Called from main thread // Called from main thread
void PushSamples(const s16* samples, std::size_t num_samples); void PushSamples(const s16* samples, std::size_t num_samples);
void PushStreamingSamples(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, void PushWiimoteSpeakerSamples(const s16* samples, std::size_t num_samples, u32 sample_rate);
u32 sample_rate_divisor);
void PushSkylanderPortalSamples(const u8* samples, std::size_t num_samples); 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); void PushGBASamples(std::size_t device_number, const s16* samples, std::size_t num_samples);
u32 GetSampleRate() const { return m_output_sample_rate; } u32 GetSampleRate() const { return m_output_sample_rate; }
void SetDMAInputSampleRateDivisor(u32 rate_divisor); void SetDMAInputSampleRate(u32 sample_rate);
void SetStreamInputSampleRateDivisor(u32 rate_divisor); void SetStreamInputSampleRate(u32 sample_rate);
void SetGBAInputSampleRateDivisors(std::size_t device_number, u32 rate_divisor); void SetGBAInputSampleRate(std::size_t device_number, u32 sample_rate);
void SetStreamingVolume(u32 lvolume, u32 rvolume); void SetStreamingVolume(u32 lvolume, u32 rvolume);
void SetWiimoteSpeakerVolume(u32 lvolume, u32 rvolume); void SetWiimoteSpeakerVolume(u32 lvolume, u32 rvolume);
@ -52,9 +50,6 @@ public:
void StartLogDSPAudio(const std::string& filename); void StartLogDSPAudio(const std::string& filename);
void StopLogDSPAudio(); 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: private:
const std::size_t SURROUND_CHANNELS = 6; const std::size_t SURROUND_CHANNELS = 6;
@ -98,22 +93,21 @@ private:
using Granule = std::array<StereoPair, GRANULE_SIZE>; using Granule = std::array<StereoPair, GRANULE_SIZE>;
public: public:
MixerFifo(Mixer* mixer, u32 sample_rate_divisor, bool little_endian) MixerFifo(Mixer* mixer, u32 sample_rate, bool little_endian)
: m_mixer(mixer), m_input_sample_rate_divisor(sample_rate_divisor), : m_mixer(mixer), m_input_sample_rate(sample_rate), m_little_endian(little_endian)
m_little_endian(little_endian)
{ {
} }
void DoState(PointerWrap& p); void DoState(PointerWrap& p);
void PushSamples(const s16* samples, std::size_t num_samples); void PushSamples(const s16* samples, std::size_t num_samples);
void Mix(s16* samples, std::size_t num_samples); void Mix(s16* samples, std::size_t num_samples);
void SetInputSampleRateDivisor(u32 rate_divisor); void SetInputSampleRate(u32 sample_rate);
u32 GetInputSampleRateDivisor() const; u32 GetInputSampleRate() const;
void SetVolume(u32 lvolume, u32 rvolume); void SetVolume(u32 lvolume, u32 rvolume);
std::pair<s32, s32> GetVolume() const; std::pair<s32, s32> GetVolume() const;
private: private:
Mixer* m_mixer; Mixer* m_mixer;
u32 m_input_sample_rate_divisor; u32 m_input_sample_rate;
bool m_little_endian; bool m_little_endian;
Granule m_next_buffer{}; Granule m_next_buffer{};
@ -141,14 +135,12 @@ private:
void RefreshConfig(); void RefreshConfig();
MixerFifo m_dma_mixer{this, FIXED_SAMPLE_RATE_DIVIDEND / 32000, false}; MixerFifo m_dma_mixer{this, 32000, false};
MixerFifo m_streaming_mixer{this, FIXED_SAMPLE_RATE_DIVIDEND / 48000, false}; MixerFifo m_streaming_mixer{this, 48000, false};
MixerFifo m_wiimote_speaker_mixer{this, FIXED_SAMPLE_RATE_DIVIDEND / 3000, true}; MixerFifo m_wiimote_speaker_mixer{this, 3000, true};
MixerFifo m_skylander_portal_mixer{this, FIXED_SAMPLE_RATE_DIVIDEND / 8000, true}; MixerFifo m_skylander_portal_mixer{this, 8000, true};
std::array<MixerFifo, 4> m_gba_mixers{MixerFifo{this, FIXED_SAMPLE_RATE_DIVIDEND / 48000, true}, std::array<MixerFifo, 4> m_gba_mixers{MixerFifo{this, 48000, true}, MixerFifo{this, 48000, true},
MixerFifo{this, FIXED_SAMPLE_RATE_DIVIDEND / 48000, true}, MixerFifo{this, 48000, true}, MixerFifo{this, 48000, true}};
MixerFifo{this, FIXED_SAMPLE_RATE_DIVIDEND / 48000, true},
MixerFifo{this, FIXED_SAMPLE_RATE_DIVIDEND / 48000, true}};
u32 m_output_sample_rate; u32 m_output_sample_rate;
AudioCommon::SurroundDecoder m_surround_decoder; AudioCommon::SurroundDecoder m_surround_decoder;

View file

@ -7,7 +7,6 @@
#include <fmt/format.h> #include <fmt/format.h>
#include "AudioCommon/Mixer.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/FileUtil.h" #include "Common/FileUtil.h"
#include "Common/IOFile.h" #include "Common/IOFile.h"
@ -16,7 +15,6 @@
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "Common/Swap.h" #include "Common/Swap.h"
#include "Core/Config/MainSettings.h" #include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
constexpr size_t WaveFileWriter::BUFFER_SIZE; constexpr size_t WaveFileWriter::BUFFER_SIZE;
@ -29,7 +27,7 @@ WaveFileWriter::~WaveFileWriter()
Stop(); 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 // Ask to delete file
if (File::Exists(filename)) if (File::Exists(filename))
@ -68,7 +66,7 @@ bool WaveFileWriter::Start(const std::string& filename, u32 sample_rate_divisor)
if (basename.empty()) if (basename.empty())
SplitPath(filename, nullptr, &basename, nullptr); SplitPath(filename, nullptr, &basename, nullptr);
current_sample_rate_divisor = sample_rate_divisor; current_sample_rate = sample_rate;
// ----------------- // -----------------
// Write file header // 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(16); // size of fmt block
Write(0x00020001); // two channels, uncompressed Write(0x00020001); // two channels, uncompressed
const u32 sample_rate = Mixer::FIXED_SAMPLE_RATE_DIVIDEND / sample_rate_divisor;
Write(sample_rate); Write(sample_rate);
Write(sample_rate * 2 * 2); // two channels, 16bit Write(sample_rate * 2 * 2); // two channels, 16bit
@ -117,8 +114,8 @@ void WaveFileWriter::Write4(const char* ptr)
file.WriteBytes(ptr, 4); file.WriteBytes(ptr, 4);
} }
void WaveFileWriter::AddStereoSamplesBE(const short* sample_data, u32 count, void WaveFileWriter::AddStereoSamplesBE(const short* sample_data, u32 count, u32 sample_rate,
u32 sample_rate_divisor, int l_volume, int r_volume) int l_volume, int r_volume)
{ {
if (!file) 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; 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(); Stop();
file_index++; file_index++;
const std::string filename = const std::string filename =
fmt::format("{}{}{}.wav", File::GetUserPath(D_DUMPAUDIO_IDX), basename, file_index); fmt::format("{}{}{}.wav", File::GetUserPath(D_DUMPAUDIO_IDX), basename, file_index);
Start(filename, sample_rate_divisor); Start(filename, sample_rate);
current_sample_rate_divisor = sample_rate_divisor; current_sample_rate = sample_rate;
} }
file.WriteBytes(conv_buffer.data(), count * 4); file.WriteBytes(conv_buffer.data(), count * 4);

View file

@ -30,13 +30,13 @@ public:
WaveFileWriter(WaveFileWriter&&) = delete; WaveFileWriter(WaveFileWriter&&) = delete;
WaveFileWriter& operator=(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 Stop();
void SetSkipSilence(bool skip) { skip_silence = skip; } void SetSkipSilence(bool skip) { skip_silence = skip; }
// big endian // big endian
void AddStereoSamplesBE(const short* sample_data, u32 count, u32 sample_rate_divisor, void AddStereoSamplesBE(const short* sample_data, u32 count, u32 sample_rate, int l_volume,
int l_volume, int r_volume); int r_volume);
u32 GetAudioSize() const { return audio_size; } u32 GetAudioSize() const { return audio_size; }
private: private:
@ -50,7 +50,7 @@ private:
u32 file_index = 0; u32 file_index = 0;
u32 audio_size = 0; u32 audio_size = 0;
u32 current_sample_rate_divisor; u32 current_sample_rate;
std::array<short, BUFFER_SIZE> conv_buffer{}; std::array<short, BUFFER_SIZE> conv_buffer{};
bool skip_silence = false; bool skip_silence = false;

View file

@ -71,8 +71,8 @@ enum
}; };
AudioInterfaceManager::AudioInterfaceManager(Core::System& system) AudioInterfaceManager::AudioInterfaceManager(Core::System& system)
: m_ais_sample_rate_divisor(Mixer::FIXED_SAMPLE_RATE_DIVIDEND / 48000), : m_ais_sample_rate_divisor(FIXED_SAMPLE_RATE_DIVIDEND / 48000),
m_aid_sample_rate_divisor(Mixer::FIXED_SAMPLE_RATE_DIVIDEND / 32000), m_system(system) 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 int AudioInterfaceManager::GetAIPeriod() const
{ {
u64 period = m_cpu_cycles_per_sample * (m_interrupt_timing - m_sample_counter); u64 period = m_cpu_cycles_per_sample * (m_interrupt_timing - m_sample_counter);
u64 s_period = u64 s_period = m_cpu_cycles_per_sample * FIXED_SAMPLE_RATE_DIVIDEND / m_ais_sample_rate_divisor;
m_cpu_cycles_per_sample * Mixer::FIXED_SAMPLE_RATE_DIVIDEND / m_ais_sample_rate_divisor;
if (period == 0) if (period == 0)
return static_cast<int>(s_period); return static_cast<int>(s_period);
return static_cast<int>(std::min(period, s_period)); return static_cast<int>(std::min(period, s_period));
@ -168,7 +167,8 @@ void AudioInterfaceManager::SetAIDSampleRate(SampleRate sample_rate)
} }
SoundStream* sound_stream = m_system.GetSoundStream(); 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) void AudioInterfaceManager::SetAISSampleRate(SampleRate sample_rate)
@ -185,9 +185,10 @@ void AudioInterfaceManager::SetAISSampleRate(SampleRate sample_rate)
} }
m_cpu_cycles_per_sample = static_cast<u64>(m_system.GetSystemTimers().GetTicksPerSecond()) * m_cpu_cycles_per_sample = static_cast<u64>(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(); 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() void AudioInterfaceManager::Init()

View file

@ -23,6 +23,9 @@ class Mapping;
namespace AudioInterface 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 enum class SampleRate
{ {
AI32KHz, AI32KHz,

View file

@ -237,7 +237,7 @@ void DVDInterface::DTKStreamingCallback(DIInterruptType interrupt_type,
// Read the next chunk of audio data asynchronously. // Read the next chunk of audio data asynchronously.
s64 ticks_to_dtk = m_system.GetSystemTimers().GetTicksPerSecond() * s64(m_pending_blocks) * s64 ticks_to_dtk = m_system.GetSystemTimers().GetTicksPerSecond() * s64(m_pending_blocks) *
StreamADPCM::SAMPLES_PER_BLOCK * sample_rate_divisor / StreamADPCM::SAMPLES_PER_BLOCK * sample_rate_divisor /
Mixer::FIXED_SAMPLE_RATE_DIVIDEND; AudioInterface::FIXED_SAMPLE_RATE_DIVIDEND;
ticks_to_dtk -= cycles_late; ticks_to_dtk -= cycles_late;
if (read_length > 0) if (read_length > 0)
{ {

View file

@ -407,8 +407,7 @@ void Core::SetSampleRates()
blip_set_rates(m_core->getAudioChannel(m_core, 1), m_core->frequency(m_core), SAMPLE_RATE); blip_set_rates(m_core->getAudioChannel(m_core, 1), m_core->frequency(m_core), SAMPLE_RATE);
SoundStream* sound_stream = m_system.GetSoundStream(); SoundStream* sound_stream = m_system.GetSoundStream();
sound_stream->GetMixer()->SetGBAInputSampleRateDivisors( sound_stream->GetMixer()->SetGBAInputSampleRate(m_device_number, SAMPLE_RATE);
m_device_number, Mixer::FIXED_SAMPLE_RATE_DIVIDEND / SAMPLE_RATE);
} }
void Core::AddCallbacks() void Core::AddCallbacks()

View file

@ -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 // System internal sample rate is fixed at 32KHz * 4 (16bit Stereo) / 32 bytes DMA
return static_cast<u64>(cpu_core_clock) * aid_sample_rate_divisor / return static_cast<u64>(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) void SystemTimersManager::AudioDMACallback(Core::System& system, u64 userdata, s64 cycles_late)

View file

@ -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). // ADPCM sample rate is thought to be x2.(3000 x2 = 6000).
const unsigned int sample_rate = sample_rate_dividend / reg_data.sample_rate; const unsigned int sample_rate = sample_rate_dividend / reg_data.sample_rate;
sound_stream->GetMixer()->PushWiimoteSpeakerSamples( sound_stream->GetMixer()->PushWiimoteSpeakerSamples(samples.data(), sample_length,
samples.data(), sample_length, Mixer::FIXED_SAMPLE_RATE_DIVIDEND / (sample_rate * 2)); sample_rate * 2);
} }
void SpeakerLogic::Reset() void SpeakerLogic::Reset()