use crate::instruments::common::*;
use crate::reader::*;
use crate::version::*;
use crate::writer::Writer;
use num_enum::IntoPrimitive;
use num_enum::TryFromPrimitive;
use super::dests;
use super::CommandPack;
#[repr(u8)]
#[allow(non_camel_case_types)]
#[derive(IntoPrimitive, TryFromPrimitive, PartialEq, Copy, Clone, Default, Debug)]
pub enum WavShape {
#[default]
PULSE12,
PULSE25,
PULSE50,
PULSE75,
SAW,
TRIANGLE,
SINE,
NOISE_PITCHED,
NOISE,
WT_CRUSH,
WT_FOLDING,
WT_FREQ,
WT_FUZZY,
WT_GHOST,
WT_GRAPHIC,
WT_LFOPLAY,
WT_LIQUID,
WT_MORPHING,
WT_MYSTIC,
WT_STICKY,
WT_TIDAL,
WT_TIDY,
WT_TUBE,
WT_UMBRELLA,
WT_UNWIND,
WT_VIRAL,
WT_WAVES,
WT_DRIP,
WT_FROGGY,
WT_INSONIC,
WT_RADIUS,
WT_SCRATCH,
WT_SMOOTH,
WT_WOBBLE,
WT_ASIMMTRY,
WT_BLEEN,
WT_FRACTAL,
WT_GENTLE,
WT_HARMONIC,
WT_HYPNOTIC,
WT_ITERATIV,
WT_MICROWAV,
WT_PLAITS01,
WT_PLAITS02,
WT_RISEFALL,
WT_TONAL,
WT_TWINE,
WT_ALIEN,
WT_CYBERNET,
WT_DISORDR,
WT_FORMANT,
WT_HYPER,
WT_JAGGED,
WT_MIXED,
WT_MULTIPLY,
WT_NOWHERE,
WT_PINBALL,
WT_RINGS,
WT_SHIMMER,
WT_SPECTRAL,
WT_SPOOKY,
WT_TRANSFRM,
WT_TWISTED,
WT_VOCAL,
WT_WASHED,
WT_WONDER,
WT_WOWEE,
WT_ZAP,
WT_BRAIDS,
WT_VOXSYNTH,
}
#[derive(PartialEq, Debug, Clone)]
pub struct WavSynth {
pub number: u8,
pub name: String,
pub transpose: bool,
pub table_tick: u8,
pub synth_params: SynthParams,
pub shape: WavShape,
pub size: u8,
pub mult: u8,
pub warp: u8,
pub scan: u8,
}
#[rustfmt::skip] const WAVSYNTH_COMMAND_NAMES : [&'static str; CommandPack::BASE_INSTRUMENT_COMMAND_COUNT] = [
"VOL",
"PIT",
"FIN",
"OSC",
"SIZ",
"MUL",
"WRP",
"MIR",
"FIL",
"CUT",
"RES",
"AMP",
"LIM",
"PAN",
"DRY",
"SCH",
"SDL",
"SRV",
];
#[rustfmt::skip] const DESTINATIONS : [&'static str; 15] = [
dests::OFF,
dests::VOLUME,
dests::PITCH,
"SIZE",
"MULT",
"WARP",
"SCAN",
dests::CUTOFF,
dests::RES,
dests::AMP,
dests::PAN,
dests::MOD_AMT,
dests::MOD_RATE,
dests::MOD_BOTH,
dests::MOD_BINV,
];
#[rustfmt::skip] const WAVSYNTH_FILTER_TYPES : [&'static str; 12] = [
"OFF",
"LOWPASS",
"HIGHPAS",
"BANDPAS",
"BANDSTP",
"LP > HP",
"ZDF LP",
"ZDF HP",
"WAV LP",
"WAV HP",
"WAV BP",
"WAV BS"
];
impl WavSynth {
pub const MOD_OFFSET: usize = 30;
pub fn command_name(&self, _ver: Version) -> &'static [&'static str] {
&WAVSYNTH_COMMAND_NAMES
}
pub fn destination_names(&self, _ver: Version) -> &'static [&'static str] {
&DESTINATIONS
}
pub fn filter_types(&self, _ver: Version) -> &'static [&'static str] {
&WAVSYNTH_FILTER_TYPES
}
pub fn human_readable_filter(&self) -> &'static str {
WAVSYNTH_FILTER_TYPES[self.synth_params.filter_type as usize]
}
pub fn write(&self, ver: Version, w: &mut Writer) {
w.write_string(&self.name[..], 12);
w.write(TranspEq::from(ver, self.transpose, self.synth_params.associated_eq).into());
w.write(self.table_tick);
w.write(self.synth_params.volume);
w.write(self.synth_params.pitch);
w.write(self.synth_params.fine_tune);
w.write(self.shape.into());
w.write(self.size);
w.write(self.mult);
w.write(self.warp);
w.write(self.scan);
self.synth_params.write(ver, w, WavSynth::MOD_OFFSET);
}
pub fn from_reader(
ver: Version,
reader: &mut Reader,
number: u8,
version: Version,
) -> M8Result<Self> {
let name = reader.read_string(12);
let transp_eq = TranspEq::from_version(ver, reader.read());
let table_tick = reader.read();
let volume = reader.read();
let pitch = reader.read();
let fine_tune = reader.read();
let shape = reader.read();
let size = reader.read();
let mult = reader.read();
let warp = reader.read();
let scan = reader.read();
let synth_params = if version.at_least(3, 0) {
SynthParams::from_reader3(
ver,
reader,
volume,
pitch,
fine_tune,
transp_eq.eq,
WavSynth::MOD_OFFSET,
)?
} else {
SynthParams::from_reader2(reader, volume, pitch, fine_tune)?
};
Ok(WavSynth {
number,
name,
transpose: transp_eq.transpose,
table_tick,
synth_params,
shape: shape
.try_into()
.map_err(|_| ParseError(format!("Invalid wavsynth shape")))?,
size,
mult,
warp,
scan,
})
}
}