Skip to main content

rustysynth_ext/
soundfont_info.rs

1use std::io::Read;
2
3use crate::binary_reader::BinaryReader;
4use crate::error::SoundFontError;
5use crate::four_cc::FourCC;
6use crate::read_counter::ReadCounter;
7use crate::soundfont_version::SoundFontVersion;
8
9/// The information of a SoundFont.
10#[derive(Debug)]
11#[non_exhaustive]
12pub struct SoundFontInfo {
13    pub(crate) version: SoundFontVersion,
14    pub(crate) target_sound_engine: String,
15    pub(crate) bank_name: String,
16    pub(crate) rom_name: String,
17    pub(crate) rom_version: SoundFontVersion,
18    pub(crate) creation_date: String,
19    pub(crate) author: String,
20    pub(crate) target_product: String,
21    pub(crate) copyright: String,
22    pub(crate) comments: String,
23    pub(crate) tools: String,
24}
25
26impl SoundFontInfo {
27    pub(crate) fn new<R: Read>(reader: &mut R) -> Result<Self, SoundFontError> {
28        let chunk_id = BinaryReader::read_four_cc(reader)?;
29        if chunk_id != b"LIST" {
30            return Err(SoundFontError::ListChunkNotFound);
31        }
32
33        let end = BinaryReader::read_u32(reader)? as usize;
34        let reader = &mut ReadCounter::new(reader);
35
36        let list_type = BinaryReader::read_four_cc(reader)?;
37        if list_type != b"INFO" {
38            return Err(SoundFontError::InvalidListChunkType {
39                expected: FourCC::from_bytes(*b"INFO"),
40                actual: list_type,
41            });
42        }
43
44        let mut version: Option<SoundFontVersion> = None;
45        let mut target_sound_engine: Option<String> = None;
46        let mut bank_name: Option<String> = None;
47        let mut rom_name: Option<String> = None;
48        let mut rom_version: Option<SoundFontVersion> = None;
49        let mut creation_date: Option<String> = None;
50        let mut author: Option<String> = None;
51        let mut target_product: Option<String> = None;
52        let mut copyright: Option<String> = None;
53        let mut comments: Option<String> = None;
54        let mut tools: Option<String> = None;
55
56        while reader.bytes_read() < end {
57            let id = BinaryReader::read_four_cc(reader)?;
58            let size = BinaryReader::read_u32(reader)? as usize;
59
60            match id.as_bytes() {
61                b"ifil" => version = Some(SoundFontVersion::new(reader)?),
62                b"isng" => {
63                    target_sound_engine =
64                        Some(BinaryReader::read_fixed_length_string(reader, size)?)
65                }
66                b"INAM" => bank_name = Some(BinaryReader::read_fixed_length_string(reader, size)?),
67                b"irom" => rom_name = Some(BinaryReader::read_fixed_length_string(reader, size)?),
68                b"iver" => rom_version = Some(SoundFontVersion::new(reader)?),
69                b"ICRD" => {
70                    creation_date = Some(BinaryReader::read_fixed_length_string(reader, size)?)
71                }
72                b"IENG" => author = Some(BinaryReader::read_fixed_length_string(reader, size)?),
73                b"IPRD" => {
74                    target_product = Some(BinaryReader::read_fixed_length_string(reader, size)?)
75                }
76                b"ICOP" => copyright = Some(BinaryReader::read_fixed_length_string(reader, size)?),
77                b"ICMT" => comments = Some(BinaryReader::read_fixed_length_string(reader, size)?),
78                b"ISFT" => tools = Some(BinaryReader::read_fixed_length_string(reader, size)?),
79                _ => return Err(SoundFontError::ListContainsUnknownId(id)),
80            }
81        }
82
83        let version = version.unwrap_or_else(SoundFontVersion::default);
84        let target_sound_engine = target_sound_engine.unwrap_or_default();
85        let bank_name = bank_name.unwrap_or_default();
86        let rom_name = rom_name.unwrap_or_default();
87        let rom_version = rom_version.unwrap_or_else(SoundFontVersion::default);
88        let creation_date = creation_date.unwrap_or_default();
89        let author = author.unwrap_or_default();
90        let target_product = target_product.unwrap_or_default();
91        let copyright = copyright.unwrap_or_default();
92        let comments = comments.unwrap_or_default();
93        let tools = tools.unwrap_or_default();
94
95        Ok(Self {
96            version,
97            target_sound_engine,
98            bank_name,
99            rom_name,
100            rom_version,
101            creation_date,
102            author,
103            target_product,
104            copyright,
105            comments,
106            tools,
107        })
108    }
109
110    /// Gets the version of the SoundFont.
111    pub fn get_version(&self) -> &SoundFontVersion {
112        &self.version
113    }
114
115    /// Gets the target sound engine of the SoundFont.
116    pub fn get_target_sound_engine(&self) -> &str {
117        &self.target_sound_engine
118    }
119
120    /// Gets the bank name of the SoundFont.
121    pub fn get_bank_name(&self) -> &str {
122        &self.bank_name
123    }
124
125    /// Gets the ROM name of the SoundFont.
126    pub fn get_rom_name(&self) -> &str {
127        &self.rom_name
128    }
129
130    /// Gets the ROM version of the SoundFont.
131    pub fn get_rom_version(&self) -> &SoundFontVersion {
132        &self.rom_version
133    }
134
135    /// Gets the creation date of the SoundFont.
136    pub fn get_creation_date(&self) -> &str {
137        &self.creation_date
138    }
139
140    /// Gets the author of the SoundFont.
141    pub fn get_author(&self) -> &str {
142        &self.author
143    }
144
145    /// Gets the target product of the SoundFont.
146    pub fn get_target_product(&self) -> &str {
147        &self.target_product
148    }
149
150    /// Gets the copyright message for the SoundFont.
151    pub fn get_copyright(&self) -> &str {
152        &self.copyright
153    }
154
155    /// Gets the comments for the SoundFont.
156    pub fn get_comments(&self) -> &str {
157        &self.comments
158    }
159
160    /// Gets the tools used to create the SoundFont.
161    pub fn get_tools(&self) -> &str {
162        &self.tools
163    }
164}