Not well formed ??
I think it is hyperstructured .
But you brought me to an idea !
I changed the code in this way, that it doesn't use the PB-Import of the fmod 3.61 any longer, but it opens the fmod.dll as a library and call all commands direct using CallFunction() now.
(So there was the problem of the PB-Bug "Calling a function out of a procedure crashes", so I have to take the functions out of the procedure, otherwise the program crashes.)
The whole code is now:
Code: Select all
;FSOUND-SAMPLE-Loop-Counter by Froggerprogger, 22nd May 2003
;
;Here's a way to get a callback exactly at each loopend of a looped SAMPLE:
;
;- Decompress sample-data from file into memory
;- Create a custom stream-callback with exact the same length of the sample-data
;- Copy the decompressed sample-data into the custom stream's buffer (mind the doublebuffering!)
;- Do anything inside the callback each time it is called
;____________ Declaration
Global samplerate.l ; it's the global samplerate
Global loopcount.l ; the loopcounter
Global *hSample.l ; handle of the sample
Global *hLoopStream.l ; handle of the created stream
Global sample_length_bytes.l ; length of sampledata in bytes
Global continueplaying.l ; this is directly the ProcedureReturn (0 = stop)
Global stopplaying.l ; this is set to 0 to stop exactly inside the actual callback
Global *SourceData.l ; Pointer to the Sampledata - returned from Sample_Lock
Global slewschange.l ; just for the toggleable SillyLoopEndWindowSize-Change
;____________ Initialization
samplerate = 44100
loopcount = 0
continueplaying = 1
#FSOUND_16BITS = $10 : #FSOUND_STEREO = $40
OpenLibrary(1, "fmod362std.dll")
If CallFunction(1, "_FSOUND_Init@12", samplerate,32,0) = #False
MessageRequester("","Could not initialize FMOD. Stdcall-FMOD.DLL in the EXE's directory ?",0) : End
EndIf
;____________ The Loop-Callback-Procedure
Procedure.l Loop_Callback (*hStream, *Buffer, length, dummy)
If stopplaying
CallFunction(1, "_FSOUND_Stream_Stop@4",*hLoopStream)
EndIf ;(stops immediately after the actual heard loop, exactly BEFORE playing this one, which would be the next hearable.)
If loopcount < 2 ; (load the data only the first two times to spare CPU-time - two times because of double-buffering -> *Buffer flips)
CopyMemory(*SourceData, *Buffer, sample_length_bytes)
EndIf
loopcount + 1
If slewschange
ResizeWindow(300 + Random(100), 205 + Random(100))
EndIf
ProcedureReturn continueplaying ; (WHY THIS VALUE IS IGNORED BY FMOD 3.62 ?? SETTING TO 0 HAS NO EFFECT!?)
EndProcedure
;____________ Create the main-window and put some gadgets onto in
hWnd = OpenWindow (1, 0,0,300,205, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "Froggerprogger's SAMPLE-Loop-Counter")
CreateGadgetList(hWnd)
ButtonGadget(1,5,25,290,20,"Start (again)")
ButtonGadget(2,5,67,290,20,"FSOUND_Stream_Stop immediately")
ButtonGadget(3,5,89,290,20,"FSOUND_Stream_Stop inside the next callback")
ButtonGadget(4,5,111,290,20,"Stop via callbackreturn=0 (doesn't work in fmod 3.62 ?)")
ButtonGadget(5,5,153,290,20,"Toggle SillyLoopEndWindowSizeChange On/Off")
TextGadget(6,0,183,290,20,"", #PB_Text_Center )
;____________ Get a soundfile's name
GetCurrentDirectory_(dirname.s, 255)
filename.s = OpenFileRequester("Choose a soundfile (e.g. try the car)",dirname+"car.wav","*.wav,*.mp3,*.mp2,*.ogg|*.wav;*.mp3;*.mp2;*.ogg|*.*|*.*",0)
;____________ Load the soundfile as a sample and calculate it's length in bytes
*hSample = CallFunction(1, "_FSOUND_Sample_Load@16",1,filename,0,0)
sample_modes = CallFunction(1, "_FSOUND_Sample_GetMode@4",*hSample)
sample_length_bytes = CallFunction(1, "_FSOUND_Sample_GetLength@4",*hSample)
If sample_modes & #FSOUND_16BITS : sample_length_bytes * 2 : EndIf
If sample_modes & #FSOUND_STEREO : sample_length_bytes * 2 : EndIf
;____________ Create a callback-stream with the sample's length
*hLoopStream = CallFunction(1, "_FSOUND_Stream_Create@20", @Loop_Callback(), sample_length_bytes, sample_modes, samplerate, 0)
;____________ Main-Loop
resume = 1
While resume
Select WindowEvent()
Case #PB_Event_Gadget
Select EventGadgetID()
Case 1 : stopplaying = 0 : continueplaying = 1 :
CallFunction(1, "_FSOUND_Sample_Lock@28",*hSample, 0, sample_length_bytes, @*SourceData, @*Dummy2, @SourceDataLen, @Dummy3) ; get the pointer to the sample-data
CallFunction(1, "_FSOUND_Stream_Play@8", 1, *hLoopStream) : loopcount = 0 ; play it (again)
CallFunction(1, "_FSOUND_Sample_Unlock@20",*hSample, @*SourceData, @*Dummy2, @SourceDataLen, @Dummy3) ; just unlock again
Case 2 : CallFunction(1, "_FSOUND_Stream_Stop@4",*hLoopStream) : continueplaying = 0 ; stop immediately
Case 3 : stopplaying = 1 : actloop = loopcount : continueplaying = 0 ; stop immediately after the current loop
Case 4 : continueplaying = 0 ; stop using Callback-ProcedureReturn 0
Case 5 : slewschange ! 1 ; toggles the colorchange at loopend on/off
EndSelect
Case #PB_Event_CloseWindow : resume = 0
Default
SetGadgetText(6, "Loop:"+Str(loopcount))
EndSelect
Delay(1)
Wend
;____________ Prepare program's end
CallFunction(1, "_FSOUND_Stream_Stop@4",*hLoopStream)
CallFunction(1, "_FSOUND_Close@0")
End
What I did then was trying this code with the stdcall - fmod.dll 3.61 and 3.62. (just change the name in OpenLibrary())
--> Tataaa. The behaviour is different:
With 3.61 'Stop after actual double-buffered loop' works fine and 'Stop immediately after actual loop' has no effect.
With 3.62 'Stop after actual double-buffered loop' has no effect anymore and 'Stop immediately after actual loop' WORKS FINE !
--> So there was no problem with PB, it was a bug in the old fmod.dll 3.61
But now I have 2 new problems and 1 more strange question:
poblem 1.) Why does the return-value 0 has no effect any longer ? FMOD-docu 3.62 says it should works - hmm.
problem 2.) I have to prepare the new FMOD.DLL 3.62 - Import AS FAST AS POSSIBLE . Damn.
question 1.) I call the FSOUND_Stream_Stop-function from the inside of the callback using CallFunction() AND THERE'S NO PROBLEM. Why ? I had to put the Lock an Unlock-functions out of the loop, because it crashed, so the PB-CallFunction-from-Procedure-Bug seems not to exist always?
thank you for your impression FloHimself !