1use std::error;
2use std::fmt;
3use std::io;
4
5use crate::four_cc::FourCC;
6
7#[derive(Debug)]
9#[non_exhaustive]
10pub enum SynthesizerError {
11 SampleRateOutOfRange(i32),
12 BlockSizeOutOfRange(usize),
13 MaximumPolyphonyOutOfRange(usize),
14}
15
16impl error::Error for SynthesizerError {}
17
18impl fmt::Display for SynthesizerError {
19 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
20 match self {
21 SynthesizerError::SampleRateOutOfRange(value) => write!(
22 f,
23 "the sample rate must be between 16000 and 192000, but was {}",
24 value
25 ),
26 SynthesizerError::BlockSizeOutOfRange(value) => write!(
27 f,
28 "the block size must be between 8 and 1024, but was {}",
29 value
30 ),
31 SynthesizerError::MaximumPolyphonyOutOfRange(value) => {
32 write!(
33 f,
34 "the maximum number of polyphony must be between 8 and 256, but was {}",
35 value
36 )
37 }
38 }
39 }
40}
41
42#[derive(Debug)]
44#[non_exhaustive]
45pub enum SoundFontError {
46 IoError(io::Error),
47 RiffChunkNotFound,
48 InvalidRiffChunkType {
49 expected: FourCC,
50 actual: FourCC,
51 },
52 ListChunkNotFound,
53 InvalidListChunkType {
54 expected: FourCC,
55 actual: FourCC,
56 },
57 ListContainsUnknownId(FourCC),
58 SampleDataNotFound,
59 UnsupportedSampleFormat,
60 SampleDecompressionFailed(String),
61 SubChunkNotFound(FourCC),
62 InvalidPresetList,
63 InvalidInstrumentId {
64 preset_id: usize,
65 instrument_id: usize,
66 },
67 InvalidPreset(usize),
68 PresetNotFound,
69 InvalidInstrumentList,
70 InvalidSampleId {
71 instrument_id: usize,
72 sample_id: usize,
73 },
74 InvalidInstrument(usize),
75 InstrumentNotFound,
76 InvalidSampleHeaderList,
77 InvalidZoneList,
78 ZoneNotFound,
79 InvalidGeneratorList,
80 SanityCheckFailed,
81}
82
83impl error::Error for SoundFontError {
84 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
85 match self {
86 SoundFontError::IoError(err) => Some(err),
87 _ => None,
88 }
89 }
90}
91
92impl fmt::Display for SoundFontError {
93 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94 match self {
95 SoundFontError::IoError(err) => err.fmt(f),
96 SoundFontError::RiffChunkNotFound => write!(f, "the RIFF chunk was not found"),
97 SoundFontError::InvalidRiffChunkType { expected, actual } => write!(
98 f,
99 "the type of the RIFF chunk must be '{}', but was '{}'",
100 expected, actual
101 ),
102 SoundFontError::ListChunkNotFound => write!(f, "the LIST chunk was not found"),
103 SoundFontError::InvalidListChunkType { expected, actual } => write!(
104 f,
105 "the type of the LIST chunk must be '{}', but was '{}'",
106 expected, actual
107 ),
108 SoundFontError::ListContainsUnknownId(id) => {
109 write!(f, "the INFO list contains an unknown ID '{id}'")
110 }
111 SoundFontError::SampleDataNotFound => write!(f, "no valid sample data was found"),
112 SoundFontError::UnsupportedSampleFormat => write!(
113 f,
114 "SoundFont3 is not supported; rebuild rustysynth-ext with the 'sf3' feature enabled"
115 ),
116 SoundFontError::SampleDecompressionFailed(message) => {
117 write!(f, "failed to decompress the sample data: {message}")
118 }
119 SoundFontError::SubChunkNotFound(id) => {
120 write!(f, "the '{}' sub-chunk was not found", id)
121 }
122 SoundFontError::InvalidPresetList => write!(f, "the preset list is invalid"),
123 SoundFontError::InvalidInstrumentId {
124 preset_id,
125 instrument_id,
126 } => write!(
127 f,
128 "the preset with the ID '{preset_id}' contains an invalid instrument ID '{instrument_id}'"
129 ),
130 SoundFontError::InvalidPreset(preset_id) => {
131 write!(f, "the preset with the ID '{preset_id}' has no zone")
132 }
133 SoundFontError::PresetNotFound => write!(f, "no valid preset was found"),
134 SoundFontError::InvalidInstrumentList => write!(f, "the instrument list is invalid"),
135 SoundFontError::InvalidSampleId {
136 instrument_id,
137 sample_id,
138 } => write!(
139 f,
140 "the instrument with the ID '{instrument_id}' contains an invalid sample ID '{sample_id}'"
141 ),
142 SoundFontError::InvalidInstrument(instrument_id) => {
143 write!(
144 f,
145 "the instrument with the ID '{instrument_id}' has no zone"
146 )
147 }
148 SoundFontError::InstrumentNotFound => write!(f, "no valid instrument was found"),
149 SoundFontError::InvalidSampleHeaderList => {
150 write!(f, "the sample header list is invalid")
151 }
152 SoundFontError::InvalidZoneList => write!(f, "the zone list is invalid"),
153 SoundFontError::ZoneNotFound => write!(f, "no valid zone was found"),
154 SoundFontError::InvalidGeneratorList => write!(f, "the generator list is invalid"),
155 SoundFontError::SanityCheckFailed => write!(f, "sanity check failed"),
156 }
157 }
158}
159
160impl From<io::Error> for SoundFontError {
161 fn from(err: io::Error) -> Self {
162 SoundFontError::IoError(err)
163 }
164}
165
166#[derive(Debug)]
168#[non_exhaustive]
169pub enum MidiFileError {
170 IoError(io::Error),
171 InvalidChunkType { expected: FourCC, actual: FourCC },
172 InvalidChunkData(FourCC),
173 UnsupportedFormat(i16),
174 InvalidTempoValue,
175}
176
177impl error::Error for MidiFileError {
178 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
179 match self {
180 MidiFileError::IoError(err) => Some(err),
181 _ => None,
182 }
183 }
184}
185
186impl fmt::Display for MidiFileError {
187 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
188 match self {
189 MidiFileError::IoError(err) => err.fmt(f),
190 MidiFileError::InvalidChunkType { expected, actual } => write!(
191 f,
192 "the chunk type must be '{}', but was '{}'",
193 expected, actual
194 ),
195 MidiFileError::InvalidChunkData(id) => write!(f, "the '{}' chunk has invalid data", id),
196 MidiFileError::UnsupportedFormat(format) => {
197 write!(f, "the format {} is not supported", format)
198 }
199 MidiFileError::InvalidTempoValue => write!(f, "failed to read the tempo value"),
200 }
201 }
202}
203
204impl From<io::Error> for MidiFileError {
205 fn from(err: io::Error) -> Self {
206 MidiFileError::IoError(err)
207 }
208}