midi-control 0.2.3

Communicate with MIDI controllers
Documentation
//
// (c) 2020-2022 Hubert Figuière
//
// SPDX-License-Identifier: LGPL-3.0-or-later

//! Arturia device support
//!
//! This is done without any warranty or any documentation or support
//! from the vendor (albeit I'd love this to change)
//!
#![doc = include_str!("../../doc/arturia.md")]

use crate::sysex;

/// Arturia extended manufacturer ID
pub const EXTENDED_ID_VALUE: sysex::ManufacturerId = sysex::ManufacturerId::ExtId(0x20, 0x6b);

/// Arturia_v2 protocol
///
/// SysEx messages using [`EXTENDED_ID_VALUE`]
/// starts with `0x7f`, [`PRODUCT_ID`][v2::PRODUCT_ID]
pub mod v2 {
    use super::EXTENDED_ID_VALUE;
    use crate::consts;
    use crate::message::{MidiMessage, SysExEvent};

    /// Define the product id for the command.
    /// This is defining the protocol.
    pub const PRODUCT_ID: u8 = 0x42;

    /// Verbs for the command
    pub mod verb {
        /// Used to query a value from the device.
        pub const GET: u8 = 0x01;
        /// Use to set a value on the device, or the device to tell the live.
        pub const SET: u8 = 0x02;
        /// Select the device memory to read.
        pub const READ_MEM: u8 = 0x05;
        /// Select the device memory to write to.
        pub const WRITE_MEM: u8 = 0x06;
    }

    /// Param for the command
    pub mod param {
        /// Mode of the controller.
        pub const MODE: u8 = 0x01;
        /// Set the channel
        pub const CHANNEL: u8 = 0x02;
        /// Set the cc number (what about not CC?)
        pub const CC_NUM: u8 = 0x03;
        /// Lower range
        pub const FROM: u8 = 0x04;
        /// Higher range
        pub const TO: u8 = 0x05;
        /// Colour
        pub const COLOUR: u8 = 0x10;
        // ????
        // 0x40
    }

    #[repr(u8)]
    #[derive(Clone, Copy)]
    /// Values of the controls.
    pub enum Control {
        Pad1 = 112,
        Pad2,
        Pad3,
        Pad4,
        Pad5,
        Pad6,
        Pad7,
        Pad8,
        Pad9,
        Pad10,
        Pad11,
        Pad12,
        Pad13,
        Pad14,
        Pad15,
        Pad16,
    }

    #[repr(u8)]
    /// The colour of the pad, as the numerical value for the message.
    pub enum Colour {
        Red = 1,
        Green = 4,
        Yellow = 5,
        Blue = 16,
        Purple = 17,
        Cyan = 20,
        White = 127,
    }

    /// Build a [SysEx message][MidiMessage::SysEx] to query a value.
    ///
    /// * `param_id` is the id on the item
    /// * `item_id` is a control (logical)
    ///
    /// Return a [`MidiMessage`]
    pub fn get_value(param_id: u8, item_id: u8) -> MidiMessage {
        MidiMessage::SysEx(SysExEvent::new_manufacturer(
            EXTENDED_ID_VALUE,
            &[
                0x7f,
                PRODUCT_ID,
                verb::GET,
                0x00,
                param_id,
                item_id,
                consts::EOX,
            ],
        ))
    }

    /// Build a [SysEx message][MidiMessage::SysEx] to set a value.
    ///
    /// * `param_id` is the id on the item
    /// * `item_id` is a control (logical)
    /// * `value` the value
    ///
    /// Return a [`MidiMessage`]
    pub fn set_value(param_id: u8, item_id: u8, value: u8) -> MidiMessage {
        MidiMessage::SysEx(SysExEvent::new_manufacturer(
            EXTENDED_ID_VALUE,
            &[
                0x7f,
                PRODUCT_ID,
                verb::SET,
                0x00,
                param_id,
                item_id,
                value,
                consts::EOX,
            ],
        ))
    }
}