A Macro Player That Fixes Broken Macros

This forum is a catch all for all posts that do not belong in other forums.

A Macro Player That Fixes Broken Macros

Postby Technicality » Mon Mar 01, 2021 1:35 am

Hello!
I wanted to share my first attempt at a macro player that (mostly) fixes any broken macro. Unfortunately, this isn't even close to perfect and the fixes will make many songs have a more erratic tempo.

Similarly to my Mixed Macro Program, this features a "Delay" variable, which by default is set to 80, but you can increase or decrease the delay based on how high/low your ping is. To change the Delay, simply open the file in notepad, located "Delay = 80" Increase the Delay if you are experiencing skipped octaves, decrease the delay if you aren't. You'll likely end up with a Delay between 25-200. I highly recommend you tweak the Delay until you have it at the absolute lowest value that doesn't cause octave skips.

How to use:
Put the Macro Player script in the same folder that you keep all of your macro .ahk files. If it isn't it the same folder it won't work.
Type the name of the macro you'd like to play into the "Song Name" box. You must type the name exactly how the original ahk file is named otherwise it won't work.
Press F1 to play, F2 to pause, F3 to exit the script

*Note* The only way to "fix" a macro is to change the original Abc code so that it doesn't require excessive octave swapping. This script simply shuffles around the sleep durations/octave swaps slightly to optimize their order of execution, while also setting a hard limit for the minimum time between octave swaps. The ideal solution to fixing macros would involve a much more in depth. If people are interested in a macro player that does this, then leave some feedback in the comments. Something like this would likely take me quite a while, so I'm not going to spend the time on it unless there's enough interest for it.

Link for macro player:
http://www.mediafire.com/file/9seg1fm9505w5zr/Macro_Player.ahk/file
Technicality
 
Posts: 6
Joined: Thu Feb 25, 2021 11:04 pm

Re: A Macro Player That Fixes Broken Macros

Postby Technicality » Mon Mar 01, 2021 1:46 am

Here's the code for the macro player in case you'd rather just copy/paste it into your own ahk script instead

#NoEnv
#MaxHotkeysPerInterval 99000000
#HotkeyInterval 99000000
#KeyHistory 0
#singleinstance force
ListLines Off
Process, Priority, , High
SetBatchLines, -1
SetKeyDelay, -1
SetMouseDelay, -1
SetDefaultMouseSpeed, 0
SetWinDelay, -1
SetControlDelay, -1
Gui, Add, Text,, Type Song Name Below
Gui, Add, Edit, w300 vSongName,
Gui, Add, Text,, Controls
Gui, Add, Text,, F1 pauses the app
Gui, Add, Text,, F2 pauses the app
Gui, Add, Text,, F3 closes the app
Gui, SongProgress:Add, Edit, w400 h300 vSheetProgress
StringCaseSense, On
Keys := []
noteOrSleep := []
KeysToPlay := []
SleepNext := []
nkey = 0
global notif := false
nchord := ""
rest = 0




;~~~~~~~~~~~~~~~~Adjust Delay Variable~~~~~~~~~~~~~
global Delay = 80
;~~~~~~~~~~~~~~~~Adjust Delay Variable~~~~~~~~~~~~~






global Delay2 := Delay / 10
global isSleep := false
counter := new SecondCounter
hotkey, F2, pauseScript
Gui, Show
F1::
global isSleep, notif
Gui, Submit, Nohide
FileDelete, Sheet Music/%SongName%.txt
Loop, read, %SongName%.ahk
{
Loop, parse, A_LoopReadLine, %A_Space%
{
var = %A_Loopfield%
if (isSleep = true){
if(notif = true){
nChord := ""
}
if (nChord > ""){
Keys.Push(nChord)
NoteOrSleep.Push(1)
nChord := ""
}
Keys.Push(var)
NoteOrSleep.Push(0)
isSleep := false
notif := false
}else if (notif = true){
if (nChord > ""){
Keys.Push(nChord)
NoteOrSleep.Push(1)
nChord := ""
}
notif := false
}else{
if (var = "{Numpad1"){
nkey = 1
}
if (var = "{Numpad2"){
nkey = 2
}
if (var = "{Numpad3"){
nkey = 3
}
if (var = "{Numpad4"){
nkey = 4
}
if (var = "{Numpad5"){
nkey = 5
}
if (var = "{Numpad6"){
nkey = 6
}
if (var = "{Numpad7"){
nkey = 7
}
if (var = "{Numpad8"){
nkey = 8
}
if (var = "{Numpad9}"){
nkey = 0
nchord := nchord . nKey
notif := true
}
if (var = "{Numpad0}"){
nkey = 9
nchord := nchord . nKey
notif := true
}
if (var = "down}"){
nchord := nchord . nKey
}
if (var = "up}"){
notif := true
}
}
if (var = "Sleep,"){
isSleep := true
}
}
}
klen := Keys.Length()
nlen := NoteOrSleep.Length()
Gui, Font, s12, Verdana
;Gui, SongProgress:Show,,Sheet Music
toLoop = 1
Loop %klen%
{
isNote := NoteOrSleep[toLoop]
toPlay := Keys[toLoop]
isNextNote := NoteOrSleep[toLoop + 1]
toPlayNext := Keys[toLoop + 1]
if (isNote = 0){
if ((toPlayNext = 0) || (toPlayNext = 9))
{
toSleep := toPlay - Delay
if (toSleep > 0)
{
KeysToPlay.Push(Delay)
SleepNext.Push(0)
KeysToPlay.Push(toPlayNext)
SleepNext.Push(1)
KeysToPlay.Push(toSleep)
SleepNext.Push(0)
toLoop++
}else{
KeysToPlay.Push(toPlay)
SleepNext.Push(0)
}
}else{
KeysToPlay.Push(toPlay)
SleepNext.Push(0)

}
}else{
KeysToPlay.Push(toPlay)
SleepNext.Push(1)
}
toLoop++
}
klen := KeysToPlay.Length()
nlen := SleepNext.Length()
Loop %klen%
{
toSheet := KeysToPlay[A_Index]
if StrLen(toSheet) > 1
{
toText .= "[" . KeysToPlay[A_Index] . "]" . " "
}else{
toText .= KeysToPlay[A_Index] . " "
}
}
;GuiControl,SongProgress:, SheetProgress, %toText%
Loop %klen%
{
isNote := SleepNext[A_Index]
toPlay := KeysToPlay[A_Index]
if (isNote = 1){
Loop, parse, toPlay
{
var := A_LoopField
if ((var = 9) || (var = 0))
{
if (counter.count > 0)
{
dif = %Delay%
dif -= (counter.count * 10)
;Msgbox, %dif%
Sleep, %dif%
}
counter.Stop()
counter.Start()
}
Send %var%
}
}else{
Sleep, %toPlay%
}
}
return



F3::ExitApp
pauseScript:
pause
return
GuiClose:
ExitApp

class SecondCounter {
__New() {
this.interval := 1
this.count := 1
; Tick() has an implicit parameter "this" which is a reference to
; the object, so we need to create a function which encapsulates
; "this" and the method to call:
this.timer := ObjBindMethod(this, "Tick")
}
Start() {
; Known limitation: SetTimer requires a plain variable reference.
timer := this.timer
this.count := 1
SetTimer % timer, % this.interval
;ToolTip % "Counter started"
}
Stop() {
; To turn off the timer, we must pass the same object as before:
timer := this.timer
this.count := 0
SetTimer % timer, Off
;ToolTip % "Counter stopped at " this.count
}
; In this example, the timer calls this method:
Tick() {
global Delay2
this.count++
if (this.count >= Delay2){
this.Stop()
this.count := 0
}
;ToolTip % this.count
}
}
Technicality
 
Posts: 6
Joined: Thu Feb 25, 2021 11:04 pm

Re: A Macro Player That Fixes Broken Macros

Postby JamesyBeanZ » Mon Jun 27, 2022 2:55 am

This is amazing code works 95% on all the old songs before the patch that caused the octave slips. Even works on my more complicated and what I thought was unplayable macros I've never made public. Great job!
JamesyBeanZ
 
Posts: 10
Joined: Tue Jun 21, 2016 7:16 am



Return to General Discussion



Who is online

Users browsing this forum: No registered users and 12 guests