use super::{Builder, Reader};
use crate::{Error, OplChip, Result, Sequence};
pub struct Imf;
impl Imf {
pub fn load(bytes: &[u8], tick_hz: u32) -> Result<Sequence> {
if bytes.len() >= 2 {
let length = usize::from(u16::from_le_bytes([bytes[0], bytes[1]]));
if length > 0 && length % 4 == 0 && length + 2 == bytes.len() {
return Self::load_type1(bytes, tick_hz);
}
}
Self::load_type0(bytes, tick_hz)
}
pub fn load_type0(bytes: &[u8], tick_hz: u32) -> Result<Sequence> {
if !bytes.len().is_multiple_of(4) {
return Err(Error::Format("IMF data length must be a multiple of four"));
}
let mut output = Builder::new(OplChip::Opl2, tick_hz)?;
let mut input = Reader::new(bytes);
while input.remaining() > 0 {
let register = input.u8()?;
let value = input.u8()?;
output.write(u16::from(register), value);
output.delay(u64::from(input.u16()?))?;
}
output.finish()
}
pub fn load_type1(bytes: &[u8], tick_hz: u32) -> Result<Sequence> {
let mut input = Reader::new(bytes);
let length = usize::from(input.u16()?);
Self::load_type0(input.take(length)?, tick_hz)
}
}