Skip to content

V0.3 #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
393609e
feat: Implemented virtual midi ports
Maboroshy May 1, 2024
bbd8943
feat: Show virtual midi ports in widget
Maboroshy May 1, 2024
3b07b91
fix: Fix issue with SavedCheckedStateAction setChecked state loading …
Maboroshy May 1, 2024
b454afb
fix: Fix boolean values loading from QSettings
Maboroshy May 1, 2024
0e2b815
fix: Remove unnecessary typing imports
Maboroshy May 1, 2024
a771b75
ci: Add ruff check
Maboroshy May 1, 2024
8246d21
feat: Implemented autostart for all platforms (darwin is untested)
Maboroshy May 4, 2024
5fb8048
ci: Added both check and format to ruff action
Maboroshy May 4, 2024
bf12cb8
fix: remove useless imports
Maboroshy May 4, 2024
3ff25bf
fix: Fix port send and port re-enable issues
Maboroshy May 5, 2024
56cc39b
refactor: Moved autostart to class in shared.py
Maboroshy May 6, 2024
904ec03
feat: Make sysex msg attrs represent universal messages
Maboroshy May 6, 2024
a5bc19b
fix: Handle no script path situation correctly
Maboroshy May 6, 2024
fe47277
docs: Remove loopMIDI from scripts readmes since midiscripter is cros…
Maboroshy May 6, 2024
e865b94
docs: New Controls Layers example
Maboroshy May 6, 2024
4ebdf2b
fix: Don't allow unhashable as GUI widget content attribute
Maboroshy May 6, 2024
559b1b8
docs: Update README.md
Maboroshy May 6, 2024
74d58c2
docs: Update README.md
Maboroshy May 6, 2024
ea2e895
fix: Filled and corrected all type annotations
Maboroshy May 6, 2024
129334b
docs: Minor fixes
Maboroshy May 6, 2024
f9c0e75
docs: Major changes to Guide
Maboroshy May 6, 2024
dae76e1
ci: Add 'ruff' dependency
Maboroshy May 6, 2024
47e038f
ci: Add annotations check
Maboroshy May 6, 2024
d652586
ci: Bumped version to 0.3
Maboroshy May 6, 2024
027293a
docs: Improve docs
Maboroshy May 7, 2024
c26f895
fix: Make running from IPython or another process raise RuntimeError
Maboroshy May 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/ruff.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ jobs:
- uses: actions/checkout@v4
- uses: chartboost/ruff-action@v1
with:
args: 'format --check'
args: 'check'
- uses: chartboost/ruff-action@v1
with:
args: 'format'
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Changelog

## v0.3 - 07.05.2024

### Added

- Linux and macOS support.
- On Linux and macOS declaration of unavailable MIDI port will create a virtual
port that show up in ports widget with `[v]` prefix.

## Fixed

- MIDI port send issues
- Sending with closed port behaviour
- Port re-enabling behaviour
- Running starter from IPython now raises exception.

## v0.2 - 30.04.2024

Initial release
101 changes: 69 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
# MIDI Scripter

MIDI Scripter is a framework for scripting MIDI, keyboard and Open Sound Control (OSC) input and output with a few lines of Python code.
MIDI Scripter is a framework for scripting MIDI, keyboard and Open Sound
Control (OSC) input and output with only a few lines of Python code.

MIDI Scripter is intended for digital audio workstation (DAW) controls scripting but can also be used for general input conversion and automation. It fits where controller mappings are not enough but rewriting DAW controller integration is too much.
MIDI Scripter listens to selected input ports and feed incoming messages to
subscribed callables (functions, methods, etc.). These callables or any
other Python code can send modified or brand-new messages with
output ports. MIDI Scripter can act as a proxy to filter and transform and
convert the input.

MIDI Scripter included customizable GUI that provides messages logging,
"ready to paste" port and message declarations and one line of code widgets for
monitoring / controlling scripts.

An octave transposer with GUI controls in 10 lines of code:

``` python
from midiscripter import * # safe * import with no bloat
from midiscripter import *

midi_keyboard = MidiIn('Port name') # GUI will provide you with port names
proxy_output = MidiOut('loopMIDI Port') # using loopMIDI virtual port for output
midi_keyboard = MidiIn('MIDI Keyboard') # GUI will provide you with port names
proxy_output = MidiOut('To DAW') # using virtual port for output

# GUI control in a single line, many widget available, custom widgets supported
# GUI control in a single line
octave_selector = GuiButtonSelectorH(('-2', '-1', '0', '+1', '+2'), select='0')

@midi_keyboard.subscribe # decorated function will receive port's messages
Expand All @@ -25,42 +34,70 @@ if __name__ == '__main__': # combine multiple scripts by importing them
start_gui() # opens helpful customizable GUI
```

![Screenshot](https://github.com/Maboroshy/midi-scripter/blob/master/examples/octave_transposer/screenshot.png?raw=true)
![Screenshot after some widget arrangement](https://github.com/Maboroshy/midi-scripter/blob/master/examples/octave_transposer/screenshot.png?raw=true)

[You can find more examples here.](https://github.com/Maboroshy/midi-scripter/tree/master/examples)

[Scripting guide and API documentation available.](https://maboroshy.github.io/midi-scripter)

Currently MIDI Scripter is at "beta" development stage. It's fully functional but needs some more testing. It targets only Windows for now. Linux and macOS support will follow.
Currently MIDI Scripter is at "beta" development stage. It's fully
functional but needs more user feedback. It works on Windows and Linx and
should work on macOS.

## What it can do

For writing Python code:

- Prepare MIDI, OSC and keyboard inputs and outputs with a single line,
without boilerplate code.
- Feed input messages to functions or any callables by "decorating" them.
- Work with common message objects instead of raw data different for each port
type.
- Send MIDI, OSC and keyboard output messages.
- Create GUI widgets with one line and arrange them with mouse on your script's
dashboard.

For live performance setups:

## Features
Easy tasks for MIDI Scripter:
1. Filter, modify and route MIDI, OSC and keyboard messages in any way.
2. Map MIDI, OSC and keyboard to each other.
3. Map any Python code to input message.
4. Make extra "shift" keys to multiply MIDI controls.
5. Organize mappings into sets / scenes with GUI controls.
6. Make an extra overlay mappings on top of MIDI controller's default DAW integration by using proxy.
- Make extra layers to multiply MIDI controls.
- Organize mappings into sets / scenes with GUI dashboard.
- Make an extra overlay mappings on top of MIDI controller's DAW integration by
using proxies.
- Create and map complex macros.

Complex tasks for MIDI Scripter:
1. Create and map complex macros involving multiple hardware or virtual MIDI controllers.
2. Make custom sequencer or MIDI input generator.
3. Make music education or trainer GUI application based on MIDI input.
For MIDI related apps:

- Make custom sequencers or MIDI output generators.
- Make basic music training GUI applications based on MIDI input.

For software control and automation:

- Use MIDI controllers or keyboard shortcuts to run any Python code.
- Use keyboard macros to control apps.

## Installation
1. [Python 3.11+](https://www.python.org/downloads/) with "Add python.exe to PATH" option.
2. [loopMIDI](https://www.tobias-erichsen.de/software/loopmidi.html) for virtual MIDI output ports on Windows.
3. `pip install midiscripter` in console.

## Setup
Run loopMIDI and add virtual ports you want to send MIDI messages. You can enable its autostart option.
1. Install [Python 3.11+](https://www.python.org/downloads/) including pip.
2. Run `pip install midiscripter`.

Enable virtual MIDI output ports as MIDI inputs in DAW.
Extra steps for Windows:

1. Enable `Add python .exe to PATH` option in Python installer.
2. Install [loopMIDI](https://www.tobias-erichsen.de/software/loopmidi.html)
and set required virtual MIDI ports inside it.

## Quick Start
1. Paste [script template](examples/script_template.py) to Python IDE or plain text editor. IDE is greatly recommended.
2. Run unchanged template script from IDE or by `python .\script_template.py` to open GUI for more info on available ports and their input.
3. Turn on the ports' checkboxes to enable them and watch the log for input messages.
4. Click on port names and messages to copy their declarations to the clipboard. Paste the declarations to your script.
5. Write the functions you need. Subscribe them to messages with `@input_port.subscribe` decorator. Use `log('messages')` for debugging. Use `output_port.send(msg)` to send modified or created messages from a function.
6. Restart the script from GUI.

1. Paste [script template](examples/script_template.py) to Python IDE or plain
text editor. IDE is greatly recommended.
2. Run unaltered template script from IDE or by `python` command to open GUI for
more info on available ports and their input.
3. Turn on available ports' checkboxes to enable them, and watch the log for
input messages.
4. Click on port names and messages to copy their declarations to the clipboard.
Paste the declarations to your script.
5. Write the functions you need. Subscribe them to input messages with
`@input_port.subscribe` decorator. Use `log('messages')` for debugging.
Use `output_port.send(msg)` to send modified or created messages from a
function.
6. Restart the script from GUI to check how in works.
Loading