[Solved] Adapting Structure to PB_X64
Posted: Sun Jun 20, 2021 1:20 pm
Hi
The code below run normally with PB 5.73 x86, but not with x64.
Seems that the problem is related with the API WaitForSingleObject (just my guess).
Is there any solution for run with PB x64?
Thanks.
The code below run normally with PB 5.73 x86, but not with x64.
Seems that the problem is related with the API WaitForSingleObject (just my guess).
Code: Select all
;/ /// Threadbased DirectSound Streaming Play by Inc.
;/ /// Main parts do base on a Directsound playback example by Tomijan
;/ /// For PB4
;/ /// Normally you should not use DirectX within threads, but here no problems do occur
;/ /// Please do report any bugs.
;/ /// In this state the code is just an example. Its quick'n dirty and so still using globals and no further commands
;/ /// like stop/pause/seek etc. are implemented - these will be supported in future releases.
#NUM_PLAY_NOTIFICATIONS = 2
#Duration = 1 ;in sec. - Keep in mind: Increasing the buffer size increases the audio data latency
;
#DSBCAPS_LOCSOFTWARE = $8
#DSBCAPS_CTRLFREQUENCY = $20
#DSBCAPS_CTRLVOLUME = $80
#DSBCAPS_CTRLPAN = $40
#DSBCAPS_CTRLPOSITIONNOTIFY = $00000100
#DSBCAPS_GETCURRENTPOSITION2 =$00010000
#DSBCAPS_GLOBALFOCUS = $00008000
;
#DSSCL_EXCLUSIVE = 3
#DSSCL_NORMAL = 1
#DSSCL_PRIORITY = 2
#DSSCL_WRITEPRIMARY = 4
#DD_OK = 0
#DS_OK = 0
;
#DSBPLAY_LOOPING = $1
#DSBLOCK_FROMWRITECURSOR = $1
#DSBLOCK_ENTIREBUFFER = $2
#TIME_CALLBACK_FUNCTION = 0
;Structure WAVEFORMATEX Extends WAVEFORMAT
; wBitsPerSample.w
; cbSize.w
;EndStructure
Structure DSBUFFERDESC
dwSize.l
dwFlags.l
dwBufferBytes.l
dwReserved.l
*lpwfxFormat
EndStructure
Structure DSBPOSITIONNOTIFY
dwOffset.l;
hEventNotify.l;
EndStructure
Structure DIRECTSOUND
RA_DirectSound.l
Sound.l
Notify.l
secBuflen.l
nChannels.l
EndStructure
Global hWndM, hEvent, ThreadID, SoundFinished.b
Global Dim Notifications.DSBPOSITIONNOTIFY(#NUM_PLAY_NOTIFICATIONS-1)
Global DX8Sound.DIRECTSOUND
Procedure Delete(*obj.IUnknown)
ProcedureReturn *obj\Release()
EndProcedure
Procedure PrepareDX8Sound (*pWfx.WAVEFORMATEX)
If OpenLibrary(0,"DSOUND.DLL")
Result.l = CallFunction(0,"DirectSoundCreate8",0,@*RA_DirectSound.IDIRECTSOUND8,0)
EndIf
If Result = #Null
Result = *RA_DirectSound\SetCooperativeLevel(hWndM,#DSSCL_NORMAL) ; hwnd is the WindowID
If Result.l <> #DD_OK
Delete(*RA_DirectSound)
Else
dsbd.DSBUFFERDESC
dsbd\dwSize = SizeOf(DSBUFFERDESC)
dsbd\dwFlags = #DSBCAPS_LOCSOFTWARE|#DSBCAPS_CTRLVOLUME|#DSBCAPS_CTRLPOSITIONNOTIFY|#DSBCAPS_GLOBALFOCUS | #DSBCAPS_GETCURRENTPOSITION2
dsbd\dwBufferBytes = *pWfx\nAvgBytesPerSec * #Duration
dsbd\lpwfxFormat = *pWfx
nBlockAlign = *pWfx\nBlockAlign;
nSamplesPerSec = *pWfx\nSamplesPerSec;
dwNotifySize = nSamplesPerSec * #Duration * nBlockAlign / #NUM_PLAY_NOTIFICATIONS;
dwNotifySize = dwNotifySize - (dwNotifySize % nBlockAlign)
hEvent = CreateEvent_(0,#True,0,0)
For i = 0 To #NUM_PLAY_NOTIFICATIONS-1
Notifications(i)\dwOffset = dwNotifySize*(i)
Notifications(i)\hEventNotify = hEvent
Next
Result.l = *RA_DirectSound\CreateSoundBuffer(@dsbd,@*pDSB.IDirectSoundBuffer,0)
If Result.l <> #DD_OK
Delete(*RA_DirectSound)
Fresult = #Null
Else
*DSB8.IDIRECTSOUNDBUFFER8 = 0
*pDSB\QueryInterface(?IID_DirectSoundBuffer8,@*DSB8)
*DSN8.IDirectSoundNotify = 0
*pDSB\QueryInterface(?IID_DirectSoundNotify8,@*DSN8)
Delete(*pDSB)
If *DSB8 = 0
Delete(*RA_DirectSound)
Else
NotifyRes = *DSN8\SetNotificationPositions(#NUM_PLAY_NOTIFICATIONS,@Notifications(0))
DX8Sound\secBuflen = #Duration * *pWfx\nAvgBytesPerSec
DX8Sound\Sound = *DSB8
DX8Sound\Notify = *DSN8
DX8Sound\RA_DirectSound = *RA_DirectSound
DX8Sound\nChannels = *pWfx\nChannels
Fresult = *DSB8
EndIf
EndIf
EndIf
Else
MessageRequester("Error","Please install DirectX v.8 or above",0)
End
EndIf
If IsLibrary(0)
CloseLibrary(0)
EndIf
ProcedureReturn Fresult
EndProcedure
Procedure TimerThread(dummy)
dwLength.l = DX8Sound\secBuflen/#NUM_PLAY_NOTIFICATIONS
dwLengthAll.l = DX8Sound\secBuflen
*Sound.IDIRECTSOUNDBUFFER8 = DX8Sound\Sound
L1 = 1
Repeat
wfso = WaitForSingleObject_(hEvent,#INFINITE)
wres = *Sound\Lock(0, dwLength, @Write1, @L1, @Write2, @L2, #DSBLOCK_FROMWRITECURSOR )
If wres = #DS_OK
L1 = ReadData(0, Write1, L1) ;/ /// If the result > 0 then there's still data to buffer and therefore to play
Debug "Buffer 1 refilled using "+Str(L1)+ "bytes"
If L2
L2 = ReadData(0, Write2, L2)
Debug "Buffer 2 refilled using "+Str(L2)+ "bytes"
Debug " "
EndIf
lres = *Sound\Unlock(Write1, L1, Write2, L2) ; L1/L2 here do inform how much data has been buffered
EndIf
ResetEvent_(hEvent)
Debug "Soundfile readpointer now at byte "+Str(Loc(0))
Until L1 = 0 ;/ /// No more bytes in Soundfile available and by this no more bytes to buffer and so playback stops.
Debug "... which should equal to "+Str(Lof(0))+" which is the actual soundfile size"
Debug " "
Debug "finished"
SoundFinished = #True
*Sound\stop() ;/ /// Do stop the Loop
KillThread(ThreadID)
EndProcedure
Procedure DXSound(File.s)
Protected pWfx.WAVEFORMATEX
cb = ReadFile(0, File)
If cb
FileSeek(0, 20) ;/ /// go to the WAVEFORMATEX headerpart of the Soundfile ...
ReadData(0, @pWfx, SizeOf(WAVEFORMATEX))
FileSeek(0, 44) ;/ /// ... and to the start of the soundata. --> http://de.wikipedia.org/wiki/WAV_(Format)
Result = PrepareDX8Sound(@pWfx)
If Result
*Sound.IDIRECTSOUNDBUFFER8 = DX8Sound\Sound
*Sound\SetCurrentPosition(0)
*Sound\Play(0,0,#DSBPLAY_LOOPING) ;/ /// Start the Loop
ThreadID = CreateThread(@TimerThread(),0) ;/ /// Creating our buffer refilling thread
EndIf
EndIf
EndProcedure
;- /// An example of usage
CompilerIf #PB_Compiler_Debugger = #False
MessageRequester("Info","Please run this example using the debugger and see its output while choosing a wave file")
End
CompilerEndIf
hWndM = OpenWindow(0,0,0,20,20,"Sound",#PB_Window_ScreenCentered)
File.s = OpenFileRequester("Choose a soundfile","","Wave files (*.wav)|*.wav",0)
DXSound(File) ;/ /// Load and Play
Repeat
event = WaitWindowEvent()
Delay(10)
Until SoundFinished = #True Or event = #PB_Event_CloseWindow
If IsThread(ThreadID) : KillThread(ThreadID) : EndIf
CloseWindow(0)
FreeMemory(-1)
End
DataSection
IID_DirectSoundBuffer8: ; DSOUND.h
Data.l $6825A449
Data.w $7524,$4D82
Data.b $92,$0F,$50,$E3,$6A,$B3,$AB,$1E
IID_DirectSoundNotify8:
Data.l $B0210783
Data.w $89CD, $11D0
Data.b $AF,$08,$00,$A0,$C9,$25,$CD,$16
EndDataSection
Thanks.