0
0

Where is dspfx.dll? Old one from FMOD 3.6.3 just gives an access violation with FMOD 3.7.0! Or how can I do my own dsp unit with VB without using a dll?

  • You must to post comments
0
0

I had a problem with access violtations before as well, try removing byval from your CopyMemory call.

  • You must to post comments
0
0

Well, now VB just terminates. No exception. There must be ByVal in code, and you must copymemory to newbuffer. But i think that it will need more than just DataS(i)=DataS(i)+10. Line DataS(i)=32767 will do the spectrum static with first 2 spectrum arrays of value 1 and lowers constantly. Maybe i just cant add 10 to every frequency -so 10 to DataS(0), 9.8 to DataS(1) and so on.

  • You must to post comments
0
0

So i was playing a little with dsp callbacks. I wrote a dsp unit in VB. You can take a look at it(if you want). Follow theese:
1)Put 2 commandbuttons on the form. Leave names as original.
2)Put 2 textboxes to form. Also do not change the names.
3)Put 1 checkbox to form – Check1
Paste the following code to form’s1 code window:
[code:1k5atq25]Private Sub Command1_Click()
‘Dim drv As Long
‘drv = FSOUND_GetDriver
‘FSOUND_SetDriver -1
‘MsgBox drv
Call FSOUND_Init(44100, 32, FSOUND_INIT_GLOBALFOCUS) ‘init
StrH = FSOUND_Stream_Open("c:\sstt.mp3", FSOUND_NORMAL Or FSOUND_LOOP_NORMAL, 0, 0) ‘load stream
Kanal = FSOUND_Stream_Play(FSOUND_FREE, StrH) ‘play it
Command1.Enabled = False
Command2.Enabled = True
End Sub

Private Sub Command2_Click()
DSPPTR = FSOUND_DSP_Create(AddressOf FSOUND_DSPCALLBACK, 255, 222) ‘create dsp unit
Call FSOUND_DSP_SetActive(DSPPTR, 1) ‘activate it
Command2.Enabled = False
End Sub

Private Sub Form_Unload(Cancel As Integer)
‘deactivate unit,unload etc
‘will successfully unload approx. every 10th time
Call FSOUND_DSP_SetActive(DSPPTR, 0)
FSOUND_Stream_Stop StrH
FSOUND_Stream_Close StrH

FSOUND_Close
End Sub

Private Sub Check1_Click()
EffA = Check1.value
End Sub
[/code:1k5atq25]

4)add fmod.bas to your project(create new copy)
5)add the following to the beggining of fmod.bas module:
[code:1k5atq25]Dim StrH As Long
Dim Kanal As Long
Dim DSPPTR As Long
Dim EffA As Long
[/code:1k5atq25]

6)add the following to the end of fmod.bas module:
[code:1k5atq25] Public Function FSOUND_DSPCALLBACK(ByVal OriginalBuffer As Long, ByVal NewBuffer As Long, ByVal Length As Long, ByVal Param As Long) As Long
‘i know that i am totally wrong with this dsp unit, but lets look at it.
‘Debug.Print “DSP UNIT CALLED!” & CStr(Rnd)
Dim str As String
str = Space(Length) ‘reserve memory
‘str = GetStringFromPointer(originalbuffer)
Call CopyMemory(ByVal str, ByVal OriginalBuffer, ByVal Length) ‘copy the memory to string(i dont know in what form should be mp3 data-a string?)
‘FSOUND_DSPCALLBACK = OriginalBuffer
‘add data to textbox...not needed
If Len(Form1.Text1.Text) > 5000 Then Form1.Text1.Text = “”
Form1.Text1.Text = Form1.Text1.Text & str
Form1.Text1.SelStart = Len(Form1.Text1.Text)
Dim abc As String
Dim tmp As String
Dim tmpnum As Long
Dim i As Long
On Error GoTo 1
EffA = Form1.Check1.value ‘tells if super cool effect is enabled
If EffA = 0 Then
abc = str ‘if not then just return originalbuffer
GoTo 55574753
End If
For i = 0 To Length ‘else proceed chr by chr and reverse them, so character code of 50 will become 205 etc.
tmp = Mid(str, i + 1, 1)
tmpnum = 255 – Asc(tmp)
abc = abc & Chr(tmpnum)
Next i
GoTo 55568554 ‘skip this, return newbuffer
55574753
FSOUND_DSPCALLBACK = OriginalBuffer ‘just original stream buffer

GoTo 313347
55568554
FSOUND_DSPCALLBACK = StrPtr(abc) ‘here we return modified data
313347
‘data to textbox...
If Len(Form1.Text2.Text) > 5000 Then Form1.Text2.Text = “”
Form1.Text2.Text = Form1.Text2.Text & abc
Form1.Text2.SelStart = Len(Form1.Text2.Text)
‘that’s all
Exit Function
1
Debug.Print “ERROR!”
Resume Next
End Function
[/code:1k5atq25]
7)i recommend saving the project – it may crash
8)Change the enabled property of command2 to false
9)Change the multiline property of text1 and text2 to true
10)Run it, but first read on.

I noticed that when ceating a dsp unit fmod dll will create a new thread in the process. When you were sometimes trying thread things in vb-crashes,lockups,unexpected terminations… will occur. But now,when the project is runnig (IDE only – as .exe it will crash even if compiled as p-code), click command1 button(please copy some mp3 to c:\ and rename it to sstt.mp3). The sound will start to play. Now click command2. The DSP unit will become active, and you can try the check1.

Fine, main question of all this is:
How can I change the mp3 data to have some effect on it(for example lowpass)? Any help would be great.

  • You must to post comments
0
0

I’ve always had problems using copymemory and I found that playing around with byval brought different results, if I used it then it gave me an access violation and crashed VB, if I didnt use it the audio played but with severe buffer underruns and was choppy before crashing the ide. So, I’m not sure where the problem lies.

  • You must to post comments
0
0

The last reply was made by me, i forgot to login. Vilo.

  • You must to post comments
0
0

I tried many methods how to pass a pointer to the buffer. Most of them caused an exception in msvbvm60.dll, but the music was playin about 20 seconds after the error and the app then closed.
So i have rewritten EchoCallback form fmod c++ example(i know c++ a bit.). And it works good, no exceptions. Only the echo falls down very quickly. Maybe i have done some error. So its problem with DataS(i)=DataS(i)+10. But i dont totally understand what is echo callback doing. Dont you know where can i download some documentation how fmod dsps works?

  • You must to post comments
0
0

Please post it as an VB project I can download. 😀

  • You must to post comments
0
0

[url=http://dspguru.com:3tualpib]Dsp Guru[/url:3tualpib].

  • You must to post comments
0
0

Just from looking at the code it doesnt look like the DSP callback is optimized, since callbacks are called fairly rapidly your DSP callback looks bulky and slow. Also, to create your own effects (lowpass, etc.) what you can do is use CopyMemory to retrieve the array of data (copying it from the NewBuffer pointer) and then change the values in whatever way you want, after you are done changing the array you can simply use CopyMemory again to copy the array of changed values back into a pointer (NewBuffer). Why are you using StrPtr? Its my understanding that StrPtr returns a pointer to a string, so using it in the callback wouldnt be very effective since the data buffer is a long integer.

  • You must to post comments
0
0

Ok thanks.

  • You must to post comments
0
0

Well it is totally understandable that nobody remaked the project. I have read your post and optimized the callback. Heres the code:
[code:jn7u03ey]
Public Function FSOUND_DSPCALLBACK(ByVal OriginalBuffer As Long, ByVal NewBuffer As Long, ByVal Length As Long, ByVal Param As Long) As Long
On Error Resume Next
Dim DataS() As Single
Dim i As Long
ReDim DataS(0 To Length) As Single
Call CopyMemory(DataS(0), ByVal NewBuffer, Length)
For i = 0 To UBound(DataS)
DataS(i) = DataS(i) + 0.1
Next i
Call CopyMemory(ByVal NewBuffer, DataS(0), Length)
FSOUND_DSPCALLBACK = NewBuffer
End Function
[/code:jn7u03ey]

So, I have to copy newbuffer into array. Of what size? Is it 0 to Length?
Then what datatype? Single? Without On Error Resume Next sometimes owerflow occurs with a single having value -1,#QNAN. I also tryed long, double, byte. Then i changed the values a bit and copied the array back to newbuffer. The result? Just very chrispy sound. I wanted to make a mp3 more louder. Any ideas?

  • You must to post comments
0
0

Could you post your echo callback?

  • You must to post comments
0
0

[quote="Vilo":3hyx0toj]Of what size? Is it 0 to Length?
Then what datatype? Single?[/quote:3hyx0toj]

It depends on the mixer being used so you have to use Fsound_getmixer, and if its an FPU mixer than the data type would be single, anything else is an integer. And yes, it will be an array from 0 to length. I wrote some code a while ago that did this:

[code:3hyx0toj]
Public Function GetDataINT(ByVal Buffer As Long, ByRef IntBuffer() As Integer)

Dim nrOfVals As Long 
If UBound(IntBuffer) > 1023 Then nrOfVals = 1024 Else nrOfVals = UBound(IntBuffer) + 1 
CopyMemory IntBuffer(0), ByVal Buffer, nrOfVals * 2 

End Function

Public Function GetDataFPU(ByVal Buffer As Long, ByRef FpuBuffer() As Single)

Dim nrOfVals As Long 
If UBound(FpuBuffer) > 1023 Then nrOfVals = 1024 Else nrOfVals = UBound(FpuBuffer) + 1 
CopyMemory FpuBuffer(0), ByVal Buffer, nrOfVals * 4 

End Function
[/code:3hyx0toj]

The way you need to copy the array back to newbuffer is by returning it as a pointer to the callback function. You would need to use CopyMemory again to get a new pointer to your data, then you return the newly created pointer to the DSP Callback. But a problem that I encountered while making my Oscilliscope example is that the data from the DSP unit doesnt sync with the sound output.

EDIT: typos

  • You must to post comments
0
0

Of course, here it is:

[code:3mwcvvux]
Public Function EchoCallback(ByVal originalbuffer As Long, ByVal newbuffer As Long, ByVal length As Long, ByVal param As Long) As Long
Dim mixertype As Long
Dim outputfreq As Long
Dim taillen As Long
Dim startlen As Long
outputfreq = 44100
mixertype = FSOUND_GetMixer()
Dim echobuff As Long
echobuff = param
If mixertype = FSOUND_MIXER_BLENDMODE Or mixertype = FSOUND_MIXER_QUALITY_FPU Then

    EchoCallback = newbuffer
    Exit Function
    End If


If EchoOffset + length > EchoLen Then
    taillen = EchoLen - EchoOffset

    startlen = length - taillen

    Call FSOUND_DSP_MixBuffers(newbuffer, echobuff + (LShift(EchoOffset, 2)), taillen, outputfreq, 128, FSOUND_STEREOPAN, FSOUND_STEREO Or FSOUND_16BITS)
    Call FSOUND_DSP_MixBuffers(newbuffer + (LShift(taillen, 2)), echobuff, startlen, outputfreq, 128, FSOUND_STEREOPAN, FSOUND_STEREO Or FSOUND_16BITS)

‘ memcpy(echobuff + (EchoOffset << 2), newbuffer, taillen << 2);
Ԥ memcpy(echobuff, (char *)newbuffer + (taillen << 2), startlen << 2);
CopyMemory ByVal echobuff + (LShift(EchoOffset, 2)), ByVal newbuffer, LShift(taillen, 2)
CopyMemory ByVal echobuff, ByVal newbuffer + (LShift(taillen, 2)), LShift(startlen, 2)

Else
    Call FSOUND_DSP_MixBuffers(newbuffer, echobuff + (LShift(EchoOffset, 2)), length, outputfreq, 128, FSOUND_STEREOPAN, FSOUND_STEREO Or FSOUND_16BITS)

‘ memcpy(echobuff + (EchoOffset << 2), newbuffer, length << 2);
CopyMemory ByVal echobuff + (LShift(EchoOffset, 2)), ByVal newbuffer, LShift(length, 2)

EchoOffset = EchoOffset + length
If EchoOffset &gt;= EchoLen Then
EchoOffset = EchoOffset - EchoLen
End If

End If
EchoCallback = newbuffer
End Function

Public Function InitDSP(val As Long)

EchoLen = val
EchoBuffer = GlobalAlloc(GMEM_FIXED Or GMEM_ZEROINIT, val * 4) ' calloc(EchoLen, 4);
EchoOffset = 0
EchoUnit = FSOUND_DSP_Create(AddressOf EchoCallback, 255, EchoBuffer)
Call FSOUND_DSP_SetActive(EchoUnit, 1) 'activate it

End Function

Function MakeLong(LoWord As Long, HiWord As Long) As Long
‘Replacement for the c++ Function MAKELONG
‘You need this to pass values to certain function calls.
‘i.e BASS_ChannelSetPosition needs to pass a value
‘using make long, i.e BASS_ChannelSetPosition Handle,MakeLong(Order,Row)
MakeLong = LoWord Or LShift(HiWord, 16)
End Function

Public Function LShift(ByVal lValue As Long, ByVal lNumberOfBitsToShift As Long) As Long
Const ksCallname As String = "LShift"
On Error GoTo Procedure_Error
LShift = lValue * (2 ^ lNumberOfBitsToShift)

Procedure_Exit:
Exit Function

Procedure_Error:
Err.Raise Err.Number, ksCallname, Err.Description, Err.HelpFile, Err.HelpContext
Resume Procedure_Exit
End Function

Public Function RShift(ByVal lValue As Long, ByVal lNumberOfBitsToShift As Long) As Long

Const ksCallname As String = &quot;RShift&quot;
On Error GoTo Procedure_Error
RShift = lValue \ (2 ^ lNumberOfBitsToShift)

Procedure_Exit:
Exit Function

Procedure_Error:
Err.Raise Err.Number, ksCallname, Err.Description, Err.HelpFile, Err.HelpContext
Resume Procedure_Exit
End Function

[/code:3mwcvvux]

So i call initdsp(500) – 500 is a default len of echo.
But the echo is anyway falling too fast. Commented lines were that ones that i wasnt sure if they are rightly rewrited to vb.
And about dspguru. I think that those algorithms are too complicated for me. Lshift, Rshift, MakeLong functions are from different sources, they are not mine.

  • You must to post comments
0
0

Thanks for the functions. I was playing with them for a long time, but without success. All I want is to make a mp3 more louder.
You said that i should first call FSOUND_GetMixer to determine how mixer is fmod using. It returned 7. So its FSOUND_MIXER_QUALITY_MMXP5. Then its integer datatype. Heres the code:

[code:1cbls7ly]
Public Function FSOUND_DSPCALLBACK(ByVal OriginalBuffer As Long, ByVal NewBuffer As Long, ByVal Length As Long, ByVal Param As Long) As Long
Dim DataS() As Integer
Dim i As Long
ReDim DataS(0 To Length) As Integer
Call GetDataINT(NewBuffer, DataS())
For i = 0 To UBound(DataS)
DataS(i) = DataS(i) + 10
Next i
Call CopyMemory(ByVal NewBuffer, DataS(0), ByVal Length)
FSOUND_DSPCALLBACK = NewBuffer
End Function
[/code:1cbls7ly]

The result? No effect. Even the spectrum does not change. Whats wrong?

  • You must to post comments
0
0

You shouldnt copymemory directly to the newbuffer, you should use copymemory to get a pointer to your array than return that pointer to your callback. So like:

Dim Buffer as long
Call CopyMemory(ByVal Buffer, DataS(0), ByVal Length)
FSOUND_DSPCALLBACK = Buffer

  • You must to post comments
0
0

That does access violation!

  • You must to post comments
Showing 17 results
Your Answer

Please first to submit.