Skip to content

Commit

Permalink
Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
hamoid committed Jan 11, 2024
1 parent b3d5657 commit 03af3d4
Showing 1 changed file with 94 additions and 22 deletions.
116 changes: 94 additions & 22 deletions docs/ORX/midiControllers.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
layout: default
title: MIDI controllers
parent: ORX
last_modified_at: 2023.07.24 16:41:35 +0200
last_modified_at: 2024.01.11 17:46:11 +0100
nav_order: 140
has_children: false
---
Expand All @@ -23,59 +23,66 @@ set in `build.gradle.kts` and reimport the gradle project.

## Listing MIDI controllers

To connect to a MIDI controller you will need the exact name and vendor
of the controller as they are reported
to the operating system. To discover these identifiers it is easiest to
list the controllers, this can be done using
the `MidiDeviceDescription.list()` function.
To connect to a MIDI controller you will need its device name which can be
discovered by calling the `listMidiDevices()` function.

```kotlin
fun main() = application {
program {
MidiDeviceDescription.list().forEach {
listMidiDevices().forEach {
println("name: '${it.name}', vendor: '${it.vendor}', receiver:${it.receive}, transmitter:${it.transmit}")
}
}
}
```

From what this program outputs you can pick a controller by copying its
name and vendor identifiers.

## Connecting to a MIDI controller

Once you have the controller name and vendor you can use
`MidiTransceiver.fromDeviceVendor` to open the midi controller. For
example to use a Behringer BCR2000 controller on a Ubuntu system we
Once you have the controller name you can use
`openMidiDevice` to connect to the MIDI controller.
For example to use a Behringer BCR2000 controller on a Ubuntu system we
can use the following.

```kotlin
fun main() = application {
program {
val controller = MidiTransceiver.fromDeviceVendor(this, "BCR2000 [hw:2,0,0]", "ALSA (http://www.alsa-project.org)")
val controller = openMidiDevice("BCR2000")
}
}
```

Tip: request `BCR2000` instead of `BCR2000 [hw:2,0,0]` so your program continues
to work after plugging your controller into a different USB port.
Caveat: do specify the full name if connecting multiple controllers of the same brand and model.

## Listening to the controller

Once connected to a controller we can start listening to the MIDI events
it sends out. The orx-midi library supports controller change, note on
and note off events.
it sends out. The orx-midi library supports six types of MIDI events.

```kotlin
fun main() = application {
program {
val controller = MidiTransceiver.fromDeviceVendor(this, "BCR2000 [hw:2,0,0]", "ALSA (http://www.alsa-project.org)")
val controller = openMidiDevice("BCR2000 [hw:2,0,0]")

controller.controlChanged.listen {
println("control change: channel: ${it.channel}, control: ${it.control}, value: ${it.value}")
println("[control change] channel: ${it.channel}, control: ${it.control}, value: ${it.value}")
}
controller.noteOn.listen {
println("note on: channel: ${it.channel}, key: ${it.note}, velocity: ${it.velocity}")
println("[note on] channel: ${it.channel}, key: ${it.note}, velocity: ${it.velocity}")
}
controller.noteOff.listen {
println("note off: ${it.channel}, key: ${it.note},")
println("[note off] channel: ${it.channel}, key: ${it.note},")
}
controller.channelPressure.listen {
println("[channel pressure] channel: ${it.channel}, pressure: ${it.pressure}")
}
controller.pitchBend.listen {
println("[pitch bend] channel: ${it.channel}, pitch: ${it.pitchBend}")
}
controller.programChanged.listen {
println("[program change] channel: ${it.channel}, program: ${it.program}")
}
}
}
Expand All @@ -92,18 +99,83 @@ in the controller.
```kotlin
fun main() = application {
program {
val controller = MidiTransceiver.fromDeviceVendor(this, "BCR2000 [hw:2,0,0]", "ALSA (http://www.alsa-project.org)")
val controller = openMidiDevice("BCR2000")

// send a control change
controller.controlChange(channel = 1, control = 3, value = 42)

// send a program change
controller.programChange(channel = 2, program = 5)

// send a note event
// send a note on event
controller.noteOn(channel = 3, key = 60, velocity = 100)
// note: send velocity 0 to stop a note

// send a note off event
controller.noteOn(channel = 3, key = 60, velocity = 0)

// send a pitch bend event
controller.pitchBend(channel = 4, 50)

// send a channel pressure event
controller.channelPressure(channel = 4, 100)
}
}
```

## MIDI console

For debugging purposes one can visualize all the MIDI events by using the `MidiConsole`.

```kotlin
fun main() = application {
program {
val controller = openMidiDevice("Launchpad [hw:4,0,0]")

extend(MidiConsole()) {
register(controller)
}
}
}
```

## Variable binding

One can easily bind MIDI controller inputs like knobs and sliders to program variables.
In the following example 7 inputs control the radius, position
and color of a circle.

Note that `ColorParameter` binds four consecutive inputs (red, green, blue and alpha).

[More about Parameter Annotations](/ORX/quickUIs.html#parameter-annotations).

```kotlin
fun main() = application {
program {
val controller = openMidiDevice("Launchpad [hw:4,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, controller, channel = 0, control = 1)
bindMidiControl(settings::x, controller, 0, 2)
bindMidiControl(settings::y, controller, 0, 3)
bindMidiControl(settings::color, controller, 0, 4)

extend {
drawer.fill = settings.color
drawer.circle(drawer.bounds.center + Vector2(settings.x, settings.y), settings.radius)
}
}
}
```
Expand Down

0 comments on commit 03af3d4

Please sign in to comment.