czardas Posted July 30, 2007 Share Posted July 30, 2007 Today I thought I'd make a metronome. I know my script is a bit primative and probably incorrect. #include <Sound.au3> $wait = InputBox("Miliseconds to Wait", "Enter a number greater than zero.") While 1 _SoundPlay("metro.wav", 1) Sleep($wait) WEnd The problem I am having is that as soon as another process does anything, the metronome slows down. Is there a way that I can force it to keep a regular beat? Or do I have to forget using Sleep() and try another approach? operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
PsaltyDS Posted July 30, 2007 Share Posted July 30, 2007 Today I thought I'd make a metronome. I know my script is a bit primative and probably incorrect. #include <Sound.au3> $wait = InputBox("Miliseconds to Wait", "Enter a number greater than zero.") While 1 _SoundPlay("metro.wav", 1) Sleep($wait) WEnd The problem I am having is that as soon as another process does anything, the metronome slows down. Is there a way that I can force it to keep a regular beat? Or do I have to forget using Sleep() and try another approach? Your call to _SoundPlay() takes time to load/unload at each loop. Better to dig into the Sound.au3 listing and tease out the object creation/dll call so it only has to be done once. You might want to use AdLibEnable(), or maybe TimerInit()/TimerDiff() instead of Sleep(). Also, throw in a little math to get "Beats per minute (BPM)" vice time in miliseconds. Much more useful for a metronome functions. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
czardas Posted July 30, 2007 Author Share Posted July 30, 2007 Your call to _SoundPlay() takes time to load/unload at each loop. Better to dig into the Sound.au3 listing and tease out the object creation/dll call so it only has to be done once. You might want to use AdLibEnable(), or maybe TimerInit()/TimerDiff() instead of Sleep().Also, throw in a little math to get "Beats per minute (BPM)" vice time in miliseconds. Much more useful for a metronome functions. I thought there would be some way around this. New territory for me to explore: AdLibEnable(), TimerInit()/TimerDiff(). Of course I was intending to use bpm. I only threw in the input box at the last minute. I was just concerned that the method I was using was not the best. Thanks for your suggestions. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
GMK Posted July 30, 2007 Share Posted July 30, 2007 (edited) Hmmm...I wonder if you could use MIDI through some kind of API or DLL programming? (Just thinking out loud. Might be something interesting to look into.)EDIT: Maybe this would help: http://www.autoitscript.com/forum/index.php?showtopic=37072 *shrug* Edited July 30, 2007 by GMK Link to comment Share on other sites More sharing options...
ChrisL Posted July 30, 2007 Share Posted July 30, 2007 ProcessSetPriority ( @autoitpid, 5) might help too [u]Scripts[/u]Minimize gui to systray _ Fail safe source recoveryMsgbox UDF _ _procwatch() Stop your app from being closedLicensed/Trial software system _ Buffering Hotkeys_SQL.au3 ADODB.Connection _ Search 2d Arrays_SplashTextWithGraphicOn() _ Adjust Screen GammaTransparent Controls _ Eventlogs without the crap_GuiCtrlCreateFlash() _ Simple Interscript communication[u]Websites[/u]Curious Campers VW Hightops Lambert Plant Hire Link to comment Share on other sites More sharing options...
czardas Posted July 30, 2007 Author Share Posted July 30, 2007 (edited) Hmmm...I wonder if you could use MIDI through some kind of API or DLL programming? (Just thinking out loud. Might be something interesting to look into.)Obviously what I thought might be a simple script writing exercise seems to be less straight forward than I first thought. I will look into it later. I am writing some other scripts at the moment, which are more important to me than a desktop metronome. I would like to have one however, so if anyone is looking for a project If not I'll try and get my head around it. A lot of this stuff is new to me. I think I need to absorb some new methods and ideas. Thanks for the response. Edited July 30, 2007 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
czardas Posted July 30, 2007 Author Share Posted July 30, 2007 ProcessSetPriority ( @autoitpid, 5) might help tooNow that sounds like the kind of thing that I was originally thinking of. Still there is an issue with time taken to load the wav file. This limits the bpm, so I will probably have to combine all your answers to get a efficient application. operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
PsaltyDS Posted July 30, 2007 Share Posted July 30, 2007 I don't actually use AdLibEnable much, and this seemed like a good experiment with switching AdLibEnable on/off based on an input, so I did a demo: expandcollapse popup#include <guiconstants.au3> Opt("GuiOnEventMode", 1) Global $BEAT_NUM = 0, $BEAT_CNT = 1 ; Create GUI $hGUI = GUICreate("AutoIt Metronome", 300, 170) GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit") ; Add controls GUICtrlCreateLabel("The AutoIt Metronome", 10, 10, 280, 30, $SS_CENTER) GUICtrlSetFont(-1, 12, 600) GUICtrlCreateLabel("Beats Per Minute:", 10, 50, 135, 20, $SS_RIGHT) $BeatsPerMin = GUICtrlCreateInput("60", 155, 50, 50, 20) GUICtrlCreateUpdown(-1) GUICtrlSetLimit(-1, 240, 1) GUICtrlCreateLabel("Beats Per Bar:", 10, 80, 135, 20, $SS_RIGHT) $BeatsPerBar = GUICtrlCreateInput("0", 155, 80, 50, 20) GUICtrlCreateUpdown(-1) GUICtrlSetLimit(-1, 64, 0) $Start_Button = GUICtrlCreateButton("START", 50, 120, 75, 30) GUICtrlSetOnEvent(-1, "_ButtonHit") $Stop_Button = GUICtrlCreateButton("STOP", 175, 120, 75, 30) GUICtrlSetOnEvent(-1, "_ButtonHit") ; Await user actions GUISetState() While 1 Sleep(20) WEnd Func _ButtonHit() Local $Input, $BEAT_TIME Switch @GUI_CtrlId Case $Start_Button $Input = GUICtrlRead($BeatsPerMin) If StringIsInt($Input) And $Input >= 1 And $Input <= 240 Then $BEAT_TIME = Int(60000 / $Input) $Input = GUICtrlRead($BeatsPerBar) If StringIsInt($Input) And $Input >= 0 And $Input <= 64 Then $BEAT_NUM = 1 $BEAT_CNT = $Input AdlibEnable("_Beat", $BEAT_TIME) Else GUICtrlSetData($BeatsPerBar, 0) EndIf Else GUICtrlSetData($BeatsPerMin, 60) EndIf Case $Stop_Button AdlibDisable() EndSwitch EndFunc ;==>_ButtonHit Func _Beat() Local $BeepFreq = 2000, $BeepTime = 10 If $BEAT_CNT > 0 Then If $BEAT_NUM = 1 Then $BeepFreq = 1000 $BeepTime = 25 EndIf $BEAT_NUM += 1 If $BEAT_NUM > $BEAT_CNT Then $BEAT_NUM = 1 EndIf Beep($BeepFreq, $BeepTime) EndFunc ;==>_Beat Func _Quit() Exit EndFunc ;==>_Quit Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
czardas Posted July 31, 2007 Author Share Posted July 31, 2007 (edited) Failed upload attempt [see below]. Edited August 9, 2007 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
czardas Posted August 3, 2007 Author Share Posted August 3, 2007 I don't actually use AdLibEnable much, and this seemed like a good experiment with switching AdLibEnable on/off based on an input, so I did a demo:Sorry it took so long for me to respond. I wrote a lengthy reply to this the other day, but for some reason the post failed and I did not have time to rewrite it. Firstly I wanted to thank you for having spent the time to make this. However I can't actually use it because it is too quiet. Unfortunately I don't know why, and I am at a loss to fix it. I could amplify the signal, but that would mean carrying an amplifier and speakers around with my laptop. Not very practical. The second part of my original response was about the beats per bar idea. I like the idea, and I have thought of several improvements. I will post these ideas in detail within the next day or two, if anyone is interested. I do not want anyone to think that I am after free code. It's just that I find this project a bit tricky. I think that it is worth the effort to make this thing, because I am sure that it will get used, and it's a nice thing to share.Please check back in a day or two, as I need to study your code and gather my thoughts about additional features, namely programmable accents, musical symbols on the interface and standard time signature settings.Thanks again,Czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
PsaltyDS Posted August 3, 2007 Share Posted August 3, 2007 If you are going to use Sound.au3 vice Beep, then you could make it smoother with the following: Break down the code in Sound.au3 to get info needed to do these things: 1. Open the DLL only once with DllOpen(), saving the handle at the begining, and close it at the end. This avoids repeated open/close cycles every time you do DllCall() to play the sound. 2. Do $oSnd.Open only once, saving the alias, so you don't have to open the WAV file over and over again. 3. Do the DllCall() for play with your own line of code. Don't use _SoundPlay() because it will reintroduce the inefficiency you correct with 1 and 2 above. 4. Find a way to introduce an altenate volume level, or an alternate sound, or both so you can have a "down beat" that sounds different than the "beat". 5. Either use .wav files other people already have, or post them for use in testing (i.e. I don't have "metro.wav" that you used before). Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
GMK Posted August 7, 2007 Share Posted August 7, 2007 I modified PsaltyDS' metronome code above to make a MIDI metronome. MIDI UDF required: http://www.autoitscript.com/forum/index.ph...mp;#entry385157expandcollapse popup#include <guiconstants.au3> #include <midiudf.au3> Opt("GuiOnEventMode", 1) Global $BEAT_NUM = 0, $BEAT_CNT = 1, $open = _midiOutOpen () ; Create GUI $hGUI = GUICreate("AutoIt Metronome", 300, 170) GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit") ; Add controls GUICtrlCreateLabel("The AutoIt Metronome", 10, 10, 280, 30, $SS_CENTER) GUICtrlSetFont(-1, 12, 600) GUICtrlCreateLabel("Beats Per Minute:", 10, 50, 135, 20, $SS_RIGHT) $BeatsPerMin = GUICtrlCreateInput("120", 155, 50, 50, 20) GUICtrlCreateUpdown(-1) GUICtrlSetLimit(-1, 240, 40) GUICtrlCreateLabel("Beats Per Bar:", 10, 80, 135, 20, $SS_RIGHT) $BeatsPerBar = GUICtrlCreateInput("4", 155, 80, 50, 20) GUICtrlCreateUpdown(-1) GUICtrlSetLimit(-1, 64, 0) $Start_Button = GUICtrlCreateButton("START", 50, 120, 75, 30) GUICtrlSetOnEvent(-1, "_ButtonHit") $Stop_Button = GUICtrlCreateButton("STOP", 175, 120, 75, 30) GUICtrlSetOnEvent(-1, "_ButtonHit") ; Await user actions GUISetState() While 1 Sleep(20) WEnd Func _ButtonHit() Local $Input, $BEAT_TIME Switch @GUI_CtrlId Case $Start_Button $Input = GUICtrlRead($BeatsPerMin) If StringIsInt($Input) And $Input >= 1 And $Input <= 240 Then $BEAT_TIME = Int(60000 / $Input) $Input = GUICtrlRead($BeatsPerBar) If StringIsInt($Input) And $Input >= 0 And $Input <= 64 Then $BEAT_NUM = 1 $BEAT_CNT = $Input AdlibEnable("_Beat", $BEAT_TIME) Else GUICtrlSetData($BeatsPerBar, 0) EndIf Else GUICtrlSetData($BeatsPerMin, 60) EndIf Case $Stop_Button _MidiOutReset ($open) AdlibDisable() EndSwitch EndFunc ;==>_ButtonHit Func _Beat() Local $Note = 0x99 + (77 * 256) + (127 * 0x10000) ;77 = Lo Woodblock If $BEAT_CNT > 0 Then If $BEAT_NUM = 1 Then $Note = 0x99 + (76 * 256) + (127 * 0x10000) ;76 = Hi Woodblock $BEAT_NUM += 1 If $BEAT_NUM > $BEAT_CNT Then $BEAT_NUM = 1 EndIf _MidiOutShortMsg ($open, $Note) EndFunc ;==>_Beat Func _Quit() _MidiOutClose ($open) Exit EndFunc ;==>_Quit Link to comment Share on other sites More sharing options...
PsaltyDS Posted August 7, 2007 Share Posted August 7, 2007 I modified PsaltyDS' metronome code above to make a MIDI metronome. MIDI UDF required: http://www.autoitscript.com/forum/index.ph...mp;#entry385157Nicely done! Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
czardas Posted August 8, 2007 Author Share Posted August 8, 2007 (edited) Here's the wav file I was using. Sorry about the delay, I have been busy lately. I tried to post this a few days ago [see above], but something went wrong. This business of using DLLcall: How do I know which DLL to call? I've never done it. Edited August 8, 2007 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
czardas Posted August 8, 2007 Author Share Posted August 8, 2007 (edited) I modified PsaltyDS' metronome code above to make a MIDI metronome. MIDI UDF required: http://www.autoitscript.com/forum/index.ph...mp;#entry385157Thanks again to all. However I don't seem to get anything from this code. I have downloaded the midiUDF but I don't get a GUI? Nothing happens at all. Ok I should be able to figure it out, after all your efforts. Edited August 9, 2007 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
PsaltyDS Posted August 9, 2007 Share Posted August 9, 2007 Thanks again to all. However I don't seem to get anything from this code. I have downloaded the midiUDF but I don't get a GUI? Nothing happens at all. Ok I should be able to figure it out, after all your efforts.GMK's version works great for me, and it doesn't need any external sound files, so it's a great solution.When you run it from SciTE, to you get any errors on Syntax Check or in the console? Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
czardas Posted August 9, 2007 Author Share Posted August 9, 2007 (edited) GMK's version works great for me, and it doesn't need any external sound files, so it's a great solution. When you run it from SciTE, to you get any errors on Syntax Check or in the console? The only thing I get is the task bar icon, which tells me that the script is running. It may have something to do with windows 2000 operating system, which I am using at the moment. I can try it on XP. Perhaps that's the problem? I'll let you know how I get on. Actually yes there are errors See below: >C:\Program Files\AutoIt3\SciTE\..\au3check.exe "C:\Documents and Settings\Administrator\My Documents\metro2.au3" AutoIt3 Syntax Checker v1.54 Copyright © Tylo 2006 C:\Documents and Settings\Administrator\My Documents\midiudf.au3(34,104) : WARNING: $MIDI_UNCACHE: possibly used before declaration. Const $MIDI_CACHE_VALID = ($MIDI_CACHE_ALL Or $MIDI_CACHE_BESTFIT Or $MIDI_CACHE_QUERY Or $MIDI_UNCACHE) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~^ C:\Documents and Settings\Administrator\My Documents\midiudf.au3(1049,19) : WARNING: $getmmsyserr: possibly used before declaration. if $getmmsyserr = ~~~~~~~~~~~~~~~~^ C:\Documents and Settings\Administrator\My Documents\midiudf.au3(1076,34) : ERROR: DllStructGetData() [built-in] called with wrong number of args. $get = Dllstructgetdata($struct) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^ C:\Documents and Settings\Administrator\My Documents\midiudf.au3(1049,19) : ERROR: $getmmsyserr: undeclared global variable. if $getmmsyserr = ~~~~~~~~~~~~~~~~^ C:\Documents and Settings\Administrator\My Documents\metro2.au3 - 2 error(s), 2 warning(s) >Exit code: 2 Time: 0.449 Edited August 9, 2007 by czardas operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
DW1 Posted August 9, 2007 Share Posted August 9, 2007 You included the midi au3 and you get these errors? What version number AutoIt3 are you running? AutoIt3 Online Help Link to comment Share on other sites More sharing options...
czardas Posted August 9, 2007 Author Share Posted August 9, 2007 You included the midi au3 and you get these errors?What version number AutoIt3 are you running?v3.2.4.9 operator64 ArrayWorkshop Link to comment Share on other sites More sharing options...
DW1 Posted August 9, 2007 Share Posted August 9, 2007 put the midiudf.au3 in the Autoit "Include" folder. Make sure that the includes are still at the top of the page. Make sure you are using the right include as well. I included the midiudf.au3 that everybody is using as an attachment, I would suggest deleting the old one and using this one in case thats the issue. AutoIt3 Online Help Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now