Enum tune::midi::ChannelMessageType[][src]

pub enum ChannelMessageType {
    NoteOff {
        key: u8,
        velocity: u8,
    },
    NoteOn {
        key: u8,
        velocity: u8,
    },
    PolyphonicKeyPressure {
        key: u8,
        pressure: u8,
    },
    ControlChange {
        controller: u8,
        value: u8,
    },
    ProgramChange {
        program: u8,
    },
    ChannelPressure {
        pressure: u8,
    },
    PitchBendChange {
        value: i16,
    },
}

A parsed representation of the channel-agnostic part of a MIDI message.

Variants

NoteOff

Fields of NoteOff

key: u8velocity: u8
NoteOn

Fields of NoteOn

key: u8velocity: u8
PolyphonicKeyPressure

Fields of PolyphonicKeyPressure

key: u8pressure: u8
ControlChange

Fields of ControlChange

controller: u8value: u8
ProgramChange

Fields of ProgramChange

program: u8
ChannelPressure

Fields of ChannelPressure

pressure: u8
PitchBendChange

Fields of PitchBendChange

value: i16

Implementations

impl ChannelMessageType[src]

pub fn in_channel(self, channel: u8) -> Option<ChannelMessage>[src]

Creates a new ChannelMessage from self with the given channel.

None is returned if the channel value is outside the range [0..16).

Examples

let message_type = ChannelMessageType::NoteOn {
        key: 77,
        velocity: 88
    };
let message = message_type.in_channel(15).unwrap();

assert_eq!(message.channel(), 15);
assert_eq!(message.message_type(), message_type);

let channel_out_of_range = message_type.in_channel(16);
assert!(channel_out_of_range.is_none());

pub fn transform(
    &self,
    tuning: impl KeyboardMapping<PianoKey>
) -> TransformResult
[src]

Applies a tuning transformation to a MIDI message.

This operation only succeeds for polyphonic messages whose transformed note is in the allowed MIDI range [0..128). If the transformation is successful the deviation from the accurate transformed note is reported.

Examples

let tuning = (
    Scl::builder().push_cents(120.0).build().unwrap(),
    KbmRoot::from(Note::from_midi_number(62)).to_kbm(),
);

// Usually, polyphonic messages are transformed

let in_range = ChannelMessageType::NoteOn { key: 100, velocity: 88 };

match in_range.transform(&tuning) {
    TransformResult::Transformed { message_type, deviation, orig_key, mapped_note } => {
        assert_eq!(
            message_type,
            ChannelMessageType::NoteOn { key: 108, velocity: 88 }
        );
        assert_approx_eq!(deviation.as_cents(), -40.0);
        assert_eq!(orig_key, 100);
        assert_eq!(mapped_note, 108);
    },
    _ => unreachable!(),
}

// When the transformed note is out of range messages are not transformed

let out_of_range = ChannelMessageType::NoteOn { key: 120, velocity: 88 };

assert!(matches!(out_of_range.transform(&tuning), TransformResult::NoteOutOfRange));

// Monophonic messages are never transformed

let not_transformed = ChannelMessageType::ProgramChange { program: 42 };

assert!(matches!(not_transformed.transform(&tuning), TransformResult::NotKeyBased));

pub fn distribute(
    &self,
    tuner: &ChannelTuner<PianoKey>,
    channel_offset: u8
) -> Vec<ChannelMessage>
[src]

Distributes the given ChannelMessageType to multiple channels depending on the state of the provided ChannelTuner.

The parameter channel_offset specifies the amount by which the channel number returned by tuner will be raised. Messages that cannot be mapped to a valid MIDI message will be discarded.

Examples

let mut tuning = (
    Scl::builder().push_cents(25.0).build().unwrap(),
    KbmRoot::from(Note::from_midi_number(62)).to_kbm(),
);

let (tuner, _) = ChannelTuner::apply_full_keyboard_tuning(
    &tuning,
    (0..128).map(PianoKey::from_midi_number),
);

// Usually, polyponic messages are distributed

let in_range = ChannelMessageType::NoteOn {
    key: 91,
    velocity: 88,
};

let distributed = in_range.distribute(&tuner, 4);
assert_eq!(distributed.len(), 1);
assert_eq!(
    distributed[0].message_type(),
    ChannelMessageType::NoteOn {
        key: 69,
        velocity: 88,
    }
);
assert_eq!(distributed[0].channel(), 6);

// When mapped channel is out of range messages are discarded

assert!(in_range.distribute(&tuner, 14).is_empty());

// When transformed note is out of range messages are discarded

let mut macrotuning = (
    Scl::builder().push_cents(120.0).build().unwrap(),
    KbmRoot::from(Note::from_midi_number(62)).to_kbm(),
);

let (macrotuner, _) = ChannelTuner::apply_full_keyboard_tuning(
    &macrotuning,
    (0..128).map(PianoKey::from_midi_number),
);

let out_of_range = ChannelMessageType::NoteOn {
    key: 120,
    velocity: 88,
};

assert!(out_of_range.distribute(&macrotuner, 4).is_empty());

// Monophonic messages are distributed to multiple channels

let monophonic = ChannelMessageType::ProgramChange { program: 42 };

let distributed = monophonic.distribute(&tuner, 4);
assert_eq!(distributed.len(), 4);
for (index, channel) in (0..4).zip(4..8) {
    assert_eq!(
        distributed[index].message_type(),
        ChannelMessageType::ProgramChange { program: 42 }
    );
    assert_eq!(distributed[index].channel(), channel);
}

// When mapped channel is out of range messages are discarded

let distributed = monophonic.distribute(&tuner, 14);
assert_eq!(distributed.len(), 2);
for (index, channel) in (0..2).zip(14..16) {
    assert_eq!(
        distributed[index].message_type(),
        ChannelMessageType::ProgramChange { program: 42 }
    );
    assert_eq!(distributed[index].channel(), channel);
}

Trait Implementations

impl Clone for ChannelMessageType[src]

impl Copy for ChannelMessageType[src]

impl Debug for ChannelMessageType[src]

impl Eq for ChannelMessageType[src]

impl PartialEq<ChannelMessageType> for ChannelMessageType[src]

impl StructuralEq for ChannelMessageType[src]

impl StructuralPartialEq for ChannelMessageType[src]

Auto Trait Implementations

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.