VST Hosting: processing a .wav-file
Posted: Sat Jun 10, 2006 11:24 pm
I am trying to make a VST host that will use a VST plugin to process a 44100, 16 bit, stereo .wav-file. However, when I call the plugin's standard method 'processReplacing()' the file does not seem to get processed correctly - with some plugins the sound gets distorted, with others processReplacing() never returns.
Can anybody see what I am doing wrong in the following code? (to run the code you need directx 8, a 2-input VST plugin and a 44100, 16 bit stereo .wav-file)
Can anybody see what I am doing wrong in the following code? (to run the code you need directx 8, a 2-input VST plugin and a 44100, 16 bit stereo .wav-file)
Code: Select all
#DSBLOCK_ENTIREBUFFER = $2
#audioMasterVersion = 1
Enumeration
#effOpen
#effClose
#effSetProgram
#effGetProgram
#effSetProgramName
#effGetProgramName
#effGetParamLabel
#effGetParamDisplay
#effGetParamName
#effGetVu
#effSetSampleRate
#effSetBlockSize
#effMainsChanged
#effEditGetRect
#effEditOpen
#effEditClose
#effEditDraw
#effEditMouse
#effEditKey
#effEditIdle
#effEditTop
#effEditSleep
#effIdentify
#effGetChunk
#effSetChunk
#effNumOpcodes
EndEnumeration
Structure DSBUFFERDESC
dwSize.l
dwFlags.l
dwBufferBytes.l
dwReserved.l
*lpwfxFormat
guid3DAlgorithm.GUID
EndStructure
Structure AEffect
magic.l
dispatcher.l
process.l
setParameter.l
getParameter.l
numPrograms.l
numParams.l
numInputs.l
numOutputs.l
flags.l
resvd1.l
resvd2.l
initialDelay.l
realQualities.l
offQualities.l
ioRatio.f
object.l
user.l
uniqueID.l
version.l
processReplacing.l
future.b[60]
EndStructure
Structure WAVEFORMATEX
wFormatTag.w
nChannels.w
nSamplesPerSec.l
nAvgBytesPerSec.l
nBlockAlign.w
wBitsPerSample.w
cbSize.w
EndStructure
Structure WAVDATA
mem.l
size.l
EndStructure
Procedure.l GetWavHeader(*wavfmt.WAVEFORMATEX, filename.s)
Protected fmtSize.l
If ReadFile(0, filename)
If ReadLong(0) <> 'FFIR' : ProcedureReturn #False : EndIf
ReadLong(0)
If ReadLong(0) <> 'EVAW' : ProcedureReturn #False : EndIf
While ReadLong(0) <> ' tmf' And Eof(0) = #False
FileSeek(0, Loc(0)-3)
Wend
fmtSize = ReadLong(0)
*wavfmt\wFormatTag = ReadWord(0)
*wavfmt\nChannels = ReadWord(0)
*wavfmt\nSamplesPerSec = ReadLong(0)
*wavfmt\nAvgBytesPerSec = ReadLong(0)
*wavfmt\nBlockAlign = ReadWord(0)
*wavfmt\wBitsPerSample = ReadWord(0)
If fmtSize > 16
*wavfmt\cbSize = ReadWord(0)
Else
*wavfmt\cbSize = 0
EndIf
CloseFile(0)
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure.l GetWAVData(*wavdata.WAVDATA, filename.s)
If ReadFile(0, filename)
While ReadLong(0) <> 'atad' And Eof(0) = #False
FileSeek(0, Loc(0)-3)
Wend
*wavdata\size = ReadLong(0)
*wavdata\mem = AllocateMemory(*wavdata\size)
ReadData(0, *wavdata\mem, *wavdata\size)
CloseFile(0)
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
Procedure Host(*effect.AEffect, opcode.l, index.l, Value.l, *ptr.l, opt.f)
Select opcode
Case #audioMasterVersion
r = 2
EndSelect
ProcedureReturn r
EndProcedure
If OpenLibrary(0, "dsound.dll") And OpenLibrary(1, "phaser.dll") And GetWavHeader(wavFormat.WAVEFORMATEX, "drumloop2.wav") And GetWavData(wavData.WAVDATA, "drumloop2.wav")
hwnd = OpenWindow(0,0,0,800,400,"Sound", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
CallFunction(0,"DirectSoundCreate8",0,@dsound.IDirectSound8,0)
dsound\SetCooperativeLevel(hwnd,1)
desc.DSBUFFERDESC\dwSize = SizeOf(DSBUFFERDESC)
desc\dwBufferBytes = wavData\size
desc\lpwfxFormat = @wavFormat
dsound\CreateSoundBuffer(@desc,@dsb.IDirectSoundBuffer,0)
sampleFrames = wavData\size / 4
*effect.AEffect = CallFunction(1, "main", @Host())
CallFunctionFast(*effect\dispatcher, *effect, #effOpen, 0, 0, #Null, 0.0)
CallFunctionFast(*effect\dispatcher, *effect, #effMainsChanged, 0, 0, #Null, 0.0)
CallFunctionFast(*effect\dispatcher, *effect, #effSetSampleRate, 0, 0, #Null, 44100)
CallFunctionFast(*effect\dispatcher, *effect, #effSetBlockSize, 0, sampleFrames, #Null, 0.0)
CallFunctionFast(*effect\dispatcher, *effect, #effMainsChanged, 0, 1, #Null, 0.0)
Dim in.l(1)
Dim leftIn.f(sampleFrames-1)
Dim rightIn.f(sampleFrames-1)
m = wavData\mem
For i = 0 To sampleFrames-1
leftIn(i) = PeekW(m)/32768
rightIn(i) = PeekW(m+2)/32768
m + 4
Next
in(0) = leftIn()
in(1) = rightIn()
Dim out.l(1)
Dim leftOut.f(sampleFrames-1)
Dim rightOut.f(sampleFrames-1)
out(0) = leftOut()
out(1) = rightOut()
CallFunctionFast(*effect\processReplacing, *effect, in(), out(), sampleFrames)
processedWavData = AllocateMemory(wavData\size)
m = processedWavData
For i = 0 To sampleFrames-1
PokeW(m, leftOut(i) * 32768)
PokeW(m+2, rightOut(i) * 32768)
m + 4
Next
dsb\Lock(0,0,@m,@len,0,0,#DSBLOCK_ENTIREBUFFER)
CopyMemory(processedWavData,m,len)
dsb\UnLock(m,len,0,0)
dsb\Play(0, 0, 0)
FreeMemory(processedWavData)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
CallFunctionFast(*effect\dispatcher, *effect, #effMainsChanged, 0, 0, #Null, 0.0)
CallFunctionFast(*effect\dispatcher, *effect, #effClose, 0, 0, #Null, 0.0)
dsb\Stop()
dsb\Release()
dsound\Release()
CloseLibrary(1)
CloseLibrary(0)
Else
MessageRequester("Error","Can't find VST plugin and/or .wav-file.",0)
EndIf