Code: Select all
#include "Windows.bi"
#Include Once "crt/string.bi"
#include "win/mmsystem.bi"
#define WAVE_MAPPER -1
dim shared _hWaveOut as HWAVEOUT
dim shared cs as CRITICAL_SECTION
type QueueWAVEHDR
_wavehdr as WAVEHDR
_next as QueueWAVEHDR ptr
end type
dim shared doneWaveHdrs as QueueWAVEHDR ptr
dim shared waitingBytes as integer
sub dsp_callback StdCall (_hWaveOut as HWAVEOUT, msg as UINT, instance as DWORD, p1 as DWORD, p2 as DWORD)
if msg = WOM_DONE then
dim p as QueueWAVEHDR ptr
p = cast(QueueWAVEHDR ptr, p1)
EnterCriticalSection(@cs)
p->_next = doneWaveHdrs
doneWaveHdrs = p
LeaveCriticalSection(@cs)
end if
end sub
sub clean_unprepares()
EnterCriticalSection(@cs)
do while (doneWaveHdrs)
dim p as QueueWAVEHDR ptr
p = doneWaveHdrs
doneWaveHdrs = p->_next
waitingBytes -= p->_wavehdr.dwBufferLength
waveOutUnprepareHeader(_hWaveOut, @p->_wavehdr, sizeof(WAVEHDR))
deallocate(p->_wavehdr.lpData)
deallocate(p)
loop
LeaveCriticalSection(@cs)
end sub
sub dsp_finalize()
if _hWaveOut then
waveOutPause(_hWaveOut)
waveOutReset(_hWaveOut)
clean_unprepares()
waveOutClose(_hWaveOut)
_hWaveOut = NULL
DeleteCriticalSection(@cs)
end if
end sub
sub SoundSet(frequency as integer, channels as integer, bits as integer)
dim as WAVEFORMATEX wfx
dsp_finalize()
memset(@wfx, 0, sizeof(wfx))
wfx.wFormatTag = WAVE_FORMAT_PCM
wfx.nChannels = channels
wfx.nSamplesPerSec = frequency
wfx.wBitsPerSample = bits
wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8
wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec
wfx.cbSize = 0
if waveOutOpen(@_hWaveOut, WAVE_MAPPER, @wfx, cast(DWORD, @dsp_callback), 0, CALLBACK_FUNCTION) <> MMSYSERR_NOERROR then
_hWaveOut = NULL
else
waveOutRestart(_hWaveOut)
InitializeCriticalSection(@cs)
end if
end sub
sub playbuffer (soundBuffer as any ptr, buffersize as integer)
if _hWaveOut then
dim p as WAVEHDR ptr = allocate(sizeof(QueueWAVEHDR))
memset(p, 0, sizeof(WAVEHDR))
p->lpData = allocate(buffersize)
if p->lpData=0 then
deallocate(p)
else
memcpy(p->lpData, SoundBuffer, buffersize)
p->dwBufferLength = buffersize: p->dwBytesRecorded = buffersize
waveOutPrepareHeader(_hWaveOut, p, sizeof(WAVEHDR))
if waveOutWrite(_hWaveOut, p, sizeof(WAVEHDR)) = MMSYSERR_NOERROR then
waitingBytes += p->dwBufferLength
else
waveOutUnprepareHeader(_hWaveOut, p, sizeof(WAVEHDR))
deallocate(p->lpData)
deallocate(p)
end if
end if
clean_unprepares()
end if
end sub
Here is an example:
Code: Select all
Dim MyBuffer(200000) as short
SoundSet 44100,2,16
dim i2 as integer
for a as integer=0 to 80
for i as integer=1 to 512*4 step 2
i2=i2+1
MyBuffer(i)= (i2 mod 20)*i2/10
MyBuffer(i+1)= (i2 mod 20)*i2/10
next
playbuffer @MyBuffer(0),1024*4
next
sleep