forked from bookdude13/midilights
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1e013ad
commit 3435815
Showing
3 changed files
with
95 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,25 @@ | ||
# midi-lightshow | ||
|
||
``` | ||
Usage: | ||
midils.py list [<backend>] | ||
midils.py run <midi-input> <dmx> <config> [<backend>] | ||
midils.py run (-d || --dry) <midi-input> <config> [<backend>] | ||
Options: | ||
<backend> Mido backend to use [default: 'mido.backends.portmidi'] | ||
<config> Path to output configuration file | ||
<dmx> Path to dmx output device (/dev/ttyUSB* on Unix, COM* on Windows) | ||
-d, --dry Dry run (output to logger) | ||
-h --help Show this text | ||
--version Show version | ||
``` | ||
|
||
# Setting up (this was done on a Unix system. May be slightly different commands on Windows) | ||
Clone the repository: `git clone [email protected]:teslaworksumn/midi-lightshow.git` | ||
Setup submodules: `git submodule init && git submodule update` | ||
Install dependencies (may need to be run as root/sudo): `python3 setup.py install` | ||
If using the PortMidi backend (default), you must install PortMidi: `sudo apt install libportmidi-dev` | ||
Run: `make run` | ||
|
||
## Notes | ||
-This program currently uses the path /dev/ttyUSB0 for the DMX output. This can be changed in midils/midils.py, and will soon be a command line argument. | ||
-The machine this runs on should either have portmidi installed, or should [set up a different backend](https://mido.readthedocs.io/en/latest/backends.html) (this will require a change in midils.py as well) | ||
-The midi input chosen is the first one found by the backend. This has worked in the past, but may act inconsistently across different machines. | ||
-[Different mido backends] (https://mido.readthedocs.io/en/latest/backends.html) can be used |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,99 @@ | ||
#!/usr/bin/env python3 | ||
import os | ||
import mido | ||
from docopt import docopt | ||
from IoThread import IoThread | ||
from mapper import Mapper | ||
from plugins import Dmx as OutDmx | ||
from plugins import Log as OutLog | ||
from mapper import Mapper | ||
|
||
|
||
help_text = """MIDI Lightshow. | ||
Usage: | ||
midils.py list [<backend>] | ||
midils.py run <midi-input> <dmx> <config> [<backend>] | ||
midils.py run (-d || --dry) <midi-input> <config> [<backend>] | ||
Options: | ||
<backend> Mido backend to use [default: 'mido.backends.portmidi'] | ||
<config> Path to output configuration file | ||
<dmx> Path to dmx output device (/dev/ttyUSB* on Unix, COM* on Windows) | ||
-d, --dry Dry run (output to logger) | ||
-h --help Show this text | ||
--version Show version | ||
""" | ||
|
||
channel_outputs = [] | ||
|
||
|
||
def main(): | ||
dmx = OutDmx() | ||
dmx.setPort('/dev/ttyUSB0') | ||
dmx.connect() | ||
vixenlog = OutLog() | ||
# DMX is 1-indexed | ||
out_function = lambda channels: dmx.sendDMX([ch + 1 for ch in channels]) | ||
#out_function = vixenlog.send | ||
dir_path = os.path.dirname(os.path.realpath(__file__)) | ||
config_path = dir_path + '/configs/octaves.json' | ||
mapper = Mapper(config_path) | ||
# Parse arguments | ||
arguments = docopt(help_text) | ||
|
||
backend = mido.Backend(arguments['<backend>']) | ||
|
||
try: | ||
# Setup midi input | ||
backend_portmidi = mido.Backend('mido.backends.portmidi') | ||
inputs = backend_portmidi.get_input_names() | ||
if (arguments['list']): | ||
inputs = backend.get_input_names() | ||
print(inputs) | ||
elif (arguments['run']): | ||
input_name = arguments['<midi-input>'] | ||
mapper = get_mapper(arguments) | ||
(out_fn, cleanup_fn) = get_run_type_functions(arguments) | ||
|
||
run(input_name, mapper, backend, out_fn, cleanup_fn) | ||
else: | ||
print("How did we get here?? (docopt failed us or command not accounted for)") | ||
|
||
|
||
# Runs midi-lightshow with a light channel mapper, a mido backend, a | ||
# unary function to handle output, and a zero-ary function to do any necessary cleanup | ||
def run(input_name, mapper, mido_backend, out_fn, cleanup_fn): | ||
try: | ||
# Start listening for midi | ||
input_thread = IoThread(backend_portmidi, inputs[0], out_function, mapper) | ||
input_thread = IoThread(mido_backend, input_name, out_fn, mapper) | ||
input_thread.start() | ||
# Wait until user exits | ||
print("Enter 'exit' to stop the program") | ||
while input("Command: ") != 'exit': | ||
pass | ||
# Cleanup | ||
input_thread.stop() | ||
dmx.disconnect() | ||
cleanup_fn() | ||
except Exception as e: | ||
print(e) | ||
|
||
main() | ||
|
||
# Returns the output function and cleanup function associated with the run type, | ||
# which is determined by the user provided arguments. Dry run uses a logger, | ||
# normal run uses a DMX output plugin | ||
def get_run_type_functions(arguments): | ||
if arguments['--dry']: | ||
vixenlog = OutLog() | ||
out_fn = vixenlog.send | ||
cleanup_fn = lambda: None # No cleanup needed | ||
else: | ||
dmx = OutDmx() | ||
dmx_port = arguments['<dmx>'] | ||
dmx.setPort(dmx_port) | ||
dmx.connect() | ||
# DMX is 1-indexed | ||
out_fn = lambda channels: dmx.sendDMX([ch + 1 for ch in channels]) | ||
cleanup_fn = dmx.disconnect | ||
|
||
return (out_fn, cleanup_fn) | ||
|
||
|
||
# Gets the output mapper from the user provided config file. Checks if path to said | ||
# config file exists as well. Returns the mapper if everything worked, None if problem/not found | ||
def get_mapper(arguments): | ||
config_file = arguments['<config>'] | ||
dir_path = os.path.dirname(os.path.realpath(__file__)) | ||
config_path = dir_path + '/configs/' + config_file | ||
mapper = Mapper(config_path) | ||
return mapper | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,12 +2,12 @@ | |
|
||
setup( | ||
name='midi-lightshow', | ||
version='0.1.0', | ||
version='0.2.0', | ||
author='Ryan Fredlund', | ||
author_email='[email protected]', | ||
packages=['midils'], | ||
url='https://github.com/bookdude13/midi-lightshow', | ||
url='https://github.com/teslaworksumn/midi-lightshow', | ||
license='LICENSE', | ||
description='Interface between a midi keyboard and some dmx-controlled lights', | ||
install_requires=['mido', 'pyserial'] | ||
install_requires=['docopt', 'mido', 'pyserial'] | ||
) |