#include"AudioEngine.h" AudioEngine::AudioEngine() { } AudioEngine::~AudioEngine() { ExitAudioEngine(); delete[] m_audioBuffer1; delete[] m_audioBuffer2; } void AudioEngine::InitAudioEngine() { InitWavFormat(); InitDevice(); InitWavHeader(); InitAudioThread(); } void AudioEngine::ExitAudioEngine() { m_isRunning = false; m_audioThread.join(); waveOutUnprepareHeader(m_hWaveOut, &m_waveHeader1, sizeof(WAVEHDR)); waveOutUnprepareHeader(m_hWaveOut, &m_waveHeader2, sizeof(WAVEHDR)); waveOutClose(m_hWaveOut); } void AudioEngine::SubmitSource(AudioSource* p_audioSource) { if (p_audioSource) { m_audioSource = p_audioSource; } } void AudioEngine::Update(double p_deltaTime) { } MMRESULT AudioEngine::PlayFrontData() { WAVEHDR* m_frontHeader = m_isBuffer1Front ? &m_waveHeader1 : &m_waveHeader2; MMRESULT result = waveOutWrite(m_hWaveOut, m_frontHeader, sizeof(WAVEHDR)); if (result != MMSYSERR_NOERROR) { std::cout << "Failed to write audio data1" << std::endl; return result; } return MMSYSERR_NOERROR; } void AudioEngine::PrepareBackData() { if (!m_audioSource || !m_audioSource->IsActive()) { return; } m_audioSource->PrepareBufferData(); short* backBuffer = (m_isBuffer1Front ? m_audioBuffer2 : m_audioBuffer1); memcpy(backBuffer, m_audioSource->GetBufferData(), sizeof(m_audioBuffer1)); } void AudioEngine::SwapBuffer() { m_isBuffer1Front = !m_isBuffer1Front; } MMRESULT AudioEngine::InitAudioThread() { MMRESULT result = MMSYSERR_NOERROR; m_isRunning = true; m_audioThread = std::thread([&]() { PlayFrontData(); SwapBuffer(); PlayFrontData(); }); if (!m_audioThread.joinable()) { std::cout << "Failed to create audio thread" << std::endl; result = MMSYSERR_ERROR; } return result; } void AudioEngine::InitWavFormat() { m_waveFormat.wFormatTag = WAVE_FORMAT_PCM; m_waveFormat.nChannels = 2; m_waveFormat.nSamplesPerSec = 44100; m_waveFormat.nAvgBytesPerSec = 176400; m_waveFormat.nBlockAlign = 4; m_waveFormat.wBitsPerSample = 16; m_waveFormat.cbSize = 0; } MMRESULT AudioEngine::InitDevice() { MMRESULT result; /*音频设备枚举*/ WAVEOUTCAPS waveOutCaps; for (UINT i = 0; i < waveOutGetNumDevs(); ++i) { waveOutGetDevCaps(i, &waveOutCaps, sizeof(WAVEOUTCAPS)); m_waveOutCaps.push_back(waveOutCaps); std::cout << "Device #" << i << ": " << waveOutCaps.szPname << std::endl; } /*打开默认音频设备*/ //同时设置该设备的回调 result = waveOutOpen(&m_hWaveOut, WAVE_MAPPER, &m_waveFormat, (DWORD_PTR)&AudioEngine::StaticAudioCallback, reinterpret_cast(this), CALLBACK_FUNCTION); if (result != MMSYSERR_NOERROR) { std::cout << "Failed to open audio device" << std::endl; return result; } return MMSYSERR_NOERROR; } void AudioEngine::OnAudioCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { // 在这里处理音频事件 if (uMsg == WOM_DONE) { PrepareBackData(); SwapBuffer(); PlayFrontData(); } } void CALLBACK AudioEngine::StaticAudioCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { // 通过 dwInstance 恢复到实际的 AudioEngine 实例 AudioEngine* audioEngine = reinterpret_cast(dwInstance); if (audioEngine != nullptr) { audioEngine->OnAudioCallback(hwo, uMsg, dwInstance, dwParam1, dwParam2); } } MMRESULT AudioEngine::InitWavHeader() { MMRESULT result; /*header1-initialize*/ m_waveHeader1.lpData = (LPSTR)m_audioBuffer1; m_waveHeader1.dwBufferLength = sizeof(m_audioBuffer1); m_waveHeader1.dwFlags = 0; result = waveOutPrepareHeader(m_hWaveOut, &m_waveHeader1, sizeof(WAVEHDR)); if (result != MMSYSERR_NOERROR) { std::cout << "Failed to prepare audio header1" << std::endl; return result; } /*header2-initialize*/ m_waveHeader2.lpData = (LPSTR)m_audioBuffer2; m_waveHeader2.dwBufferLength = sizeof(m_audioBuffer2); m_waveHeader2.dwFlags = 0; result = waveOutPrepareHeader(m_hWaveOut, &m_waveHeader2, sizeof(WAVEHDR)); if (result != MMSYSERR_NOERROR) { std::cout << "Failed to prepare audio header2" << std::endl; return result; } return MMSYSERR_NOERROR; }