summaryrefslogtreecommitdiff
path: root/src/soundfont.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/soundfont.rs')
-rw-r--r--src/soundfont.rs14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/soundfont.rs b/src/soundfont.rs
index efa60dd..35a24aa 100644
--- a/src/soundfont.rs
+++ b/src/soundfont.rs
@@ -191,7 +191,7 @@ mod vorbis {
Err("bad vorbis file".to_string())
} else {
let samples = samples as usize;
- let mut vec = Vec::with_capacity(samples);
+ let mut vec = Vec::with_capacity(samples + 1);
for i in 0..samples {
vec.push(unsafe { *output.add(i) });
}
@@ -289,15 +289,17 @@ impl Sample {
file.read_exact(&mut data8)?;
match file_type {
FileType::SF2 => {
- self.data = vec![0i16; len];
+ self.data = Vec::with_capacity(len + 1);
for i in 0..len as usize {
- self.data[i] = i16::from_le_bytes([data8[2 * i], data8[2 * i + 1]]);
+ self.data.push(i16::from_le_bytes([data8[2 * i], data8[2 * i + 1]]));
}
}
FileType::SF3 => {
self.data = vorbis::decode(&data8).map_err(SampleError::Vorbis)?;
}
}
+ // (***) add an extra sample to the end to prevent OOB
+ self.data.push(self.data[self.data.len() - 1]);
Ok(())
}
}
@@ -948,10 +950,10 @@ impl SoundFont {
let start = read_u32(&mut file)?;
let end = read_u32(&mut file)?;
- if end < start {
+ if end <= start {
return Err(OpenError::BadSoundFont(format!(
"sample starts at {}, and ends before then (at {})",
- start, end
+ start, end as i64 - 1
)));
}
let mut startloop = read_u32(&mut file)?;
@@ -1314,6 +1316,8 @@ impl SoundFont {
break;
}
// interpolate between one sample and the next
+ // note: it's okay to do this even for samples where endloop = end, because
+ // we added an additional sample to the end -- see (***)
let sample1 = data[s] as f32;
let sample2 = data[s + 1] as f32;
let mut sample = sample1 + (sample2 - sample1) * (s_frac as f32);