Code: Select all
'===================================================================================================
' Wave Device Output Copyright (C)2004 Alpha-II Productions
'===================================================================================================
'---------------------------------------------------------------------------------------------------
'MMSYSTEM.H Imports
'
'Visit MSDN for information on the Windows multi-media library:
'
'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_waveform_audio_reference.asp
Const WAVE_FORMAT_PCM As Long = 1&
Const WAVE_MAPPER As Long = -1&
Const WAVE_ALLOWSYNC As Long = &H2
Const WOM_DONE As Long = &H3BD
Const MMSYSERR_NOERROR = 0
Const CALLBACK_FUNCTION = &H30000
Type WAVEFORMATEX 'Wave format chunk
wFormatTag As Integer 'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_waveformatex_str.asp
nChannels As Integer
nSamplesPerSec As Long
nAvgBytesPerSec As Long
nBlockAlign As Integer
wBitsPerSample As Integer
cbSize As Integer
End Type
Type WAVEHDR 'Output buffer header
lpData As Long 'http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_wavehdr_str.asp
dwBufferLength As Long
dwBytesRecorded As Long
dwUser As Long
dwFlags As Long
dwLoops As Long
lpNext As Long
reserved As Long
End Type
Declare Function waveOutOpen Lib "winmm.dll" (lphWaveOut As Long, ByVal uDeviceID As Long, lpFormat As WAVEFORMATEX, ByVal dwCallback As Long, ByVal dwInstance As Long, ByVal dwFlags As Long) As Long
Declare Function waveOutReset Lib "winmm.dll" (ByVal hWaveOut As Long) As Long
Declare Function waveOutClose Lib "winmm.dll" (ByVal hWaveOut As Long) As Long
Declare Function waveOutWrite Lib "winmm.dll" (ByVal hWaveOut As Long, lpWaveOutHdr As WAVEHDR, ByVal uSize As Long) As Long
Declare Function waveOutPrepareHeader Lib "winmm.dll" (ByVal hWaveOut As Long, lpWaveOutHdr As WAVEHDR, ByVal uSize As Long) As Long
Declare Function waveOutUnprepareHeader Lib "winmm.dll" (ByVal hWaveOut As Long, lpWaveOutHdr As WAVEHDR, ByVal uSize As Long) As Long
'===================================================================================================
' Global Data
Private Const SAMPLE_RATE As Long = 32000 'Output sample rate is 32kHz (SNESAPU default)
Private Const BUFSIZE As Long = 3200 '((100 * SAMPLE_RATE) / 1000) = 100ms at 32kHz
Private Handle As Long 'Handle to output device
Private Ready As Boolean 'Output device is ready for data
Private Fmt As WAVEFORMATEX 'Output format
Private Hdr(1) As WAVEHDR 'Headers for output buffers
Private Buffer(BUFSIZE - 1, 1) As Long 'Raw PCM output buffers (16-bit stereo)
'Wave Out Callback
'
'Event handler called by Windows when the output device needs attention
'
'In:
' hwo = Handle to output device
' uMsg = Message being sent
' dwInstance = User defined data (not used in here)
' pWHdr -> Current wave header (if applicable)
' dwParam2 = not used
Private Sub WaveOutDone(ByVal hwo As Long, ByVal uMsg As Long, ByVal dwInstance As Long, ByRef pWHdr As WAVEHDR, ByVal dwParam2 As Long)
If (uMsg = WOM_DONE) And (Ready = True) Then 'We only care if a buffer is through playing and we're ready for data
EmuAPU pWHdr.lpData, pWHdr.dwBufferLength / 4, True 'Emulate SNES APU
waveOutWrite hwo&, pWHdr, Len(pWHdr) 'Send PCM data to output device
End If
End Sub
'Initialize format chunk for sending audio data to the output device
Public Sub WavInit()
Fmt.wFormatTag = WAVE_FORMAT_PCM
Fmt.nChannels = 2
Fmt.nSamplesPerSec = SAMPLE_RATE
Fmt.nAvgBytesPerSec = 2 * (16 / 8) * SAMPLE_RATE
Fmt.nBlockAlign = 2 * (16 / 8)
Fmt.wBitsPerSample = 16
Fmt.cbSize = 0
End Sub
'Close the output device if it's still open
Public Sub WavQuit()
WavClose
End Sub
'Open the output device, prepare the buffers, load the .spc file, and begin sending audio
Public Function WavOpen(file() As Byte) As Boolean
Dim error As Long
If Ready Then
WavOpen = True
Exit Function
End If
'Open audio device
error = waveOutOpen(Handle, -1, Fmt, AddressOf WaveOutDone, 0, WAVE_ALLOWSYNC Or CALLBACK_FUNCTION)
If error = MMSYSERR_NOERROR Then
Ready = True
'Initialize buffers
Hdr(0).dwBufferLength = BUFSIZE * 4
Hdr(0).lpData = VarPtr(Buffer(0, 0))
waveOutPrepareHeader Handle, Hdr(0), Len(Hdr(0))
Hdr(1).dwBufferLength = BUFSIZE * 4
Hdr(1).lpData = VarPtr(Buffer(0, 1))
waveOutPrepareHeader Handle, Hdr(1), Len(Hdr(1))
'Load .spc file into emulator
LoadSPCFile file(0)
'Manually send empty buffer messages to begin output
WaveOutDone Handle, WOM_DONE, 0, Hdr(0), 0
WaveOutDone Handle, WOM_DONE, 0, Hdr(1), 0
Else
Ready = False
MsgBox "Error opening audio device"
End If
WavOpen = Ready
End Function
'Close the output device and release the buffer headers
Public Sub WavClose()
If Ready Then
Ready = False
waveOutReset Handle 'Tell Windows to reset the output device
waveOutUnprepareHeader Handle, Hdr(0), Len(Hdr(0))
waveOutUnprepareHeader Handle, Hdr(1), Len(Hdr(1))
waveOutClose Handle 'Close output device
Handle = 0
End If
End Sub


