mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-05 06:00:33 -04:00
157 lines
3 KiB
C++
157 lines
3 KiB
C++
// WaveOut.cpp: implementation of the WaveOut class.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "WaveOut.h"
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Construction/Destruction
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
WaveOut::WaveOut()
|
|
{
|
|
_device=0;
|
|
}
|
|
|
|
WaveOut::~WaveOut()
|
|
{
|
|
if (_device) Close();
|
|
}
|
|
|
|
|
|
int WaveOut::Open(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms)
|
|
{
|
|
MSG msg;
|
|
PeekMessage(&msg,0,0,0,0); //ensure message queue created
|
|
_paused=false;
|
|
_wrpos=0;
|
|
_pending=0;
|
|
memset(_buffers,0,sizeof(_buffers));
|
|
_played=0;
|
|
_written=0;
|
|
|
|
WAVEFORMATEX format;
|
|
format.cbSize=sizeof(format);
|
|
format.nChannels=numchannels;
|
|
format.nSamplesPerSec=samplerate;
|
|
format.nAvgBytesPerSec=numchannels*samplerate*(bitspersamp/8);
|
|
format.nBlockAlign=numchannels*(bitspersamp/8);
|
|
format.wBitsPerSample=bitspersamp;
|
|
format.wFormatTag=WAVE_FORMAT_PCM;
|
|
_event=CreateEvent(NULL,FALSE,FALSE,NULL);
|
|
_persec=format.nAvgBytesPerSec;
|
|
MMRESULT res=waveOutOpen(&_device,WAVE_MAPPER,&format,(DWORD)_event,(DWORD)this,CALLBACK_EVENT);
|
|
if (res==MMSYSERR_NOERROR) return 0;
|
|
return -1;
|
|
}
|
|
|
|
void WaveOut::Close()
|
|
{
|
|
Flush(1);
|
|
waveOutClose(_device);
|
|
_device=0;
|
|
|
|
}
|
|
|
|
int WaveOut::NextBuffer()
|
|
{
|
|
int b=_wrpos;
|
|
printf("Buffers: %5d time: %d\r",_pending,GetOutputTime()/1000);
|
|
if (_buffers[_wrpos]==0 || (_buffers[_wrpos]->dwFlags & WHDR_DONE))
|
|
{
|
|
if (_buffers[_wrpos])
|
|
{
|
|
waveOutUnprepareHeader(_device,_buffers[_wrpos],sizeof(*_buffers[_wrpos]));
|
|
free(_buffers[_wrpos]->lpData);
|
|
_played+=_buffers[_wrpos]->dwBufferLength;
|
|
delete _buffers[_wrpos];
|
|
_buffers[_wrpos]=0;
|
|
_pending--;
|
|
}
|
|
_wrpos++;
|
|
if (_wrpos>=MAXBUFFERS) _wrpos=0;
|
|
return b;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
|
|
int WaveOut::Write(const char *buf, int len)
|
|
{
|
|
int pos=NextBuffer();
|
|
while (pos==-1)
|
|
{
|
|
WaitForSingleObject(_event,INFINITE);
|
|
pos=NextBuffer();
|
|
}
|
|
WAVEHDR *hdr=new WAVEHDR;
|
|
memset(hdr,0,sizeof(*hdr));
|
|
hdr->dwBufferLength=len;
|
|
hdr->lpData=(char *)malloc(len);
|
|
memcpy(hdr->lpData,buf,len);
|
|
waveOutPrepareHeader(_device,hdr,sizeof(*hdr));
|
|
waveOutWrite(_device,hdr,sizeof(*hdr));
|
|
_buffers[pos]=hdr;
|
|
_pending++;
|
|
_written+=len;
|
|
return 0;
|
|
}
|
|
|
|
int WaveOut::CanWrite()
|
|
{
|
|
return _paused?0:16*1024*1024;
|
|
}
|
|
|
|
int WaveOut::IsPlaying()
|
|
{
|
|
while (_pending)
|
|
{
|
|
if (NextBuffer()==-1) return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int WaveOut::Pause(int pause)
|
|
{
|
|
bool waspaused=_paused;
|
|
if (pause)
|
|
{
|
|
if (!waspaused) waveOutPause(_device);
|
|
_paused=true;
|
|
}
|
|
else
|
|
{
|
|
if (waspaused) waveOutRestart(_device);
|
|
_paused=false;
|
|
}
|
|
return waspaused?1:0;
|
|
}
|
|
|
|
void WaveOut::SetVolume(int volume)
|
|
{
|
|
|
|
}
|
|
|
|
void WaveOut::SetPan(int pan)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
void WaveOut::Flush(int t)
|
|
{
|
|
waveOutReset(_device);
|
|
while (_pending) NextBuffer();
|
|
}
|
|
|
|
|
|
int WaveOut::GetOutputTime()
|
|
{
|
|
return (int)((__int64)_played*(__int64)1000/(__int64)_persec);
|
|
}
|
|
|
|
int WaveOut::GetWrittenTime()
|
|
{
|
|
return (int)((__int64)_played*(__int64)1000/(__int64)_persec);
|
|
}
|