use crate::{
SystemExclusiveData,
ParseError,
Checksum
};
use crate::k5000::formant::FormantFilter;
use crate::k5000::harmonic::{
Envelope as HarmonicEnvelope,
Levels
};
use crate::k5000::morf::{
HarmonicCommon,
MorfHarmonic
};
pub const HARMONIC_COUNT: usize = 64;
pub const BAND_COUNT: usize = 128;
pub struct AdditiveKit {
pub common: HarmonicCommon,
pub morf: MorfHarmonic,
pub formant_filter: FormantFilter,
pub levels: Levels,
pub bands: [u8; BAND_COUNT],
pub envelopes: Vec::<HarmonicEnvelope>,
}
impl Default for AdditiveKit {
fn default() -> Self {
AdditiveKit {
common: Default::default(),
morf: Default::default(),
formant_filter: Default::default(),
levels: Default::default(),
bands: [0; BAND_COUNT],
envelopes: vec![Default::default(); HARMONIC_COUNT],
}
}
}
impl AdditiveKit {
pub fn new() -> Self {
Default::default()
}
}
impl SystemExclusiveData for AdditiveKit {
fn from_bytes(data: &[u8]) -> Result<Self, ParseError> {
let mut offset = 0;
let checksum = data[offset];
eprintln!("{:#04X}: additive kit checksum = {:#02x}", offset, checksum);
offset += 1;
let hc_data = &data[1..7];
let common = HarmonicCommon::from_bytes(hc_data)?;
eprintln!("{:#04X}: harmonic common = {}", offset, common);
offset += HarmonicCommon::data_size();
let morf_data = &data[7..20];
let morf = MorfHarmonic::from_bytes(morf_data)?;
eprintln!("{:#04X}: MORF harmonic = {}", offset, morf);
offset += MorfHarmonic::data_size();
let ff_data = &data[20..37];
let formant_filter = FormantFilter::from_bytes(ff_data)?;
eprintln!("{:#04X}: FF = {}", offset, formant_filter);
offset += FormantFilter::data_size();
let levels_data = &data[37..165];
let levels = Levels::from_bytes(levels_data)?;
offset += Levels::data_size();
eprintln!("{:#04X}: FF bands start here", offset);
let mut bands: [u8; BAND_COUNT] = [0; BAND_COUNT];
for i in 0..BAND_COUNT {
bands[i] = data[offset];
offset += 1;
}
eprintln!("{:#04X}: Harmonic envelopes start here", offset);
let mut envelopes: Vec::<HarmonicEnvelope> = vec![HarmonicEnvelope::new(); HARMONIC_COUNT];
for _ in 0..HARMONIC_COUNT {
envelopes.push(HarmonicEnvelope::from_bytes(&data[offset..offset + 8])?);
offset += 8;
}
Ok(AdditiveKit {
common,
morf,
formant_filter,
levels,
bands,
envelopes,
})
}
fn to_bytes(&self) -> Vec<u8> {
let mut result: Vec<u8> = Vec::new();
result.push(self.checksum());
result.extend(self.common.to_bytes());
result.extend(self.morf.to_bytes());
result.extend(self.formant_filter.to_bytes());
result.extend(self.levels.to_bytes());
result.extend(self.bands.to_vec());
for env in self.envelopes.iter() {
result.extend(env.to_bytes());
}
result.push(0);
result
}
fn data_size() -> usize {
1
+ HarmonicCommon::data_size()
+ MorfHarmonic::data_size()
+ FormantFilter::data_size()
+ Levels::data_size()
+ BAND_COUNT
+ HARMONIC_COUNT * HarmonicEnvelope::data_size()
}
}
impl Checksum for AdditiveKit {
fn checksum(&self) -> u8 {
let mut total = 0;
let common_data = self.common.to_bytes();
let mut common_sum: u32 = 0;
for d in common_data {
common_sum += (d & 0xff) as u32;
}
let morf_data = self.morf.to_bytes();
for d in morf_data {
common_sum += (d & 0xff) as u32;
}
let ff_data = self.formant_filter.to_bytes();
for d in ff_data {
common_sum += (d & 0xff) as u32;
}
total += common_sum & 0xff;
let mut hc1_sum: u32 = 0;
for h in self.levels.soft.iter() {
hc1_sum += (h & 0xff) as u32;
}
total += hc1_sum;
let mut hc2_sum: u32 = 0;
for h in self.levels.loud.iter() {
hc2_sum += (h & 0xff) as u32;
}
total += hc2_sum;
let mut ff_sum: u32 = 0;
for f in self.bands.iter() {
ff_sum += (f & 0xff) as u32;
}
total += ff_sum;
let mut hcenv_sum: u32 = 0;
for env in self.envelopes.iter() {
let ed = env.to_bytes();
for e in ed {
hcenv_sum += (e & 0xff) as u32;
}
}
total += hcenv_sum & 0xff;
total += 0xa5;
(total & 0x7f) as u8
}
}