diff --git a/OscCommentMacroListener.py b/OscCommentMacroListener.py index bd77b22..6232bc0 100644 --- a/OscCommentMacroListener.py +++ b/OscCommentMacroListener.py @@ -18,6 +18,7 @@ __status__ = "Prototype" import antlr4 from CommentMacroParser import CommentMacroParser from CommentMacroListener import CommentMacroListener +from OscMacroDefinitions import * from pythonosc import osc_message_builder from pythonosc import udp_client from time import sleep @@ -32,154 +33,6 @@ def num(string): return num -def _master_go(self, ctx): - if ctx.number is not None: - print("GO MASTER doesn't support goto. " - + "Cue number " + str(ctx.number.value) + " will be ignored.") - - if (len(ctx.master.targets) == 0): - print("Main GO") - self.button_press(ctx.device, "/hog/hardware/maingo") - return 1 - else: - for i in ctx.master.targets: - if isinstance(i, int) is not True: - print("GO MASTER macro targets must be intigers. " - + str(i) + " is not an intigers.") - continue - if (i < 0): - print("Master " + str(i) + " should have been greater than 0.") - continue - master = str(i) - print("GO on master " + master) - self.button_press(ctx.device, "/hog/hardware/go/" + master) - return 1 - - -def _master_halt(self, ctx): - if (len(ctx.master.targets) == 0): - print("Main HALT") - self.button_press(ctx.device, "/hog/hardware/mainhalt") - return 1 - else: - for i in ctx.master.targets: - if isinstance(i, int) is not True: - print("GO MASTER macro targets must be intigers. " - + str(i) + " is not an intigers.") - continue - if (i < 0): - print("Master " + str(i) + " should have been greater than 0.") - continue - master = str(i) - print("HALT on master " + master) - self.button_press(ctx.device, "/hog/hardware/pause/" + master) - return 1 - - -def _master_fade(self, ctx): - level = ctx.number.value - if (level < 0 or level > 100): - print("Level must be between 0 and 100.") - return -1 - if (len(ctx.master.targets) == 0): - print("MASTER FADE doesn't support unspecified current master.") - return -1 - else: - for i in ctx.master.targets: - if isinstance(i, int) is not True: - print("FADE MASTER macro targets must be intigers. " - + str(i) + " is not an intigers.") - continue - if (i < 0): - print("Master " + str(i) + " should have been greater than 0.") - continue - master = str(i) - print("Fade Master "+master+" to "+str(level)+"%") - level *= 255 / 100 # percent in Macro, 0>255 in OSC - self.send_message(ctx.device, "/hog/hardware/fader/"+master, level) - return 1 - - -def _master_fade_grand(self, ctx): - level = ctx.number.value - if (level < 0 or level > 100): - print("Level must be between 0 and 100.") - return -1 - print("Fading Grand Master to " + str(level) + "%") - level *= 255 / 100 # percent in Macro, 0>255 in OSC - self.send_message(ctx.device, "/hog/hardware/fader/0", level) - return 1 - - -def _master_choose(self, ctx): - if (ctx.number.value < 0): - print("Master must be greater than 0.") - return -1 - master = str(ctx.number.value) - print("Choose Master " + master) - self.button_press(ctx.device, "/hog/hardware/choose/" + master) - return 1 - - -def _list_go(self, ctx): - for i in ctx.targets: - list = str(i) - if ctx.number is not None: - list += "." + str(ctx.number.value) - print("Go on List " + list) - self.send_message(ctx.device, "/hog/playback/go/0", list) - return 1 - - -def _list_halt(self, ctx): - for i in ctx.targets: - print("Halting List " + str(i)) - self.send_message(ctx.device, "/hog/playback/halt/0", i) - return 1 - - -def _list_release(self, ctx): - for i in ctx.targets: - print("Releasing List " + str(i)) - self.send_message(ctx.device, "/hog/playback/release/0", i) - return 1 - - -def _scene_go(self, ctx): - for i in ctx.targets: - print("Go on Scene " + str(i)) - self.send_message(ctx.device, "/hog/playback/go/1", i) - return 1 - - -def _scene_halt(self, ctx): - for i in ctx.targets: - print("Halt Scene " + str(i)) - self.send_message(ctx.device, "/hog/playback/halt/1", i) - return 1 - - -def _scene_release(self, ctx): - for i in ctx.targets: - print("Release Scene " + str(i)) - self.send_message(ctx.device, "/hog/playback/release/1", i) - return 1 - - -command = {"GM": _master_go, - "HM": _master_halt, - "FM": _master_fade, - "FGM": _master_fade_grand, - "CM": _master_choose, - "GL": _list_go, - "HL": _list_halt, - "RL": _list_release, - "GS": _scene_go, - "HS": _scene_halt, - "RS": _scene_release - } - - # https://raw.githubusercontent.com/jszheng/py3antlr4book/master/bin/pygrun # this is a python version of TestRig def beautify_lisp_string(in_string): @@ -247,13 +100,15 @@ class OscCommentMacroListener(CommentMacroListener): print(beautify_lisp_string(lisp_tree_str)) # execute macro from name + ret = -1 name = ctx.children[0].getText() try: - command[name](self, ctx) + ret = command[name](self, ctx) except KeyError: print(name + " macro is not compatable with OSC.") return -1 print("Exiting Macro") + return ret def enterMaster(self, ctx: CommentMacroParser.MasterContext): ctx.targets = [] diff --git a/OscMacroDefinitions.py b/OscMacroDefinitions.py new file mode 100644 index 0000000..f0bdaa3 --- /dev/null +++ b/OscMacroDefinitions.py @@ -0,0 +1,163 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +"""OscMacroDefinitions.py: Hog 4 comment macros in OSC for Python3.""" + +__author__ = "Kevin Matz" +__copyright__ = "Copyright 2018, Company 235, LLC" +__credits__ = ["Kevin Matz"] + +__license__ = "MIT" +__version__ = "0.0.1" +__maintainer__ = "Kevin Matz" +__email__ = "kevin@company235.com" + +__status__ = "Prototype" + + +def _master_go(self, ctx): + if ctx.number is not None: + print("GO MASTER doesn't support goto. " + + "Cue number " + str(ctx.number.value) + " will be ignored.") + + if (len(ctx.master.targets) == 0): + print("Main GO") + self.button_press(ctx.device, "/hog/hardware/maingo") + return 1 + else: + for i in ctx.master.targets: + if isinstance(i, int) is not True: + print("GO MASTER macro targets must be intigers. " + + str(i) + " is not an intigers.") + continue + if (i < 0): + print("Master " + str(i) + " should have been greater than 0.") + continue + master = str(i) + print("GO on master " + master) + self.button_press(ctx.device, "/hog/hardware/go/" + master) + return 1 + + +def _master_halt(self, ctx): + if (len(ctx.master.targets) == 0): + print("Main HALT") + self.button_press(ctx.device, "/hog/hardware/mainhalt") + return 1 + else: + for i in ctx.master.targets: + if isinstance(i, int) is not True: + print("GO MASTER macro targets must be intigers. " + + str(i) + " is not an intigers.") + continue + if (i < 0): + print("Master " + str(i) + " should have been greater than 0.") + continue + master = str(i) + print("HALT on master " + master) + self.button_press(ctx.device, "/hog/hardware/pause/" + master) + return 1 + + +def _master_fade(self, ctx): + level = ctx.number.value + if (level < 0 or level > 100): + print("Level must be between 0 and 100.") + return -1 + if (len(ctx.master.targets) == 0): + print("MASTER FADE doesn't support unspecified current master.") + return -1 + else: + for i in ctx.master.targets: + if isinstance(i, int) is not True: + print("FADE MASTER macro targets must be intigers. " + + str(i) + " is not an intigers.") + continue + if (i < 0): + print("Master " + str(i) + " should have been greater than 0.") + continue + master = str(i) + print("Fade Master "+master+" to "+str(level)+"%") + level *= 255 / 100 # percent in Macro, 0>255 in OSC + self.send_message(ctx.device, "/hog/hardware/fader/"+master, level) + return 1 + + +def _master_fade_grand(self, ctx): + level = ctx.number.value + if (level < 0 or level > 100): + print("Level must be between 0 and 100.") + return -1 + print("Fading Grand Master to " + str(level) + "%") + level *= 255 / 100 # percent in Macro, 0>255 in OSC + self.send_message(ctx.device, "/hog/hardware/fader/0", level) + return 1 + + +def _master_choose(self, ctx): + if (ctx.number.value < 0): + print("Master must be greater than 0.") + return -1 + master = str(ctx.number.value) + print("Choose Master " + master) + self.button_press(ctx.device, "/hog/hardware/choose/" + master) + return 1 + + +def _list_go(self, ctx): + for i in ctx.targets: + list = str(i) + if ctx.number is not None: + list += "." + str(ctx.number.value) + print("Go on List " + list) + self.send_message(ctx.device, "/hog/playback/go/0", list) + return 1 + + +def _list_halt(self, ctx): + for i in ctx.targets: + print("Halting List " + str(i)) + self.send_message(ctx.device, "/hog/playback/halt/0", i) + return 1 + + +def _list_release(self, ctx): + for i in ctx.targets: + print("Releasing List " + str(i)) + self.send_message(ctx.device, "/hog/playback/release/0", i) + return 1 + + +def _scene_go(self, ctx): + for i in ctx.targets: + print("Go on Scene " + str(i)) + self.send_message(ctx.device, "/hog/playback/go/1", i) + return 1 + + +def _scene_halt(self, ctx): + for i in ctx.targets: + print("Halt Scene " + str(i)) + self.send_message(ctx.device, "/hog/playback/halt/1", i) + return 1 + + +def _scene_release(self, ctx): + for i in ctx.targets: + print("Release Scene " + str(i)) + self.send_message(ctx.device, "/hog/playback/release/1", i) + return 1 + + +command = {"GM": _master_go, + "HM": _master_halt, + "FM": _master_fade, + "FGM": _master_fade_grand, + "CM": _master_choose, + "GL": _list_go, + "HL": _list_halt, + "RL": _list_release, + "GS": _scene_go, + "HS": _scene_halt, + "RS": _scene_release + } diff --git a/README.md b/README.md index 4c60ce4..a5a4034 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A theoretical exersise to control a Hog 4 via OSC, with comment macros. -The comment macro grammer described in `CommentMacro.g4` is based upon the Hog 3.9 manual, Chapter 22.4. The python implementation in `OscCommentMacroListener.py` is based on Chapter 24.2 in the same manual. +The comment macro grammer described in `CommentMacro.g4` is based upon the Hog 3.9 manual, Chapter 22.4. The python3 implementation in `OscMacroDefinitions.py` is based on Chapter 24.2 in the same manual. Some macros are unsupported/unsupportable with this method. Some macro freatures, like timing, are not yet implemented. Refer to the **Features** table for specific notes.