Ok, Brett, I’ve been messing around with your StdCall version of FMOD. Whenvever I activate a callback, in this case it was for an Oscilliscope, I get an error. Creating it worked fine, using Fsound_DSP_Create, but when I activated it, using FSOUND_DSP_SetActive, it crashed. I borrowed the coded directly from your example and tried to convert it to VB as best as I could so it may be wrong.
Heres some of my code:
(Creating and activating the unit)
ScopeUnit = FSOUND_DSP_Create(AddressOf ScopeCallback, FSOUND_DSP_DEFAULTPRIORITY_USER + 3, 0)
ScopeBuffer = FSOUND_DSP_GetBufferLengthTotal() + 16
FSOUND_DSP_SetActive ScopeUnit, True
(The callback function that I wrote/borrowed from your example)
Public Function ScopeCallback(originalbuffer, newbuffer, length As Integer, param As Integer) As Long
Dim totalblocks As Integer Dim dest As Variant Dim mixertype As Long Dim src Dim count As Integer count = 0 mixerype = FSOUND_GetMixer() totalblocks = FSOUND_DSP_GetBufferLengthTotal() / FSOUND_DSP_GetBufferLength() dest = ScopeBuffer(ScopeBlock * FSOUND_DSP_GetBufferLength()) If (mixertype = FSOUND_MIXER_QUALITY_FPU) Then src = newbuffer For count = 0 To length dest(count) = src(count) + src(count + 1) * 0.5 Next count Else src = newbuffer For count = 0 To length dest(count) = (src(count) + src(count + 1) Next count End If ScopeBlock = ScopeBlock + 1 If (ScopeBlock >= totalblocks) Then ScopeBlock = 0 End If ScopeCallback = newbuffer
Please correct my error! Thanks.
- Paranoid_Android asked 16 years ago
Oh I see. Thanks. I only used Variant, and I know it is the worst data type in VB (hogs a mass load of memory), is because I didnt know what data type to use. Ok, so I tested the Fsound_DSP_SetActive with the function that brett gave me, with byval, and it freezes VB when I run it. But if I comment the activating line out the app runs normally. So I am assuming that it is a problem with the StdCall Dll in general.
The only way is Adion’s one. But VB is much more slower than C… the reason is unknown! Maybe the code generated by the compiler isn’t just optimized. This is justified by the reason that VB isn’t a language for fast things, it is just for good things
For example, when you access an element of an array, the compiler checks if the element is inside the boundaries, while C never do this thing. When the access is very frequent (like a DSP buffer) this check drops performance a lot.
Another bad thing is the check on every kind of math operation. If you sum two values VB checks if they are inside the boundaries of the data type set.
However these two checks can be disabled, but I don’t know if there is a big performance boost as expected.
If someone is interested in my dsp dll, just get the source code of my project and see how I used them. I think it’s easy enough.
- Anonymous answered 16 years ago
Hmmm, for some reason, with the StdCall dll DspFX.dll (by karlkox) doesn’t work. I dont know what’s wrong, but are there any other non-DX8 DSP FX dll’s that will work with the StdCall dll? Oh, and what was added to the new dll? Its 128kb now.
The player I made with VB has some DSPs residing in a DLL and dynamically linked to the file. The functions can be called directly from Visual Basic.
These are binaries:
http://web.tiscali.it/sababros/Download … a4_exe.zip
And these are source code:
http://web.tiscali.it/sababros/Download … a4_src.zip
I suggest you to look into source code (and the DSP callback handled directly into VB) to see how I implemented DSPs.
I used the cdecl version of FMOD, but there should be no problem using the stdcall version (obviously I mean the dsp dll, not the player!).
If you’re going to compile the program, look that there is an outdated .bas module I should send you… 😕
The dll file containing dsps is vbdsp.dll. Another dll, lowpass.dll, is the lowpass filter build into fmod example.
If I take out all of the code and use Fsound_DSP_Create it returns a pointer (specifically “42052048”). But if I purpously try to have Fsound_DSP_Create return with an error (null), it returns “255” for some reason, when it should return null. Could you give me a hint on fixing my callback function? Thanks.
And also, I dont know why my app crashes when I try to set it active. But, also, I think I might have used the wrong DLL, its really confusing because I have both of the dlls (StdCall and Cdecl), one is 124kb and the other is 127kb, which one is the StdCall one! lol, sorry.
Hey Paranoid, you forgot Byval somewhere!
Try this one, instead:
Public Function ScopeCallback(byval originalbuffer as long, byval newbuffer as long, byval length As Integer, byval param As Integer) As Long
Originalbuffer and newbuffer where also undeclared, so they mean declared to variant, the worst data type existing!
With this kind of declaration you will get a pointer into originalbuffer and a pointer into newbuffer. The game became hard because you must access directly to memory, and this isn’t possible directly from VB.
You may not access memory using something like a pointer just because VB don’t support pointers. However I heard that VB.NET supports them, but it’s pretty different from usual VB.
You may try to copy the buffer given by fmod to an external buffer declared in visual basic using copymemory functions, but I can’t be more detailed because I have no documentation here (I’m currently at University).
However, always remember that with callback you must always specify Byval. Only if documentation says that the parameter is a pointer you have to declare it with Byref (or just leave nothing). You previously declared originalbuffer and newbuffer as pointers to a variant variable.
They are pointers, but not to a variant! And VB cannot access more than the first entry of the pointer.
I don’t see why you wouldn’t do it with visual basic.
The only thing that will be really slower is that you will have to copy the array to a visual basic array, and then copy it back to the original array after you have processed it.
I don’t think the processing itself will be that much slower.
You can just check out the code of the GetSpectrum function that is included in fmod.bas, that also uses memcopy to return an array from a pointer.
I’m not sure, but since originalbuffer and newbuffer are direct pointers to an array, maybe you can directly access the buffers by declaring it as
… byref originalbuffer(1024) as single, ….
Of course, that would mean you have to know the datatype of the buffer as well as the length, before you write the program.
I assume … byref originalbuffer() as single, … is not possible, because a vb array of undefined length has some values at the beginning that would determine the length I think. (Not sure though)
Please login first to submit.