rustysynth_ext/
instrument.rs1use crate::error::SoundFontError;
2use crate::instrument_info::InstrumentInfo;
3use crate::instrument_region::InstrumentRegion;
4use crate::sample_header::SampleHeader;
5use crate::zone::Zone;
6
7#[derive(Debug)]
9#[non_exhaustive]
10pub struct Instrument {
11 pub(crate) name: String,
12 pub(crate) regions: Vec<InstrumentRegion>,
13}
14
15impl Instrument {
16 fn new(
17 info: &InstrumentInfo,
18 instrument_id: usize,
19 zones: &[Zone],
20 samples: &[SampleHeader],
21 ) -> Result<Self, SoundFontError> {
22 let name = info.name.clone();
23
24 let zone_count = info.zone_end_index - info.zone_start_index + 1;
25 if zone_count <= 0 {
26 return Err(SoundFontError::InvalidInstrument(instrument_id));
27 }
28
29 let span_start = info.zone_start_index as usize;
30 let span_end = span_start + zone_count as usize;
31 let zone_span = &zones[span_start..span_end];
32 let regions = InstrumentRegion::create(instrument_id, zone_span, samples)?;
33
34 Ok(Self { name, regions })
35 }
36
37 pub(crate) fn create(
38 infos: &[InstrumentInfo],
39 zones: &[Zone],
40 samples: &[SampleHeader],
41 ) -> Result<Vec<Instrument>, SoundFontError> {
42 if infos.len() <= 1 {
43 return Err(SoundFontError::InstrumentNotFound);
44 }
45
46 let count = infos.len() - 1;
48
49 let mut instruments: Vec<Instrument> = Vec::with_capacity(count);
50 for (instrument_id, info) in infos.iter().take(count).enumerate() {
51 instruments.push(Instrument::new(info, instrument_id, zones, samples)?);
52 }
53
54 Ok(instruments)
55 }
56
57 pub fn get_name(&self) -> &str {
59 &self.name
60 }
61
62 pub fn get_regions(&self) -> &[InstrumentRegion] {
64 &self.regions[..]
65 }
66}