MIDI module and docs
This commit is contained in:
parent
de1d602b25
commit
e52af4f58a
18
docs/midi.md
Normal file
18
docs/midi.md
Normal file
@ -0,0 +1,18 @@
|
||||
# MIDI
|
||||
The MIDI module adds keymap entries for sending MIDI data streams. It will require adding the `adafruit_midi` library from the [Adafruit CircuitPython Bundle](https://circuitpython.org/libraries) to your device's folder.
|
||||
Add it to your keyboard's modules list with:
|
||||
|
||||
```python
|
||||
from kmk.modules.midi import MidiKeys
|
||||
keyboard.modules.append(MidiKeys())
|
||||
```
|
||||
## Keycodes
|
||||
|
||||
|Key |Description |
|
||||
|-----------------|------------------------------------------------------------------------|
|
||||
|`KC.MIDI_CC()` |Sends a ControlChange message; accepts two integer arguments of `0`-`15`(controller number) then `0`-`127`(control value) |
|
||||
|`KC.MIDI_NOTE()` |Sends a Note message with both 'On' and 'Off' segments; accepts two integer arguments of `0`-`127`(note number) and `0`-`127`(velocity) |
|
||||
|`KC.MIDI_PB()` |Sends a Pitch Wheel message; accepts a single integer argument of `0`-`16383`, centered on `8192` |
|
||||
|`KC.MIDI_PC()` |Sends a Program Change message; accepts a single integer argument of `0`-`127`(program number) |
|
||||
|`KC.MIDI_START()` |Sends a Start message; accepts no arguments |
|
||||
|`KC.MIDI_STOP()` |Sends a Stop message; accepts no arguments |
|
@ -4,20 +4,27 @@ the ability to alter the core code in any way. Unlike extensions, these are not
|
||||
sandbox, and can make massive changes to normal operation.
|
||||
|
||||
## Core Modules
|
||||
These modules are proveded in all builds and can be enabled. Currently offered
|
||||
These modules are provided in all builds and can be enabled. Currently offered
|
||||
modules are
|
||||
|
||||
- [Layers](layers.md): Adds layer support (Fn key) to allow many more keys to be
|
||||
put on your keyboard
|
||||
put on your keyboard.
|
||||
- [ModTap](modtap.md): Adds support for augmented modifier keys to act as one key
|
||||
when tapped, and modifier when held.
|
||||
- [Mouse keys](mouse_keys.md): Adds mouse keycodes
|
||||
- [Mouse keys](mouse_keys.md): Adds mouse keycodes.
|
||||
- [OneShot](oneshot.md): Adds support for oneshot/sticky keys.
|
||||
- [Power](power.md): Power saving features. This is mostly useful when on battery power.
|
||||
- [Split](split_keyboards.md): Keyboards split in two. Seems ergonomic!
|
||||
- [TapDance](tapdance.md): Different key actions depending on how often it is pressed.
|
||||
|
||||
### Require Libraries
|
||||
These modules can be used without specific hardware, but require additional libraries such as the `Adafruit CircuitPython Bundle`.
|
||||
|
||||
- [MIDI](midi.md): Adds sending MIDI data in the form of keymap entries.
|
||||
|
||||
|
||||
### Peripherals
|
||||
- [ADNS9800](adns9800.md): Controlling ADNS9800 optical sensor
|
||||
- [Encoder](encoder.md): Handling rotary encoders
|
||||
- [Pimoroni trackball](pimoroni_trackball.md): Handling a small I2C trackball made by Pimoroni
|
||||
These modules are for specific hardware and may require additional libraries to function.
|
||||
- [ADNS9800](adns9800.md): Controlling ADNS9800 optical sensor.
|
||||
- [Encoder](encoder.md): Handling rotary encoders.
|
||||
- [Pimoroni trackball](pimoroni_trackball.md): Handling a small I2C trackball made by Pimoroni.
|
||||
|
108
kmk/modules/midi.py
Normal file
108
kmk/modules/midi.py
Normal file
@ -0,0 +1,108 @@
|
||||
# Originally put together by xs5871 on the KMK Firmware Discord/Matrix channel
|
||||
|
||||
import usb_midi
|
||||
|
||||
from kmk.modules import Module
|
||||
from kmk.keys import make_argumented_key
|
||||
|
||||
import adafruit_midi
|
||||
from adafruit_midi.control_change import ControlChange
|
||||
from adafruit_midi.note_off import NoteOff
|
||||
from adafruit_midi.note_on import NoteOn
|
||||
from adafruit_midi.pitch_bend import PitchBend
|
||||
from adafruit_midi.program_change import ProgramChange
|
||||
from adafruit_midi.start import Start
|
||||
from adafruit_midi.stop import Stop
|
||||
|
||||
|
||||
class midiNoteValidator:
|
||||
def __init__(self, note=69, velocity=64, channel=None):
|
||||
self.note = note
|
||||
self.velocity = velocity
|
||||
self.channel = channel
|
||||
|
||||
|
||||
class MidiKeys(Module):
|
||||
def __init__(self):
|
||||
make_argumented_key(
|
||||
names=('MIDI_CC',),
|
||||
validator=ControlChange,
|
||||
on_press=self.on_press,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
names=('MIDI_NOTE',),
|
||||
validator=midiNoteValidator,
|
||||
on_press=self.note_on,
|
||||
on_release=self.note_off,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
names=('MIDI_PB',),
|
||||
validator=PitchBend,
|
||||
on_press=self.on_press,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
names=('MIDI_PC',),
|
||||
validator=ProgramChange,
|
||||
on_press=self.on_press,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
names=('MIDI_START',),
|
||||
validator=Start,
|
||||
on_press=self.on_press,
|
||||
)
|
||||
|
||||
make_argumented_key(
|
||||
names=('MIDI_STOP',),
|
||||
validator=Stop,
|
||||
on_press=self.on_press,
|
||||
)
|
||||
|
||||
try:
|
||||
self.midi = adafruit_midi.MIDI(
|
||||
midi_out=usb_midi.ports[1], out_channel=0
|
||||
)
|
||||
except IndexError:
|
||||
self.midi = None
|
||||
# if debug_enabled:
|
||||
print('No midi device found.')
|
||||
|
||||
def during_bootup(self, keyboard):
|
||||
return None
|
||||
|
||||
def before_matrix_scan(self, keyboard):
|
||||
return None
|
||||
|
||||
def after_matrix_scan(self, keyboard):
|
||||
return None
|
||||
|
||||
def process_key(self, keyboard, key, is_pressed, int_coord):
|
||||
return key
|
||||
|
||||
def before_hid_send(self, keyboard):
|
||||
return None
|
||||
|
||||
def after_hid_send(self, keyboard):
|
||||
return None
|
||||
|
||||
def on_powersave_enable(self, keyboard):
|
||||
return None
|
||||
|
||||
def on_powersave_disable(self, keyboard):
|
||||
return None
|
||||
|
||||
def send(self, message):
|
||||
if self.midi:
|
||||
self.midi.send(message)
|
||||
|
||||
def on_press(self, key, keyboard, *args, **kwargs):
|
||||
self.send(key.meta)
|
||||
|
||||
def note_on(self, key, keyboard, *args, **kwargs):
|
||||
self.send(NoteOn(key.meta.note, key.meta.velocity, channel=key.meta.channel))
|
||||
|
||||
def note_off(self, key, keyboard, *args, **kwargs):
|
||||
self.send(NoteOff(key.meta.note, key.meta.velocity, channel=key.meta.channel))
|
Loading…
Reference in New Issue
Block a user