Page 1 of 1
PlaySound() in end of Thread
Posted: Sun Jul 18, 2010 4:33 pm
by Phantomas
Hello, if I use PlaySound() in End of Thread, then Sound not played (or played shortly) because thread exiting (quit). Can I fix it without API use, only with PB?
Example:
Code: Select all
InitSound() ; This can return 0 in executable file?
#sound = 0
#sound_file = "path_to_sound_file.wav"
Procedure thread(*i_dont_know_what_for_this)
PlaySound(#sound)
;Delay(1000)
EndProcedure
If LoadSound(#sound, #sound_file) = 0
End
Else
thread = CreateThread(@thread(), 0)
WaitThread(thread)
EndIf
I think, solution exist like that: add Delay(sound_file_length)

.
This may fixed in newest PB versions?
Thanks & Sorry if this trouble already discussed.
Re: PlaySound() in end of Thread
Posted: Sun Jul 18, 2010 10:13 pm
by RASHAD
You can use MP3 file and in that case you will be using the Movie Lib
You can estimate the duration time before playing the audio file
But if you insist to Use WAV file and Thread next snippet is for Windows
Code: Select all
Global SFile$
SFile$ = "g:\projects\02 Silencio.wav"
Procedure thread(*i_dont_know_what_for_this)
PlaySound_(SFile$,0,#SND_SYNC|#SND_NODEFAULT)
EndProcedure
thread = CreateThread(@thread(), 0)
;WaitThread(thread)
While IsThread(thread)
Wend
Debug "End"
Re: PlaySound() in end of Thread
Posted: Sun Jul 18, 2010 10:19 pm
by netmaestro
Your thread must indeed wait until the sound has time to play. But how long is that? For wav files, you can use the provided proc. It can be tweaked for other formats. What I'd do is use it to find the playtime of each sound file and put a constant at the top of your code for each, something like #EXPLOSION_1_MS = 1669 and then Delay(#EXPLOSION_1_MS) at the end of your thread procedure. This way you can use IncludeBinary and CatchSound(). But if you don't mind loading the sound from HD, RASHAD's solution is fine too.
Code: Select all
Procedure GetPlaytime(FileName.s)
; netmaestro July 2010
Protected Result.l
Protected shortFileName.s
Protected Buffer.s
#ALIAS = "WAVFILE"
shortFilename = Space(#MAX_PATH)
shortFilename = Left(shortFileName, GetShortPathName_(FileName, @shortFileName, #MAX_PATH))
Result = mciSendString_("open " + shortFileName + " type waveaudio alias " + #ALIAS + " wait", "", 0, 0)
If Result = 0
Buffer = Space(128)
Result = mciSendString_("status " + #ALIAS + " length wait", Buffer, Len(Buffer), 0)
Else
ProcedureReturn 0
EndIf
mciSendString_("close " + #ALIAS, "", 0, 0)
ProcedureReturn Val(Buffer)
EndProcedure
Re: PlaySound() in end of Thread
Posted: Mon Jul 19, 2010 8:34 am
by RASHAD
Playing WAV sound after calculating duration time
NO API ,Tested but not too much
Code: Select all
Global FName$
InitSound() ; This can return 0 in executable file?
FName$ = "G:\Projects\02 Silencio.wav"
Procedure thread(*i_dont_know_what_for_this)
ReadFile(0, FName$)
length = Lof(0)
FileSeek(0,28)
*MemoryID = AllocateMemory(4)
If *MemoryID
bytes = ReadData(0, *MemoryID, 4)
DTime = length/PeekL(*MemoryID) + 1
EndIf
FreeMemory(*MemoryID)
CloseFile(0)
LoadSound(0,FName$)
PlaySound(0)
Delay(DTime*1000)
EndProcedure
thread = CreateThread(@thread(), 0)
WaitThread(thread)
Re: PlaySound() in end of Thread
Posted: Mon Jul 19, 2010 8:53 pm
by Michael Vogel
Another possibility is to use MCI (a relict from old windows versions), which works fine with different file formats...
There are a couple of commands available, after you have loaded a song...
mciSendString_("open " + #DQUOTE$+ActSongFile+#DQUOTE$ + " type mpegvideo alias song3", 0, 0, 0)
...you can start playing...
mciSendString_("play song3", 0, 0, 0)
...get the music length...
Dummy.s=Space(#MAX_PATH)
mciSendString_("status song3 length",Dummy,#MAX_PATH,0)
ActLength=Val(Dummy)
...and check if the song has reached the end position...
Dummy.s=Space(#MAX_PATH)
mciSendString_("status song3 position",Dummy,#MAX_PATH,0)
SongPosition=Val(Dummy)
If ActLength
If SongPosition=ActLength
Finished!!!
EndIf
EndIf
Re: PlaySound() in end of Thread
Posted: Tue Jul 20, 2010 3:48 am
by clover
It seems that PlaySound() implements asynchronously. So you can get the total duration of the sound in advance of playing, then call Sleep() and set the param to the duration you have just got. And then... all is OK!
As for the way of getting the duration of the sound, you can refer to relative documents according to the sound format.
Re: PlaySound() in end of Thread
Posted: Tue Jul 20, 2010 3:53 am
by clover
Below is a section of code for attaining the duration of FLAC audio files:
Code: Select all
Procedure.i GetFlacDuration(*pData) ;return milliseconds
If *pData = #Null
ProcedureReturn 0
EndIf
If PeekS(*pData, 4, #PB_Ascii) <> "fLaC"
ProcedureReturn 0
EndIf
mbs.METADATA_BLOCK_STREAMINFO
CopyMemory(*pData + 4 + SizeOf(METADATA_BLOCK_HEADER), @mbs, SizeOf(METADATA_BLOCK_STREAMINFO))
;FLAC is big endian
;x86 CPU is little endian
sample_rate.l = 0
PokeA(@sample_rate + 2, mbs\sample_feature[0])
PokeA(@sample_rate + 1, mbs\sample_feature[1])
PokeA(@sample_rate + 0, mbs\sample_feature[2])
sample_rate >> 4
total_samples.q = 0
PokeA(@total_samples + 4, mbs\sample_feature[3])
PokeA(@total_samples + 3, mbs\sample_feature[4])
PokeA(@total_samples + 2, mbs\sample_feature[5])
PokeA(@total_samples + 1, mbs\sample_feature[6])
PokeA(@total_samples + 0, mbs\sample_feature[7])
total_samples & (%1111 << 32 | $ffffffff)
ProcedureReturn Round(total_samples / sample_rate * 1000, #PB_Round_Up)
EndProcedure