Struct Output

Source
pub struct Output { /* private fields */ }
Expand description

The object handling any messages to the launchpad. To get started, initialize with [(Output::guess)OutputDevice::guess] and then send messages to your liking. The connection to the launchpad will get closed when this object goes out of scope.

For example:

let mut output = Output::guess()?;

output.light_all(PaletteColor::BLACK); // clear screen

// make a red cross in the center
output.light_row(4, PaletteColor::RED);
output.light_row(5, PaletteColor::RED);
output.light_column(4, PaletteColor::RED);
output.light_column(5, PaletteColor::RED);

// light top left button magenta
output.light(Button::GridButton { x: 0, y: 0 }, PaletteColor::MAGENTA);

§Representing color

The Launchpad Mk3 has two different ways to represent color. You can either use one of the 128 built-in palette colors, or you can create a custom color with custom rgb components. Why would you choose the palette colors when you can just create your required colors yourself? Well some operations on the Mk3 only support palette colors. Besides, sending palette color midi messages is simply faster. Therefore you should aim to use the palette colors when possible.

Implementations§

Source§

impl Output

Source

pub fn set_button( &mut self, button: Button, color: PaletteColor, light_mode: LightMode, ) -> Result<(), MidiError>

Set a button to a certain color with a certain light_mode.

This uses a direct MIDI message on channel 1, 2 or 3 to set the color, and uses different data structures than set_buttons (which uses a SysEx message that also allows RGB button colors and flashing between 2 different palette colors).

For example to start a yellow pulse on the leftmost control button:

let button = Button::ControlButton { index: 0 };
let color = PaletteColor::YELLOW;
let light_mode = LightMode::Pulse;
output.set_button(button, color, light_mode)?;
Source

pub fn set_buttons<I, T>(&mut self, buttons: I) -> Result<(), MidiError>
where I: IntoIterator<Item = T>, T: Borrow<(Button, ButtonStyle)>,

Light multiple buttons with varying colors.

This uses a SysEx message to set one or more buttons in one go, and supports RGB colors as well as flashing between 2 colors.

Apart from set_button which uses a simpler mechanism to set button colors, all other lighting control methods forward to this one.

For example to light the top left button green and the top right button red:

output.set_buttons(&[
    (Button::GridButton { x: 0, y: 0 }, ButtonStyle::rgb(RgbColor::new(0, 0, 127))),
    (Button::GridButton { x: 7, y: 0 }, RgbColor::new(127, 0, 0).into()),
])?;
Source

pub fn light_multiple_rgb<I, T>(&mut self, buttons: I) -> Result<(), MidiError>
where I: IntoIterator<Item = T>, T: Borrow<(Button, RgbColor)>, I::IntoIter: ExactSizeIterator,

Light multiple buttons with varying RGB colors.

For example to light the top left button green and the top right button red:

output.light_multiple_rgb(&[
    (Button::GridButton { x: 0, y: 0 }, RgbColor::new(0, 0, 127)),
    (Button::GridButton { x: 7, y: 0 }, RgbColor::new(127, 0, 0)),
])?;

The implementation of this method forwards the call to Output::set_buttons.

Source

pub fn light_columns( &mut self, buttons: impl IntoIterator<Item = impl Borrow<(u8, PaletteColor)>>, ) -> Result<(), MidiError>

Light multiple columns with varying colors. This method does not light up the control buttons

For example to light the first column yellow and the second column blue:

output.light_columns(&[
    (0, PaletteColor::YELLOW),
    (1, PaletteColor::BLUE),
])?;
Source

pub fn light_rows( &mut self, buttons: impl IntoIterator<Item = impl Borrow<(u8, PaletteColor)>>, ) -> Result<(), MidiError>

Light multiple row with varying colors. This method does light up the side buttons.

Note: the row are counted starting at the control row! For example to light the control row magenta and the first grid row green:

output.light_rows(&[
    (0, PaletteColor::MAGENTA),
    (1, PaletteColor::GREEN),
])?;
Source

pub fn light_all(&mut self, color: PaletteColor) -> Result<(), MidiError>

Light all buttons, including control and side buttons.

For example to clear the screen:

output.light_all(PaletteColor::BLACK)?;
Source

pub fn send_clock_tick(&mut self) -> Result<(), MidiError>

By default, Launchpad MK3 will flash and pulse at 120 BPM. This can be altered by sending these clock ticks by calling send_clock_tick(). These ticks should be sent at a rate of 24 per beat.

To set a tempo of 100 BPM, 2400 clock ticks should be sent each minute, or with a time interval of 25ms.

Launchpad MK3 supports tempos between 40 and 240 BPM, faster clock ticks are apparently ignored.

For example to send clock ticks at 200 BPM:

let beats_per_minute = 200;
let clock_ticks_per_second = beats_per_minute * 60 * 24;
let clock_tick_interval = std::time::Duration::from_millis(1000 / clock_ticks_per_second);
loop {
    output.send_clock_tick()?;
    std::thread::sleep(clock_tick_interval);
}
Source

pub fn request_device_inquiry( &mut self, query: DeviceIdQuery, ) -> Result<(), MidiError>

Requests the Launchpad Mk3 to send a so-called device inquiry. The device inquiry contains information about the device ID and the firmware revision number.

According to the documentation, this should return both a super::Message::ApplicationVersion as well as a super::Message::BootloaderVersion.

In order to be able to receive the Launchpad Mk3’s response to this request, you must have a Launchpad Mk3 input object set up.

Source

pub fn request_sleep_mode(&mut self) -> Result<(), MidiError>

Requests the Launchpad Mk3 to send a Message::SleepState message.

In order to be able to receive the Launchpad Mk3’s response to this request, you must have a Launchpad Mk3 input object set up.

Source

pub fn scroll_text( &mut self, text: &[u8], color: PaletteColor, speed: u8, should_loop: bool, ) -> Result<(), MidiError>

Starts a text scroll across the screen.

The screen is temporarily cleared. You can specify the color of the text and whether the text should loop indefinitely.

Speed is given in pads/second, and must be in range (0..128). 16 is already quite a brisk speed. If speed is >= 64, it is interpreted as a negative number, formed by subtracing 128 from it. This will make the text scroll from left to right.

If text is the empty string, the attributes of the currently ongoing scroll will be changed instead (color, speed, looping).

When the text ends, Launchpad MK3 restores the LEDs to their previous settings.

WARNING: the Mini MK3 does not seem to have a Message that tells you when the text is finished. As such, you will have to do time calculations yourself to know when your text has finished scrolling. If your text loops, you must call Output::stop_scroll at some point.

For example to scroll the text “Hello, world!” in blue:

output.scroll_text(b"Hello, world!", PaletteColor::BLUE, 32, false)?;
Source

pub fn stop_scroll(&mut self) -> Result<(), MidiError>

Stop the ongoing text scroll immediately

Source

pub fn send_sleep(&mut self, sleep_mode: SleepMode) -> Result<(), MidiError>

Source

pub fn sleep(&mut self) -> Result<(), MidiError>

Put the Launchpad MK3 to sleep

Source

pub fn wake(&mut self) -> Result<(), MidiError>

Wake the device up from sleep mode

Source

pub fn light( &mut self, button: Button, color: PaletteColor, ) -> Result<(), MidiError>

Light a button with a color from the Mk3 palette. Identical to set_button(<button>, <color>, LightMode::Plain).

For example to light the “Volume” side button cyan:

output.light(Button::VOLUME, PaletteColor::CYAN)?;
Source

pub fn flash( &mut self, button: Button, color: PaletteColor, ) -> Result<(), MidiError>

Starts a flashing motion between the previously shown color on this button and palette color color, with a duty cycle of 50% and a bpm of 120. The bpm can be controlled using send_clock_tick().

Identical to set_button(<button>, <color>, LightMode::FLASH).

For example to start a red flash on the “Session” button at the top:

output.flash(Button::UP, PaletteColor::RED)?;
Source

pub fn pulse( &mut self, button: Button, color: PaletteColor, ) -> Result<(), MidiError>

Start a pulse; a rhythmic increase and decreases in brightness. The speed can be controlled using send_clock_tick(). Identical to set_button(<button>, <color>, LightMode::PULSE).

For example to start a magenta pulse on the top right grid button:

output.pulse(Button::GridButton { x: 7, y: 0 }, PaletteColor::MAGENTA)?;
Source

pub fn light_column( &mut self, column: u8, color: PaletteColor, ) -> Result<(), MidiError>

Light a single column, specified by column (0-8).

For example to light the entire side button column white:

output.light_column(8, PaletteColor::WHITE)?;
Source

pub fn light_row( &mut self, row: u8, color: PaletteColor, ) -> Result<(), MidiError>

Light a single row, specified by row (0-8). Note: the row counting begins at the control row! So e.g. when you want to light the first grid row, pass 1 not 0.

For example to light the first grid row green:

output.light_row(1, PaletteColor::GREEN)?;
Source

pub fn light_rgb( &mut self, button: Button, color: RgbColor, ) -> Result<(), MidiError>

Light a single button with an RGB color.

For example to light the bottom right button cyan:

output.light_rgb(Button::GridButton { x: 7, y: 7 }, RgbColor::new(0, 127, 127))?;
Source

pub fn light_multiple( &mut self, buttons: impl IntoIterator<Item = impl Borrow<(Button, PaletteColor)>>, ) -> Result<(), MidiError>

Light multiple buttons with varying colors. Identical to set_buttons(<pairs>, LightMode::Plain)

For example to light both User 1 and User 2 buttons orange:

output.light_multiple(&[
    (Button::USER_1, PaletteColor::new(9)),
    (Button::USER_2, PaletteColor::new(9)),
])?;
Source

pub fn flash_multiple( &mut self, buttons: impl IntoIterator<Item = impl Borrow<(Button, PaletteColor)>>, ) -> Result<(), MidiError>

Start flashing multiple buttons with varying colors. Identical to set_buttons(<pairs>, LightMode::Flash)

For example to flash both User 1 and User 2 buttons orange:

output.flash_multiple(&[
    (Button::USER_1, PaletteColor::new(9)),
    (Button::USER_2, PaletteColor::new(9)),
])?;
Source

pub fn pulse_multiple( &mut self, buttons: impl IntoIterator<Item = impl Borrow<(Button, PaletteColor)>>, ) -> Result<(), MidiError>

Start pulsing multiple buttons with varying colors. Identical to set_buttons(<pairs>, LightMode::Pulse)

For example to pulse both User 1 and User 2 buttons orange:

output.pulse_multiple(&[
    (Button::USER_1, PaletteColor::new(9)),
    (Button::USER_2, PaletteColor::new(9)),
])?;
Source

pub fn set_brightness(&mut self, brightness: u8) -> Result<(), MidiError>

Set the LED brightness on a scale of (0..128) (exclusive).

Source

pub fn request_brightness(&mut self) -> Result<(), MidiError>

Source

pub fn clear(&mut self) -> Result<(), MidiError>

Clears the entire field of buttons. Equivalent to output.light_all(PaletteColor::BLACK).

Trait Implementations§

Source§

impl OutputDevice for Output

Source§

const MIDI_DEVICE_KEYWORD: &'static str = "Launchpad Mini MK3 LPMiniMK3 MIDI"

Device name.

On MacOS, the Mini MK3 advertises:

  • “Launchpad Mini MK3 LPMiniMK3 DAW”
  • “Launchpad Mini MK3 LPMiniMK3 MIDI”

But only the MIDI interface works for what we want to do, so include the “MIDI” string.

Source§

const MIDI_CONNECTION_NAME: &'static str = "Launchy Mini Mk3 output"

Source§

fn from_connection(connection: MidiOutputConnection) -> Result<Self, MidiError>

Initiate from an existing midir connection.
Source§

fn send(&mut self, bytes: &[u8]) -> Result<(), MidiError>

Source§

fn guess() -> Result<Self, MidiError>

Auto Trait Implementations§

§

impl !Freeze for Output

§

impl !RefUnwindSafe for Output

§

impl Send for Output

§

impl !Sync for Output

§

impl Unpin for Output

§

impl UnwindSafe for Output

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.