use std::fmt;
use bit::BitIndex;
use crate::{Ranged, SystemExclusiveData, ParseError};
use crate::k4::{Level, Curve, Coarse, Fine};
use crate::k4::wave::Wave;
#[derive(Copy, Clone)]
pub struct Source {
pub delay: Level,
pub wave: Wave,
pub ks_curve: Curve,
pub coarse: Coarse,
pub key_track: KeyTrack,
pub fine: Fine,
pub press_freq: bool,
pub vibrato: bool,
pub velocity_curve: Curve, }
impl Source {
pub fn new() -> Source {
Source {
delay: Level::new(0),
wave: Default::default(),
ks_curve: Curve::new(1),
coarse: Coarse::new(0),
key_track: KeyTrack::On,
fine: Fine::new(0),
press_freq: true,
vibrato: true,
velocity_curve: Curve::new(1),
}
}
}
impl Default for Source {
fn default() -> Self {
Source::new()
}
}
impl fmt::Display for Source {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"delay = {}, wave = {}, KS curve = {}, coarse = {}, fine = {}, key track = {}, prs>freq = {}, vib>a.bend = {}, vel.curve = {}",
self.delay.value(),
self.wave,
self.ks_curve.value(),
self.coarse.value(),
self.fine.value(),
self.key_track,
self.press_freq,
self.vibrato,
self.velocity_curve.value()
)
}
}
impl SystemExclusiveData for Source {
fn from_bytes(data: &[u8]) -> Result<Self, ParseError> {
let mut offset: usize = 0;
let mut b: u8;
b = data[offset];
offset += 1;
let delay = b & 0x7f;
b = data[offset];
offset += 1;
let wave_high = b & 0x01;
let ks_curve = ((b >> 4) & 0x07) + 1; let wave_low = data[offset] & 0x7f;
offset += 1;
let wave = Wave::from_bytes(&[wave_high, wave_low]);
b = data[offset];
offset += 1;
let is_key_track = b.bit(6);
let coarse = ((b & 0x3f) as i8) - 24;
b = data[offset];
offset += 1;
let fixed_key = b & 0x7f;
let key_track = if is_key_track {
KeyTrack::On
}
else {
KeyTrack::FixedKey(fixed_key)
};
b = data[offset];
offset += 1;
let fine = ((b & 0x7f) as i8) - 50;
b = data[offset];
let press_freq = b.bit(0);
let vibrato = b.bit(1);
let velocity_curve = ((b >> 2) & 0x07) + 1;
Ok(Source {
delay: Level::new(delay.into()),
wave: wave?,
ks_curve: Curve::new(ks_curve.into()),
coarse: Coarse::new(coarse.into()),
key_track,
fine: Fine::new(fine.into()),
press_freq,
vibrato,
velocity_curve: Curve::new(velocity_curve.into()),
})
}
fn to_bytes(&self) -> Vec<u8> {
let mut buf: Vec<u8> = Vec::new();
buf.push(self.delay.value().try_into().unwrap());
let mut s34 = ((self.ks_curve.value() - 1) << 4) as u8;
let wave_bytes = self.wave.to_bytes();
if wave_bytes[0] == 1 {
s34.set_bit(0, true);
}
buf.push(s34);
buf.push(wave_bytes[1]);
let mut s42 = (self.coarse.value() + 24) as u8; let mut key: u8 = 0;
match self.key_track {
KeyTrack::On => {
s42.set_bit(6, true);
},
KeyTrack::FixedKey(k) => {
key = k;
}
};
buf.push(s42);
buf.push(key);
buf.push((self.fine.value() + 50) as u8);
let mut s54 = ((self.velocity_curve.value() - 1) << 2) as u8;
if self.vibrato {
s54.set_bit(0, true);
}
buf.push(s54);
buf
}
fn data_size() -> usize { 7 }
}
#[derive(Copy, Clone)]
pub enum KeyTrack {
On,
FixedKey(u8),
}
impl fmt::Display for KeyTrack {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}",
match self {
KeyTrack::On => "ON".to_string(),
KeyTrack::FixedKey(k) => format!("fixed {}", k),
}
)
}
}