[orx-midi] Update README.md, demos and docstrings

This commit is contained in:
Edwin Jakobs
2023-04-29 09:51:45 +02:00
parent 0dae37c0d5
commit 0353b923e3
8 changed files with 115 additions and 33 deletions

View File

@@ -3,19 +3,19 @@
MIDI support for keyboards and controllers. Send and receive note and control change events.
Bind inputs to variables.
Orx-midi is a wrapper around javax.midi.
Orx-midi is a wrapper around `javax.midi`.
## Usage
```kotlin
// -- list all midi devices
MidiDeviceDescription.list().forEach {
listMidiDevices().forEach {
println("${it.name}, ${it.vendor} r:${it.receive} t:${it.transmit}")
}
// -- open a midi controller and listen for control changes
val dev = MidiTransceiver.fromDeviceVendor(this, "BCR2000 [hw:2,0,0]", "ALSA (http://www.alsa-project.org)")
val dev = openMidiDevice("BCR2000 [hw:2,0,0]")
dev.controlChanged.listen {
println("${it.channel} ${it.control} ${it.value}")
}

View File

@@ -1,33 +1,37 @@
import org.openrndr.application
import org.openrndr.color.ColorRGBa
import org.openrndr.extra.midi.MidiTransceiver
import org.openrndr.extra.midi.bindMidiControl
import org.openrndr.extra.midi.openMidiDevice
import org.openrndr.extra.parameters.ColorParameter
import org.openrndr.extra.parameters.DoubleParameter
import org.openrndr.math.Vector2
/**
* Demonstration of two-way binding using [bindMidiControl]
*/
fun main() {
application {
program {
val midi = MidiTransceiver.fromDeviceVendor(this,"MIDI2x2 [hw:3,0,0]", "ALSA (http://www.alsa-project.org)")
val midi = openMidiDevice("MIDI2x2 [hw:3,0,0]")
val settings = object {
@DoubleParameter("radius", 0.0, 100.0)
var radius = 0.0
@DoubleParameter("x", -100.0, 100.0)
var x = 0.0
@DoubleParameter("y", -100.0, 100.0)
var y = 0.0
@ColorParameter("fill")
var color = ColorRGBa.WHITE
}
bindMidiControl(settings::radius, midi, 0, 1)
bindMidiControl(settings::x, midi, 0, 2)
bindMidiControl(settings::y, midi, 0, 3)
bindMidiControl(settings::color, midi, 0, 4)
extend {
drawer.fill = settings.color
drawer.circle(drawer.bounds.center + Vector2(settings.x, settings.y), settings.radius)

View File

@@ -0,0 +1,19 @@
import org.openrndr.application
import org.openrndr.extra.midi.MidiConsole
import org.openrndr.extra.midi.listMidiDevices
import org.openrndr.extra.midi.openMidiDevice
/**
* Demonstration of [MidiConsole]
*/
fun main() {
application {
program {
listMidiDevices().forEach { println(it.toString()) }
val midi = openMidiDevice("Launchpad [hw:4,0,0]")
extend(MidiConsole()) {
register(midi)
}
}
}
}

View File

@@ -1,16 +0,0 @@
import org.openrndr.application
import org.openrndr.extra.midi.MidiConsole
import org.openrndr.extra.midi.MidiDeviceDescription
import org.openrndr.extra.midi.MidiTransceiver
fun main() {
application {
program {
MidiDeviceDescription.list().forEach { println(it.toString()) }
val midi = MidiTransceiver.fromDeviceVendor(this,"Launchpad [hw:4,0,0]", "ALSA (http://www.alsa-project.org)")
extend(MidiConsole()) {
register(midi)
}
}
}
}

View File

@@ -27,6 +27,14 @@ fun bindMidiNote(on: () -> Unit, off: () -> Unit, transceiver: MidiTransceiver,
}
}
/**
* Bind MIDI control change to [Double] property
* @param property the [KMutableProperty0] to bind to
* @param transceiver the midi device to bind to
* @param channel the midi channel to use
* @param control the midi control to use
* @since 0.4.3
*/
@JvmName("bindMidiControlDouble")
fun Program.bindMidiControl(
property: KMutableProperty0<Double>,
@@ -58,6 +66,14 @@ fun Program.bindMidiControl(
}
}
/**
* Bind MIDI control change to [Boolean] property
* @param property the [KMutableProperty0] to bind to
* @param transceiver the midi device to bind to
* @param channel the midi channel to use
* @param control the midi control to use
* @since 0.4.3
*/
@JvmName("bindMidiControlBoolean")
fun Program.bindMidiControl(
property: KMutableProperty0<Boolean>,
@@ -83,7 +99,16 @@ fun Program.bindMidiControl(
}
}
/**
* Bind MIDI control change to [Vector2] property
* @param property the [KMutableProperty0] to bind to
* @param transceiver the midi device to bind to
* @param channelX the midi channel to use for the [Vector2.x] component
* @param controlX the midi control to use for the [Vector2.x] component
* @param channelY the midi channel to use for the [Vector2.y] component
* @param controlY the midi control to use for the [Vector2.y] component
* @since 0.4.3
*/
@JvmName("bindMidiControlVector2")
fun Program.bindMidiControl(
property: KMutableProperty0<Vector2>, transceiver: MidiTransceiver,
@@ -131,6 +156,18 @@ fun Program.bindMidiControl(
}
}
/**
* Bind MIDI control change to [Vector3] property
* @param property the [KMutableProperty0] to bind to
* @param transceiver the midi device to bind to
* @param channelX the midi channel to use for the [Vector3.x] component
* @param controlX the midi control to use for the [Vector3.x] component
* @param channelY the midi channel to use for the [Vector3.y] component
* @param controlY the midi control to use for the [Vector3.y] component
* @param channelZ the midi channel to use for the [Vector3.z] component
* @param controlZ the midi control to use for the [Vector3.z] component
* @since 0.4.3
*/
@JvmName("bindMidiControlVector3")
fun Program.bindMidiControl(
property: KMutableProperty0<Vector3>, transceiver: MidiTransceiver,
@@ -187,6 +224,20 @@ fun Program.bindMidiControl(
}
}
/**
* Bind MIDI control change to [ColorRGBa] property
* @param property the [KMutableProperty0] to bind to
* @param transceiver the midi device to bind to
* @param channelR the midi channel to use for the [ColorRGBa.r] component
* @param controlR the midi control to use for the [ColorRGBa.r] component
* @param channelG the midi channel to use for the [ColorRGBa.g] component
* @param controlG the midi control to use for the [ColorRGBa.g] component
* @param channelB the midi channel to use for the [ColorRGBa.b] component
* @param controlB the midi control to use for the [ColorRGBa.b] component
* @param channelA the midi channel to use for the [ColorRGBa.alpha] component
* @param controlA the midi control to use for the [ColorRGBa.alpha] component
* @since 0.4.3
*/
@JvmName("bindMidiControlColorRGBa")
fun Program.bindMidiControl(
property: KMutableProperty0<ColorRGBa>, transceiver: MidiTransceiver,

View File

@@ -9,15 +9,29 @@ import org.openrndr.math.Vector2
import org.openrndr.shape.Rectangle
import java.io.File
class MidiConsole: Extension {
/**
* A console for monitoring MIDI events
*/
class MidiConsole : Extension {
override var enabled = true
/**
* placement of the console text
*/
var box = Rectangle(0.0, 0.0, 130.0, 200.0)
val messages = mutableListOf<String>()
private val messages = mutableListOf<String>()
/**
* number of entries in the visible history
*/
var historySize = 2
val demoFont = File("demo-data/fonts/IBMPlexMono-Regular.ttf").exists()
private val demoFont = File("demo-data/fonts/IBMPlexMono-Regular.ttf").exists()
/**
* register a Midi device for monitoring
*/
fun register(transceiver: MidiTransceiver) {
transceiver.controlChanged.listen {
synchronized(messages) {

View File

@@ -41,7 +41,7 @@ class MidiEvent(val eventType: MidiEventType) {
return midiEvent
}
fun controlChange(channel:Int, control: Int, value: Int): MidiEvent {
fun controlChange(channel: Int, control: Int, value: Int): MidiEvent {
val midiEvent = MidiEvent(MidiEventType.CONTROL_CHANGED)
midiEvent.channel = channel
midiEvent.control = control
@@ -49,21 +49,21 @@ class MidiEvent(val eventType: MidiEventType) {
return midiEvent
}
fun programChange(channel:Int, program: Int): MidiEvent {
fun programChange(channel: Int, program: Int): MidiEvent {
val midiEvent = MidiEvent(MidiEventType.PROGRAM_CHANGE)
midiEvent.channel = channel
midiEvent.program = program
return midiEvent
}
fun channelPressure(channel:Int, pressure: Int): MidiEvent {
fun channelPressure(channel: Int, pressure: Int): MidiEvent {
val midiEvent = MidiEvent(MidiEventType.CHANNEL_PRESSURE)
midiEvent.channel = channel
midiEvent.pressure = pressure
return midiEvent
}
fun pitchBend(channel:Int, pitchBend: Int): MidiEvent {
fun pitchBend(channel: Int, pitchBend: Int): MidiEvent {
val midiEvent = MidiEvent(MidiEventType.PITCH_BEND)
midiEvent.channel = channel
midiEvent.pitchBend = pitchBend

View File

@@ -268,6 +268,16 @@ class MidiTransceiver(program: Program, val receiverDevice: MidiDevice?, val tra
transmitterDevicer?.close()
}
}
/**
* List all available MIDI devices
* @since 0.4.3
*/
fun listMidiDevices() = MidiDeviceDescription.list()
/**
* Open a MIDI device by name
* @param name the name of the MIDI device to open
* @since 0.4.3
*/
fun Program.openMidiDevice(name: String) = MidiTransceiver.fromDeviceVendor(this, name)