use super::*;
use std::convert::TryFrom;
use std::fmt::{self, Debug};
use std::ops::Index;
#[derive(Clone, Debug)]
pub struct InstrumentFile {
pub instrument: Instrument,
pub samples: Vec<Sample>,
}
#[derive(Clone, Debug)]
pub struct Instrument {
pub name: Name,
pub filename: DosFilename,
pub flags: InstrumentFlags,
pub new_note_action: u8,
pub duplicate_check_type: u8,
pub duplicate_check_action: u8,
pub instrument_fadeout: u8,
pub pitch_pan_separation: i8,
pub pitch_pan_centre: u8,
pub global_volume: u8,
pub default_panning: RangedU8<0, 128>,
pub random_volume_variation: RangedU8<0, 100>,
pub random_panning_variation: RangedU8<0, 64>,
pub trkver: u16,
pub number_of_samples: u8,
pub initial_filter_cutoff: RangedU8<0, 128>,
pub initial_filter_resonance: RangedU8<0, 128>,
pub mch: u8,
pub mpr: u8,
pub mbank: [u8; 2],
pub sample_map: SampleMap,
pub volume_envelope: Envelope,
pub panning_envelope: Envelope,
pub pitch_filter_envelope: Envelope,
}
bitflags! {
#[derive(Default)]
pub struct InstrumentFlags: u8 {
const ENABLE_PANNING = 1 << 0;
const ENABLE_FILTER_CUTOFF = 1 << 1;
const ENABLE_FILTER_RESONANCE = 1 << 1;
}
}
#[derive(Clone, Copy)]
pub struct SampleMap {
pub(crate) map: [Option<SampleId>; 120],
}
#[allow(non_upper_case_globals)]
impl Instrument {
pub(crate) const dfp_ignorePanning: u8 = 0x80;
pub(crate) const ifc_enableCutoff: u8 = 0x80;
pub(crate) const ifr_enableResonance: u8 = 0x80;
}
impl Default for SampleMap {
fn default() -> SampleMap {
SampleMap {
map: [None; 120],
}
}
}
impl Debug for SampleMap {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_map()
.entries(
(0..120)
.zip(self.map.iter())
.filter_map(|(k, v)| v.map(|v| (Note::try_from(k).unwrap(), v)))
)
.finish()
}
}
impl Index<Note> for SampleMap {
type Output = Option<SampleId>;
fn index(&self, index: Note) -> &Self::Output {
&self.map[usize::from(u8::from(index))]
}
}
impl Index<&Note> for SampleMap {
type Output = Option<SampleId>;
fn index(&self, index: &Note) -> &Self::Output {
self.index(*index)
}
}