📄 mmaudio.h
字号:
#ifndef _MM_AUDIO_H
#define _MM_AUDIO_H
#include "mmsystem.h"
#include "atlbase.h"
#pragma comment(lib,"winmm.lib")
//////////////////////////////////////////////////////////////////////////
class mmaudio
{
enum {block = 2048};
enum {buffer_count=2};
HWAVEOUT h;
int ch;
int sr;
int bits;
WAVEFORMATEX wfx;
WAVEHDR wh[buffer_count];
bool used[buffer_count];
byte* buffers[buffer_count];
// volatile bool playing;
HANDLE evt;
CComAutoCriticalSection cs;
int handle;
void unprepare()
{
//while( playing )
// Sleep(1);
MMRESULT res = 0;
//if( wh[handle].dwFlags & WHDR_PREPARED )
res = waveOutPrepareHeader(h, &wh[handle], sizeof(WAVEHDR));
}
bool play()
{
MMRESULT res = 0;
res = waveOutPrepareHeader(h, &wh[handle], sizeof(WAVEHDR));
MMSYSERR_INVALHANDLE;
WAVERR_UNPREPARED;
//WaitForSingleObject(evt, INFINITE);
res = waveOutWrite(h, &wh[handle], sizeof(WAVEHDR));
used[handle] = false;
if( res )
TRACE("[res]: %lx\n", res);
// handle++;
// handle %= buffer_count;
return true;
}
byte* get_buffer()
{
cs.Lock();
for( int i=0; i<buffer_count; i++ )
if( !used[i] )
{
handle = i;
used[i] = true;
cs.Unlock();
return buffers[i];
}
cs.Unlock();
return NULL;
}
public:
mmaudio():h(NULL), evt(NULL), handle(0)
{
memset(buffers, 0, buffer_count*sizeof(byte*));
memset(used, false, buffer_count*sizeof(byte));
}
~mmaudio(){destroy();}
operator HWAVEOUT()
{
return h;
}
void destroy()
{
if( h )
{
waveOutReset(h);
waveOutClose(h);
h = NULL;
}
if( evt )
{
CloseHandle(evt);
evt = NULL;
}
for( int i=0; i<buffer_count; i++ )
{
delete[] buffers[i];
buffers[i] = NULL;
}
handle = 0;
}
bool create(int channels, int sample_rate, WORD bits_per_sample)
{
if( !evt )
evt = CreateEvent(NULL, TRUE, FALSE, NULL);
ch = channels;
sr = sample_rate;
bits = bits_per_sample;
MMRESULT res = 0;
res = waveOutGetNumDevs();
if( res == 0 )
return false; // no audio device found
WAVEOUTCAPS caps;
res = waveOutGetDevCaps(0, &caps, sizeof(WAVEOUTCAPS));
ZeroMemory(&wfx, sizeof(WAVEFORMATEX));
wfx.cbSize = sizeof(wfx);
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = channels;
wfx.nSamplesPerSec = sample_rate;
wfx.wBitsPerSample = bits_per_sample;
wfx.nAvgBytesPerSec = sample_rate * channels * bits_per_sample/8;
wfx.nBlockAlign = channels * bits_per_sample/8;
res = waveOutOpen(&h, 0, &wfx, (DWORD)evt, (DWORD)this, CALLBACK_EVENT);
if( res )
return false;
for( int i=0; i<buffer_count; i++ )
{
ZeroMemory(&wh[i], sizeof(WAVEHDR));
wh[i].dwBufferLength = block*bits/8;
wh[i].dwFlags = 0;
wh[i].dwLoops = 0;
buffers[i] = new byte [block*bits/8];
wh[i].lpData = (LPSTR)buffers[i];
}
SetEvent(evt);
return true;
}
void put_data(byte* buf, int size)
{
unprepare();
memcpy(get_buffer(), buf, size);
play();
}
};
#endif // _MM_AUDIO_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -