自己改的代码播放不了,应该是怎样的
#include "stdafx.h"
#include
#include
#define REFTIMES_PER_SEC 10000000
#define REFTIMES_PER_MILLISEC 10000
#define EXIT_ON_ERROR(hres) \
if (FAILED(hres)) { printf("error\n");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);
class MyAudioSource {
public:
//WAVEFORMATEX *pwfx = NULL;
int SetFormat(WAVEFORMATEX *pwfx);
int LoadData(UINT32 num, BYTE * pData, DWORD *flags);
};
int MyAudioSource::SetFormat(WAVEFORMATEX *pwfx)
{
printf("wFormatTag is %x\n", pwfx->wFormatTag); //格式类型
printf("nChannels is %x\n", pwfx->nChannels); //声道数(即单声道,立体声)
printf("nSamplesPerSec is %d\n", pwfx->nSamplesPerSec); //采样率
printf("nAvgBytesPerSec is %d\n", pwfx->nAvgBytesPerSec); //用于缓冲区估计
printf("wBitsPerSample is %d\n", pwfx->wBitsPerSample); //单声道数据样本的位数
BOOL bRet(FALSE);
if (pwfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT)
{
printf("WAVE_FORMAT_IEEE_FLOAT\n");
pwfx->wFormatTag = WAVE_FORMAT_PCM;
pwfx->wBitsPerSample = 16;
pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
bRet = TRUE;
}
else if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
{
printf("WAVE_FORMAT_EXTENSIBLE\n");
PWAVEFORMATEXTENSIBLE pEx = reinterpret_cast<PWAVEFORMATEXTENSIBLE>(pwfx);
if (IsEqualGUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, pEx->SubFormat))
{
pEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
pEx->Samples.wValidBitsPerSample = 16; //位精度
pwfx->wBitsPerSample = 16;
pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8; //数据块大小
pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec; //用于缓冲区估计
bRet = TRUE;
}
}
return bRet;
}
int MyAudioSource::LoadData(UINT32 num, BYTE * pData, DWORD *flags)
{
char *fBuffer = new char[num];
FILE *fp;
fp = fopen("paomo.pcm", "r");
if (fp == NULL)
{
printf("文件打开失败");
return 0;
}
if (pData != NULL)
{
fread(fBuffer, num, 1, fp);
memcpy(pData, fBuffer, num);
printf("num:%d\n", num);
}
return 0;
}
HRESULT PlayAudioStream(MyAudioSource *pMySource)
{
HRESULT hr;
REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
REFERENCE_TIME hnsActualDuration;
IMMDeviceEnumerator *pEnumerator = NULL;
IMMDevice *pDevice = NULL;
IAudioClient *pAudioClient = NULL;
IAudioRenderClient *pRenderClient = NULL;
WAVEFORMATEX *pwfx = NULL;
UINT32 bufferFrameCount;
UINT32 numFramesAvailable;
UINT32 numFramesPadding;
BYTE *pData;
DWORD flags = 0;
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 = pAudioClient->GetMixFormat(&pwfx);
EXIT_ON_ERROR(hr)
hr = pAudioClient->Initialize(
AUDCLNT_SHAREMODE_SHARED,
0,
hnsRequestedDuration,
0,
pwfx,
NULL);
EXIT_ON_ERROR(hr)
// Tell the audio source which format to use.
hr = pMySource->SetFormat(pwfx);
EXIT_ON_ERROR(hr)
// Get the actual size of the allocated buffer.
hr = pAudioClient->GetBufferSize(&bufferFrameCount);
EXIT_ON_ERROR(hr)
hr = pAudioClient->GetService(
IID_IAudioRenderClient,
(void**)&pRenderClient);
EXIT_ON_ERROR(hr)
// Grab the entire buffer for the initial fill operation.
hr = pRenderClient->GetBuffer(bufferFrameCount, &pData);
EXIT_ON_ERROR(hr)
// Load the initial data into the shared buffer.
hr = pMySource->LoadData(bufferFrameCount, pData, &flags);
EXIT_ON_ERROR(hr)
hr = pRenderClient->ReleaseBuffer(bufferFrameCount, flags);
EXIT_ON_ERROR(hr)
// Calculate the actual duration of the allocated buffer.
hnsActualDuration = (double)REFTIMES_PER_SEC *
bufferFrameCount / pwfx->nSamplesPerSec;
hr = pAudioClient->Start(); // Start playing.
EXIT_ON_ERROR(hr)
// Each loop fills about half of the shared buffer.
while (flags != AUDCLNT_BUFFERFLAGS_SILENT)
{
// Sleep for half the buffer duration.
Sleep((DWORD)(hnsActualDuration / REFTIMES_PER_MILLISEC / 2));
// See how much buffer space is available.
hr = pAudioClient->GetCurrentPadding(&numFramesPadding);
EXIT_ON_ERROR(hr)
numFramesAvailable = bufferFrameCount - numFramesPadding;
// Grab all the available space in the shared buffer.
hr = pRenderClient->GetBuffer(numFramesAvailable, &pData);
EXIT_ON_ERROR(hr)
// Get next 1/2-second of data from the audio source.
hr = pMySource->LoadData(numFramesAvailable, pData, &flags);
EXIT_ON_ERROR(hr)
hr = pRenderClient->ReleaseBuffer(numFramesAvailable, flags);
EXIT_ON_ERROR(hr)
}
// Wait for last data in buffer to play before stopping.
Sleep((DWORD)(hnsActualDuration / REFTIMES_PER_MILLISEC / 2));
hr = pAudioClient->Stop(); // Stop playing.
EXIT_ON_ERROR(hr)
Exit:
CoTaskMemFree(pwfx);
SAFE_RELEASE(pEnumerator)
SAFE_RELEASE(pDevice)
SAFE_RELEASE(pAudioClient)
SAFE_RELEASE(pRenderClient)
return hr;
}
int main()
{
CoInitialize(NULL);
MyAudioSource test;
PlayAudioStream(&test);
return 0;
}