SoundPlay Questions
- PuzzledGreatly
- Posts: 1303
- Joined: 29 Sep 2013, 22:18
SoundPlay Questions
With flash it is possible to have more than one sound playing at once. SoundPlay doesn't appear to support this. Is there an alternative to using SoundPlay? We have a Windows 8 PC and bluetooth speakers. When using Soundplay short mp3 and wav files (less than a second) are being truncated. Is there any solution to buffer the whole sound before it is played? Thanks.
Re: SoundPlay Questions
Example 1 - winmm.dll:
Example 2 - bass.dll:
bass.dll can be downloaded from http://www.un4seen.com/
Code: Select all
MusicFile := "F:\Music\test.mp3"
mciSendString("open " """" MusicFile """" " type mpegvideo Alias MyMusic")
mciSendString("play MyMusic")
MsgBox, Playing...
ResRead( WAV01, "test.wav" )
PlaySoundAsync( WAV01 )
MsgBox, pause
; ====================================================================
mciSendString(Command) {
Return, DllCall("winmm.dll\mciSendString", Str,Command, Str,"", Int,0, Int,0)
}
PlaySoundAsync( ByRef Sound ) { ; http://www.autohotkey.com/board/topic/96484-read-wave-resource-from-exe-using-skans-dllread-possible/?p=609800
Return DllCall( "winmm.dll\PlaySound" ( A_IsUnicode ? "W" : "A" ), UInt,&Sound, UInt,0, UInt, 0x7 )
}
; ResRead() By SKAN, from http://www.autohotkey.com/board/topic/57631-crazy-scripting-resource-only-dll-for-dummies-36l-v07/?p=609282
ResRead( ByRef Var, Key ) {
VarSetCapacity( Var, 128 ), VarSetCapacity( Var, 0 )
If ! ( A_IsCompiled ) {
FileGetSize, nSize, %Key%
FileRead, Var, *c %Key%
Return nSize
}
If hMod := DllCall( "GetModuleHandle", UInt,0 )
If hRes := DllCall( "FindResource", UInt,hMod, Str,Key, UInt,10 )
If hData := DllCall( "LoadResource", UInt,hMod, UInt,hRes )
If pData := DllCall( "LockResource", UInt,hData )
Return VarSetCapacity( Var, nSize := DllCall( "SizeofResource", UInt,hMod, UInt,hRes ) )
, DllCall( "RtlMoveMemory", Str,Var, UInt,pData, UInt,nSize )
Return 0
}
; PlaySoundAsync_File( SoundFile ) {
; Return DllCall("winmm.dll\PlaySound", "str",SoundFile, UInt,0, UInt, 0x00020000 | 0x0001 )
; }
Code: Select all
BASS_DLLCALL := DllCall("LoadLibrary", "str", A_ScriptDir "\bass.dll") ; load Bass.dll
BASS_Init := DllCall("bass\BASS_Init", Int,-1, UInt,44100, Int,0, UInt,0, UInt,0) ;initialise Bass
BASS_start := DllCall("bass\BASS_Start", int) ;Start Bass
hMedia := DllCall("bass\BASS_StreamCreateFile", Int, 0, Astr, "F:\Music\test1.mp3", Uint, 0, Uint, 0, Uint, 0, Uint, 44100)
BASS_ChannelPlay := DllCall("bass\BASS_ChannelPlay", UInt,hMedia, Int,1) ;Starts playback
hMedia2 := DllCall("bass\BASS_StreamCreateFile", Int, 0, Astr, "F:\Music\test2.mp3", Uint, 0, Uint, 0, Uint, 0, Uint, 44100)
BASS_ChannelPlay2 := DllCall("bass\BASS_ChannelPlay", UInt,hMedia2, Int,1) ;Starts playback
MsgBox, pause
DllCall("bass\BASS_Free") ; Free Bass Contents
DllCall("FreeLibrary", UInt, BASS_DLLCALL)
ExitApp
Re: SoundPlay Questions
Else, this 2 methods will work only for .wav file, check url for more flag option (async, loop, ...)
I don't found my old script but a way to play mp3 is to open the file with mcisendstring and play it at 00s when you need it. I did a game and for play sound I needed a seperated thread to have a realtime and uncut sound, also most part of lag is cause by your computer because that will use LAV or FF or other codec filter (maybe you can see extra icon when you play a mp3). There is the SOX solution too as a player.
Else for multiple SoundPlay, http://www.autohotkey.com/board/topic/5 ... d-wrapper/
However I suggest than you use first solution of tmplinshi
Code: Select all
FileRead, Sound1, *c %SystemRoot%\Media\tada.wav
FileRead, Sound2, *c %SystemRoot%\Media\chimes.wav
msgbox READY!
sndPlaySound(Sound1)
PlaySound(Sound2)
Return
;http://msdn.microsoft.com/en-us/library/windows/desktop/dd743680.aspx
sndPlaySound(ByRef Sound ) {
Return DllCall("winmm.dll\sndPlaySound", UInt, &Sound, UInt, 0x6 ) ;SND_MEMORY|SND_NODEFAULT
}
;http://msdn.microsoft.com/en-us/library/windows/desktop/dd743680.aspx
PlaySound(ByRef Sound ) {
Return DllCall("winmm.dll\PlaySound", UInt, &Sound, UInt, 0, UInt, 0x6 ) ;SND_MEMORY|SND_NODEFAULT
}
Else for multiple SoundPlay, http://www.autohotkey.com/board/topic/5 ... d-wrapper/
Code: Select all
#Persistent
loop 10
{
SoundPlay( SystemRoot "\Media\tada.wav " , "Multi" )
sleep 50
}
SoundPlay(Filename, wait="") {
static pSoundPlay=0, File=0
if !(pSoundPlay)
pSoundPlay := RegisterCallback( "SoundPlay" )
if !(Filename=0xFFFF)
File := Filename
if (wait="Multi") or (wait>=2)
DllCall( "CreateThread", UInt,0, UInt,0, UInt,pSoundPlay, UInt,0xFFFF, UInt,0, UInt,0 )
else
SoundPlay, %File%, %wait%
return
}
- PuzzledGreatly
- Posts: 1303
- Joined: 29 Sep 2013, 22:18
Re: SoundPlay Questions
Thanks for the replies. Very interesting, though I don't fully understand them. I discovered that the Bluetooth problem is called by a A2DP delay. It's possible to work around this by having an empty sound file looping in the background so that the gate between the PC and the speakers is never closed. Is it possible to set up an endless loop? Experimenting, I tried the code below expecting to get overlapping sounds but didn't. WAV01 was replaced by WAV02:
I don't get why the Msgbox completely stops the sound (or why it should pause the sound). Does it make a difference that I am using a 64 bit system? Thanks again for the replies.
Code: Select all
ResRead( WAV01, "L:\Chants\We all scream for ice cream.wav" )
ResRead( WAV02, "L:\Chants\Yes I do answers.wav" )
PlaySoundAsync( WAV01 )
sleep 500
PlaySoundAsync( WAV02 )
MsgBox, pause
; ====================================================================
mciSendString(Command) {
Return, DllCall("winmm.dll\mciSendString", Str,Command, Str,"", Int,0, Int,0)
}
PlaySoundAsync( ByRef Sound ) { ; http://www.autohotkey.com/board/topic/96484-read-wave-resource-from-exe-using-skans-dllread-possible/?p=609800
Return DllCall( "winmm.dll\PlaySound" ( A_IsUnicode ? "W" : "A" ), UInt,&Sound, UInt,0, UInt, 0x7 )
}
; ResRead() By SKAN, from http://www.autohotkey.com/board/topic/57631-crazy-scripting-resource-only-dll-for-dummies-36l-v07/?p=609282
ResRead( ByRef Var, Key ) {
VarSetCapacity( Var, 128 ), VarSetCapacity( Var, 0 )
If ! ( A_IsCompiled ) {
FileGetSize, nSize, %Key%
FileRead, Var, *c %Key%
Return nSize
}
If hMod := DllCall( "GetModuleHandle", UInt,0 )
If hRes := DllCall( "FindResource", UInt,hMod, Str,Key, UInt,10 )
If hData := DllCall( "LoadResource", UInt,hMod, UInt,hRes )
If pData := DllCall( "LockResource", UInt,hData )
Return VarSetCapacity( Var, nSize := DllCall( "SizeofResource", UInt,hMod, UInt,hRes ) )
, DllCall( "RtlMoveMemory", Str,Var, UInt,pData, UInt,nSize )
Return 0
}
Last edited by PuzzledGreatly on 17 Nov 2013, 00:18, edited 2 times in total.
Re: SoundPlay Questions
PuzzledGreatly
Sorry, I should wrote:
Try this example:
Sorry, I should wrote:
Code: Select all
MsgBox, Playing... (Close this MsgBox to exit.)
Code: Select all
MusicFile := "L:\Chants\We all scream for ice cream.wav"
mciSendString("open " """" MusicFile """" " type mpegvideo Alias WAV01")
ResRead( WAV02, "L:\Chants\Yes I do answers.wav" )
Gui, Add, Button, vbtn_play gbtn_play, Play Sound1 (Loop)
Gui, Add, Button, gbtn_play2, Play Sound2
Gui, Add, Button, vbtn_stop gbtn_stop Disabled, Stop Sound1
Gui, Show, w300 h300
Return
btn_play:
mciSendString("play WAV01 repeat")
GuiControl, Disable, btn_play
GuiControl, Enable, btn_stop
Return
btn_play2:
sndPlaySound( WAV02 )
Return
btn_stop:
mciSendString("stop WAV01")
; mciSendString("close WAV01")
GuiControl, Disable, btn_stop
GuiControl, Enable, btn_play
Return
GuiClose:
ExitApp
; ====================================================================
sndPlaySound(ByRef Sound ) {
Return DllCall("winmm.dll\sndPlaySound", UInt, &Sound, UInt, 0x7 ) ;SND_MEMORY|SND_NODEFAULT|SND_ASYNC
}
mciSendString(Command) {
Return, DllCall("winmm.dll\mciSendString", Str,Command, Str,"", Int,0, Int,0)
}
; ResRead() By SKAN, from http://www.autohotkey.com/board/topic/57631-crazy-scripting-resource-only-dll-for-dummies-36l-v07/?p=609282
ResRead( ByRef Var, Key ) {
VarSetCapacity( Var, 128 ), VarSetCapacity( Var, 0 )
If ! ( A_IsCompiled ) {
FileGetSize, nSize, %Key%
FileRead, Var, *c %Key%
Return nSize
}
If hMod := DllCall( "GetModuleHandle", UInt,0 )
If hRes := DllCall( "FindResource", UInt,hMod, Str,Key, UInt,10 )
If hData := DllCall( "LoadResource", UInt,hMod, UInt,hRes )
If pData := DllCall( "LockResource", UInt,hData )
Return VarSetCapacity( Var, nSize := DllCall( "SizeofResource", UInt,hMod, UInt,hRes ) )
, DllCall( "RtlMoveMemory", Str,Var, UInt,pData, UInt,nSize )
Return 0
}
PlaySoundLoop( ByRef Sound ) {
Return DllCall( "winmm.dll\PlaySound", UInt,&Sound, UInt,0, UInt, 0x0004|0x0001|0x0002|0x0008 ) ; SND_MEMORY|SND_ASYNC|SND_NODEFAULT|SND_LOOP
}
- PuzzledGreatly
- Posts: 1303
- Joined: 29 Sep 2013, 22:18
Re: SoundPlay Questions
Thanks, the looping works. I'm still trying to understand the model. What would I do if I wanted a third sound or to loop two sounds?
Re: SoundPlay Questions
Code: Select all
File_WAV01 := "e:\1.wav"
File_WAV02 := "e:\2.wav"
File_WAV03 := "e:\3.wav"
File_WAV04 := "e:\4.wav"
Gui, Add, Checkbox, vEnableWAV01 gPlay1, Loop WAV01
Gui, Add, Checkbox, vEnableWAV02 gPlay2, Loop WAV02
Gui, Add, Button, gPlay3, Play WAV03
Gui, Add, Button, gPlay4, Play WAV04
Gui, Show, w300 h300
Return
Play1:
GuiControlGet, EnableWAV01
if EnableWAV01
PlayMusic(File_WAV01, "Song1", "repeat")
else
StopMusic("Song1")
Return
Play2:
GuiControlGet, EnableWAV02
if EnableWAV02
PlayMusic(File_WAV02, "Song2", "repeat")
else
StopMusic("Song2")
Return
Play3:
CloseMusic("Song3")
PlayMusic(File_WAV03, "Song3")
Return
Play4:
CloseMusic("Song4")
PlayMusic(File_WAV04, "Song4")
Return
GuiClose:
ExitApp
; ====================================================================
PlayMusic(MusicFile, MusicAlias, Flags="") { ; Flags: repeat, etc...
mciSendString("open " """" MusicFile """" " type mpegvideo Alias " MusicAlias)
mciSendString("play " MusicAlias " " Flags)
}
StopMusic(MusicAlias) {
mciSendString("stop " MusicAlias)
}
CloseMusic(MusicAlias) {
mciSendString("close " MusicAlias)
}
mciSendString(Command) {
Return, DllCall("winmm.dll\mciSendString", Str,Command, Str,"", Int,0, Int,0)
}
- PuzzledGreatly
- Posts: 1303
- Joined: 29 Sep 2013, 22:18
Re: SoundPlay Questions
Thanks, the example is great. I really appreciate the time you've taken to put these all these examples together. Is there a full list of flags, anywhere?. On the [link=http://msdn.microsoft.com/en-us/library ... }Microsoft Page[/link] repeat is listed as SND_LOOP.
Re: SoundPlay Questions
kool
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
Re: SoundPlay Questions
The flags of play command can be found on this page:
http://msdn.microsoft.com/en-us/library ... s.85).aspx
The mciSendString commands list:
http://msdn.microsoft.com/en-us/library ... s.85).aspx
hmm... I should provide links like Zelio did . Sorry PuzzledGreatly waste your time to ask for the link.
http://msdn.microsoft.com/en-us/library ... s.85).aspx
The mciSendString commands list:
http://msdn.microsoft.com/en-us/library ... s.85).aspx
hmm... I should provide links like Zelio did . Sorry PuzzledGreatly waste your time to ask for the link.
- PuzzledGreatly
- Posts: 1303
- Joined: 29 Sep 2013, 22:18
Re: SoundPlay Questions
No problem, Thank s for the links. Looks like some very interesting stuff to experiment with.
Re: SoundPlay Questions
I'm trying to use multi-thread method, seems it stop work after 9 thread:
If comment DllCall("ExitThread") line, it increase to about 30 thread:
Does anyone know the right way to call new threads?
Code: Select all
filePath = D:\YourFile.wav
i:=0
Loop 12 {
ToolTip % ++i
SoundPlay(filePath, true)
Sleep 1000
}
F1::SoundPlay(filePath, true) ; a
Esc::ExitApp
SoundPlay(file, newThread:=false) {
static pSoundPlay, filePath
if !pSoundPlay
pSoundPlay := RegisterCallback("SoundPlay")
if newThread {
filePath := file
Handle := DllCall("CreateThread", Ptr, 0, Ptr, 0, Ptr, pSoundPlay, Ptr, 0, UInt, 0, Ptr, 0)
DllCall("CloseHandle", UInt, Handle)
} else {
SoundPlay % filePath, % wait
DllCall("ExitThread")
}
}
Code: Select all
filePath = D:\YourFile.wav
i:=0
Loop 50 {
ToolTip % ++i
SoundPlay(filePath, true)
Sleep 200
}
F1::SoundPlay(filePath, true) ; a
Esc::ExitApp
SoundPlay(file, newThread:=false) {
static pSoundPlay, filePath
if !pSoundPlay
pSoundPlay := RegisterCallback("SoundPlay")
if newThread {
filePath := file
Handle := DllCall("CreateThread", Ptr, 0, Ptr, 0, Ptr, pSoundPlay, Ptr, 0, UInt, 0, Ptr, 0)
DllCall("CloseHandle", UInt, Handle)
} else {
SoundPlay % filePath, % wait
; DllCall("ExitThread")
}
}
Re: SoundPlay Questions
Also new thread does not help in case of use DllCall winmm.dll\PlaySound.
А new sound completes the current playing sound, like calling several SoundPlay, file.wav command from one thread:
А new sound completes the current playing sound, like calling several SoundPlay, file.wav command from one thread:
Code: Select all
FileRead WAV01, *c D:\dtmf.wav
FileRead WAV02, *c C:\explode.wav
FileRead WAV03, *c C:\applause.wav
FileRead WAV04, *c C:\chimes.wav
ArrWAV:={WAV01: &WAV01, WAV02: &WAV02, WAV03: &WAV03, WAV04: &WAV04}
Loop 4
Gui Add, Button, gPlay, WAV0%A_Index%
Gui Show, w200
Return
Play:
SoundPlay(ArrWAV[A_GuiControl], false)
Return
SoundPlay(Bin, Callback:=true) {
static pSoundPlay:=0
if !pSoundPlay
pSoundPlay := RegisterCallback("SoundPlay")
if Callback
PlaySound(Bin)
else
DllCall("CreateThread", UInt,0, UInt,0, UInt,pSoundPlay, Ptr,Bin, UInt,0, UInt,0)
Return
}
PlaySound(ByRef hSound) {
Return DllCall("winmm.dll\PlaySound" (A_IsUnicode ? "W" : "A"), UInt, hSound, UInt, 0, UInt, 0x7)
}
Esc::
GuiClose:
ExitApp
-
- Posts: 1
- Joined: 31 Jul 2020, 00:12
Re: SoundPlay Questions
Hello tmplinshi and PuzzledGreatly.tmplinshi wrote: ↑15 Oct 2013, 21:38PuzzledGreatly
Sorry, I should wrote:Try this example:Code: Select all
MsgBox, Playing... (Close this MsgBox to exit.)
Code: Select all
MusicFile := "L:\Chants\We all scream for ice cream.wav" mciSendString("open " """" MusicFile """" " type mpegvideo Alias WAV01") ResRead( WAV02, "L:\Chants\Yes I do answers.wav" ) Gui, Add, Button, vbtn_play gbtn_play, Play Sound1 (Loop) Gui, Add, Button, gbtn_play2, Play Sound2 Gui, Add, Button, vbtn_stop gbtn_stop Disabled, Stop Sound1 Gui, Show, w300 h300 Return btn_play: mciSendString("play WAV01 repeat") GuiControl, Disable, btn_play GuiControl, Enable, btn_stop Return btn_play2: sndPlaySound( WAV02 ) Return btn_stop: mciSendString("stop WAV01") ; mciSendString("close WAV01") GuiControl, Disable, btn_stop GuiControl, Enable, btn_play Return GuiClose: ExitApp ; ==================================================================== sndPlaySound(ByRef Sound ) { Return DllCall("winmm.dll\sndPlaySound", UInt, &Sound, UInt, 0x7 ) ;SND_MEMORY|SND_NODEFAULT|SND_ASYNC } mciSendString(Command) { Return, DllCall("winmm.dll\mciSendString", Str,Command, Str,"", Int,0, Int,0) } ; ResRead() By SKAN, from http://www.autohotkey.com/board/topic/57631-crazy-scripting-resource-only-dll-for-dummies-36l-v07/?p=609282 ResRead( ByRef Var, Key ) { VarSetCapacity( Var, 128 ), VarSetCapacity( Var, 0 ) If ! ( A_IsCompiled ) { FileGetSize, nSize, %Key% FileRead, Var, *c %Key% Return nSize } If hMod := DllCall( "GetModuleHandle", UInt,0 ) If hRes := DllCall( "FindResource", UInt,hMod, Str,Key, UInt,10 ) If hData := DllCall( "LoadResource", UInt,hMod, UInt,hRes ) If pData := DllCall( "LockResource", UInt,hData ) Return VarSetCapacity( Var, nSize := DllCall( "SizeofResource", UInt,hMod, UInt,hRes ) ) , DllCall( "RtlMoveMemory", Str,Var, UInt,pData, UInt,nSize ) Return 0 } PlaySoundLoop( ByRef Sound ) { Return DllCall( "winmm.dll\PlaySound", UInt,&Sound, UInt,0, UInt, 0x0004|0x0001|0x0002|0x0008 ) ; SND_MEMORY|SND_ASYNC|SND_NODEFAULT|SND_LOOP }
Thanks for this nice script.
If I want to speed up/down the sound, what should i have to do? I try mciSendTring("play MyMusic fast/slow/speed") but it seems not to work.
Who is online
Users browsing this forum: No registered users and 339 guests