gates_of_skeldal/Windows/WaveOut.cpp
2025-01-24 18:27:22 +01:00

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);
}