#include "framework.h"
#include <mmreg.h>
#include <mmdeviceapi.h>
#include <Audioclient.h>
#include <iostream>
#include <iomanip>
#include <chrono>
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <commdlg.h>
#include <CommCtrl.h>
#include <combaseapi.h>
#include <ShObjIdl_core.h>
#include "Shlwapi.h"
#include <Shlobj.h>
#define REFTIMES_PER_SEC 5000000
#define REFTIMES_PER_MILLISEC 10000
#define EXIT_ON_ERROR(hres) if (FAILED(hres)) {MessageBox(NULL,L"失败",L"fail",MB_OK); goto Exit; }
#define SAFE_RELEASE(punk) if ((punk) != NULL){ (punk)->Release(); (punk)=NULL;}
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
const IID IID_IAudioClient = __uuidof(IAudioClient);
const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
extern bool audio_play;
extern HANDLE pause_music;
extern HANDLE pauseEvent;
extern BYTE* PCM;
HRESULT PlayAudio(INT16 *wav_buf, LONG64 dataSize)
{
int sk = 0;
HRESULT hr;
IMMDevice* pDevice;
IMMDeviceEnumerator* pEnumerator = NULL;
IAudioClient* pAudioClient = NULL;
IAudioRenderClient* pRenderClient = NULL;
REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
UINT32 bufferSizeInFrames;
DWORD initStreamFlags = (AUDCLNT_STREAMFLAGS_RATEADJUST | AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM | AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY);
WAVEFORMATEX pwfx;
INT16* pData = NULL;
IAudioClock* audioClock;
UINT64 audioPlaybackFreq;
UINT64 audioPlaybackPos;
UINT64 audioPlaybackPosInSeconds;
UINT64 audioPlaybackPosInSamples;
UINT32 wavPlaybackSample = 0;
UINT32 bufferPadding;
UINT32 soundBufferLatency;
UINT32 numFramesToWrite;
int read = 0, n = 0;
UINT32 numWavSamples = dataSize / (2 * sizeof(UINT16));
DWORD num = 0;
//申请内存
UINT16* dataCache = new UINT16[dataSize / 2];
CopyMemory(dataCache,wav_buf, dataSize );
free(wav_buf);
hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&pEnumerator);
EXIT_ON_ERROR(hr);
hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
EXIT_ON_ERROR(hr);
hr = pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pAudioClient);
EXIT_ON_ERROR(hr);
hr = SetFormat(&pwfx);
EXIT_ON_ERROR(hr);
hr = pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, initStreamFlags, hnsRequestedDuration * 40, 0, &pwfx, NULL);
EXIT_ON_ERROR(hr);
hr = pAudioClient->GetService(__uuidof(IAudioRenderClient), (LPVOID*)(&pRenderClient));
EXIT_ON_ERROR(hr);
hr = pAudioClient->GetBufferSize(&bufferSizeInFrames);
EXIT_ON_ERROR(hr);
hr = pAudioClient->Start();
EXIT_ON_ERROR(hr);
while(read < dataSize/2)
{
hr = pAudioClient->GetCurrentPadding(&bufferPadding);
EXIT_ON_ERROR(hr);
soundBufferLatency = bufferSizeInFrames / 50;
numFramesToWrite = soundBufferLatency - bufferPadding;
hr = pRenderClient->GetBuffer(numFramesToWrite, (BYTE**)(&pData));
EXIT_ON_ERROR(hr);
for (int i = 0; i < numFramesToWrite; i++)
{
pData[2 * i] = dataCache[sk++];
pData[2 * i + 1] = dataCache[sk++];
read = read + 2;
}
hr = pRenderClient->ReleaseBuffer(numFramesToWrite, 0);
EXIT_ON_ERROR(hr);
hr = pAudioClient->GetService(__uuidof(IAudioClock), (LPVOID*)(&audioClock));
EXIT_ON_ERROR(hr);
audioClock->GetFrequency(&audioPlaybackFreq);
audioClock->GetPosition(&audioPlaybackPos, 0);
audioClock->Release();
audioPlaybackPosInSeconds = audioPlaybackPos / audioPlaybackFreq;
audioPlaybackPosInSamples = audioPlaybackPosInSeconds * 44100;
}
Exit: pAudioClient->Stop();
pAudioClient->Release();
pRenderClient->Release();
delete[]dataCache;
return 0;
}
int SetFormat(WAVEFORMATEX* wfex)
{
wfex->wFormatTag = 1;
wfex->nChannels = 2;
wfex->cbSize = 0;
wfex->nSamplesPerSec = 44100;
wfex->nAvgBytesPerSec = 44100 * 2 * 2;
wfex->wBitsPerSample = 16;
wfex->nBlockAlign = 4;
return 0;
}
最简单的WASAPI播放音乐代码
于 2021-11-05 20:39:56 首次发布