Skip to content

Commit

Permalink
soundfont-rs: Privatize methods and types that leaked to public API
Browse files Browse the repository at this point in the history
  • Loading branch information
PolyMeilex committed Dec 27, 2024
1 parent 36f3f99 commit fce4750
Show file tree
Hide file tree
Showing 13 changed files with 58 additions and 65 deletions.
7 changes: 1 addition & 6 deletions oxisynth/src/core/soundfont.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,7 @@ impl SoundFont {

let sf2 = sf2.sort_presets();

let smpl = sf2.sample_data.smpl.as_ref().unwrap();

let sample_pos = smpl.offset() + 8;
let sample_size = smpl.len() as usize;

let sample_data = SampleData::load(file, sample_pos, sample_size)?;
let sample_data = SampleData::load(file, sf2.sample_data.smpl.as_ref().unwrap())?;

let mut samples = Vec::new();

Expand Down
11 changes: 6 additions & 5 deletions oxisynth/src/core/soundfont/sample_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::{
sync::Arc,
};

use soundfont::raw::SampleChunk;

#[derive(Debug, Clone)]
pub struct SampleData(Arc<[i16]>);

Expand All @@ -11,11 +13,10 @@ impl SampleData {
Self(data)
}

pub fn load<F: Read + Seek>(
file: &mut F,
sample_pos: u64,
sample_size: usize,
) -> Result<Self, ()> {
pub fn load<F: Read + Seek>(file: &mut F, smpl: &SampleChunk) -> Result<Self, ()> {
let sample_pos = smpl.offset;
let sample_size = smpl.len as usize;

if file.seek(SeekFrom::Start(sample_pos)).is_err() {
log::error!("Failed to seek position in data file",);
return Err(());
Expand Down
15 changes: 1 addition & 14 deletions soundfont-rs/src/raw/hydra.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub struct Hydra {
}

impl Hydra {
pub fn read(
pub(crate) fn read(
pdta: &Chunk,
file: &mut ScratchReader<impl Read + Seek>,
) -> Result<Self, ParseError> {
Expand Down Expand Up @@ -119,17 +119,4 @@ impl Hydra {
sample_headers: sample_headers.ok_or(SampleHeaders)?,
})
}

pub fn pop_terminators(&mut self) {
self.preset_headers.pop().unwrap();
self.preset_bags.pop().unwrap();
self.preset_modulators.pop().unwrap();
self.preset_generators.pop().unwrap();

self.instrument_headers.pop().unwrap();
self.instrument_bags.pop().unwrap();
self.instrument_modulators.pop().unwrap();
self.instrument_generators.pop().unwrap();
self.sample_headers.pop().unwrap();
}
}
4 changes: 2 additions & 2 deletions soundfont-rs/src/raw/hydra/bag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub struct Bag {
}

impl Bag {
pub fn read(reader: &mut Reader) -> Result<Self, ParseError> {
pub(crate) fn read(reader: &mut Reader) -> Result<Self, ParseError> {
let generator_id: u16 = reader.read_u16()?;
let modulator_id: u16 = reader.read_u16()?;

Expand All @@ -24,7 +24,7 @@ impl Bag {
})
}

pub fn read_all(
pub(crate) fn read_all(
pbag: &Chunk,
file: &mut ScratchReader<impl Read + Seek>,
) -> Result<Vec<Self>, ParseError> {
Expand Down
4 changes: 2 additions & 2 deletions soundfont-rs/src/raw/hydra/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub struct Generator {
}

impl Generator {
pub fn read(reader: &mut Reader) -> Result<Self, ParseError> {
pub(crate) fn read(reader: &mut Reader) -> Result<Self, ParseError> {
let id: u16 = reader.read_u16()?;

let ty = GeneratorType::try_from(id)
Expand All @@ -88,7 +88,7 @@ impl Generator {
Ok(Self { ty, amount })
}

pub fn read_all(
pub(crate) fn read_all(
pmod: &Chunk,
file: &mut ScratchReader<impl Read + Seek>,
) -> Result<Vec<Self>, ParseError> {
Expand Down
4 changes: 2 additions & 2 deletions soundfont-rs/src/raw/hydra/instrument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ pub struct InstrumentHeader {
}

impl InstrumentHeader {
pub fn read(reader: &mut Reader) -> Result<Self, ParseError> {
pub(crate) fn read(reader: &mut Reader) -> Result<Self, ParseError> {
let name: String = reader.read_string(20)?.trim_end().to_owned();
let bag_id: u16 = reader.read_u16()?;

Ok(Self { name, bag_id })
}

pub fn read_all(
pub(crate) fn read_all(
phdr: &Chunk,
file: &mut ScratchReader<impl Read + Seek>,
) -> Result<Vec<Self>, ParseError> {
Expand Down
4 changes: 2 additions & 2 deletions soundfont-rs/src/raw/hydra/modulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ pub struct Modulator {
}

impl Modulator {
pub fn read(reader: &mut Reader, terminal: bool) -> Result<Self, ParseError> {
pub(crate) fn read(reader: &mut Reader, terminal: bool) -> Result<Self, ParseError> {
let mut src: u16 = reader.read_u16()?;
let mut dest: u16 = reader.read_u16()?;
let mut amount: i16 = reader.read_i16()?;
Expand All @@ -293,7 +293,7 @@ impl Modulator {
})
}

pub fn read_all(
pub(crate) fn read_all(
pmod: &Chunk,
file: &mut ScratchReader<impl Read + Seek>,
) -> Result<Vec<Self>, ParseError> {
Expand Down
4 changes: 2 additions & 2 deletions soundfont-rs/src/raw/hydra/preset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct PresetHeader {
}

impl PresetHeader {
pub fn read(reader: &mut Reader) -> Result<Self, ParseError> {
pub(crate) fn read(reader: &mut Reader) -> Result<Self, ParseError> {
let name: String = reader.read_string(20)?.trim_end().to_owned();
let preset: u16 = reader.read_u16()?;
let bank: u16 = reader.read_u16()?;
Expand All @@ -44,7 +44,7 @@ impl PresetHeader {
})
}

pub fn read_all(
pub(crate) fn read_all(
phdr: &Chunk,
file: &mut ScratchReader<impl Read + Seek>,
) -> Result<Vec<Self>, ParseError> {
Expand Down
4 changes: 2 additions & 2 deletions soundfont-rs/src/raw/hydra/sample.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub struct SampleHeader {
}

impl SampleHeader {
pub fn read(reader: &mut Reader) -> Result<Self, ParseError> {
pub(crate) fn read(reader: &mut Reader) -> Result<Self, ParseError> {
let name: String = reader.read_string(20)?.trim_end().to_owned();
// 20

Expand Down Expand Up @@ -78,7 +78,7 @@ impl SampleHeader {
})
}

pub fn read_all(
pub(crate) fn read_all(
phdr: &Chunk,
file: &mut ScratchReader<impl Read + Seek>,
) -> Result<Vec<Self>, ParseError> {
Expand Down
2 changes: 1 addition & 1 deletion soundfont-rs/src/raw/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub struct Info {
}

impl Info {
pub fn read(
pub(crate) fn read(
info: &Chunk,
file: &mut ScratchReader<impl Read + Seek>,
) -> Result<Self, ParseError> {
Expand Down
34 changes: 28 additions & 6 deletions soundfont-rs/src/raw/sample_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,45 @@ use crate::{error::ParseError, riff::ChunkId};

use std::io::{Read, Seek};

/// Sample can be read like so:
/// ```ignore
/// file.seek(SeekFrom::Start(chunk.offset))?;
///
/// let mut buff = vec![0u8; chunk.len as usize];
/// file.read_exact(&mut buff)?;
/// ```
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub struct SampleChunk {
pub offset: u64,
pub len: u32,
}

impl SampleChunk {
fn new(chunk: Chunk) -> Self {
Self {
offset: chunk.content_offset(),
len: chunk.len(),
}
}
}

/// The Sample Binary Data
#[derive(Debug)]
pub struct SampleData {
/// The smpl sub-chunk, if present, contains one or more “samples” of digital audio information in the form of linearly coded sixteen bit, signed, little endian (least significant byte first) words. Each sample is followed by a minimum of forty-six zero valued sample data points. These zero valued data points are necessary to guarantee that any reasonable upward pitch shift using any reasonable interpolator can loop on zero data at the end of the sound.
pub smpl: Option<Chunk>,
/// The sm24 sub-chunk, if present, contains the least significant byte counterparts to each sample data point contained in the smpl chunk. Note this means for every two bytes in the [smpl] sub-chunk there is a 1-byte counterpart in [sm24] sub-chunk.
pub smpl: Option<SampleChunk>,
/// The sm24 sub-chunk, if present, contains the least significant byte counterparts to each sample data point contained in the smpl chunk. Note this means for every two bytes in the [Self::smpl] sub-chunk there is a 1-byte counterpart in [Self::sm24] sub-chunk.
///
/// These sample waveform points are to be combined with the sample waveform points in the smpl sub-chunk, to collectively create a single sample data pool with up to 24 bits of resolution.
///
/// If the smpl Sub-chunk is not present, the sm24 sub-chunk should be ignored. If the ifil version of the format is less than thatwhich represents 2.04, the sm24 sub-chunk should be ignored. If the size of the sm24 chunk is not exactly equal to the ½ the size of the smpl chunk (+ 1 byte in the case that ½ the size of smpl chunk is an odd value), the sm24 sub-chunk should be ignored.
///
/// In any and all cases where the sm24 sub-chunk is ignored, the synthesizer should render only those samples contained within the smpl sub-chunk.
pub sm24: Option<Chunk>,
pub sm24: Option<SampleChunk>,
}

impl SampleData {
pub fn read<F: Read + Seek>(sdta: &Chunk, file: &mut F) -> Result<Self, ParseError> {
pub(crate) fn read<F: Read + Seek>(sdta: &Chunk, file: &mut F) -> Result<Self, ParseError> {
assert_eq!(sdta.id(), ChunkId::LIST);
assert_eq!(sdta.read_type(file)?, ChunkId::sdta);

Expand All @@ -34,11 +56,11 @@ impl SampleData {
match id {
// The Digital Audio Samples for the upper 16 bits
ChunkId::smpl => {
smpl = Some(ch);
smpl = Some(SampleChunk::new(ch));
}
// The Digital Audio Samples for the lower 8 bits
ChunkId::sm24 => {
sm24 = Some(ch);
sm24 = Some(SampleChunk::new(ch));
}
_ => {
return Err(ParseError::UnexpectedMemberOfSampleData(ch));
Expand Down
3 changes: 2 additions & 1 deletion soundfont-rs/src/raw/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::error::ParseError;
use std::convert::TryInto;

pub struct Reader<'a> {
pub(crate) struct Reader<'a> {
data: &'a [u8],
curr: usize,
}
Expand All @@ -10,6 +10,7 @@ impl<'a> Reader<'a> {
Self { data, curr: 0 }
}

#[allow(dead_code)]
pub fn read(&mut self, len: usize) -> &[u8] {
let start = self.curr;
let end = self.curr + len;
Expand Down
27 changes: 7 additions & 20 deletions soundfont-rs/src/riff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::{
pub struct ScratchReader<T> {
/// Scratch buffer
buff: Vec<u8>,
pub io: T,
io: T,
}

impl<T> ScratchReader<T> {
Expand Down Expand Up @@ -148,7 +148,7 @@ impl fmt::Debug for ChunkId {
}
}

/// A chunk, also known as a form
/// A RIFF chunk
#[derive(PartialEq, Eq, Debug)]
pub struct Chunk {
pos: u64,
Expand Down Expand Up @@ -191,9 +191,9 @@ impl Chunk {
self.len
}

/// Returns the offset of this chunk from the start of the stream.
pub fn offset(&self) -> u64 {
self.pos
/// Returns the content offset of this chunk from the start of the stream.
pub fn content_offset(&self) -> u64 {
self.pos + 8
}

/// Reads the chunk type of this chunk.
Expand Down Expand Up @@ -236,7 +236,7 @@ impl Chunk {
where
T: Read + Seek,
{
stream.seek(SeekFrom::Start(self.pos + 8))?;
stream.seek(SeekFrom::Start(self.content_offset()))?;

stream.read_exact(buf)?;

Expand All @@ -252,27 +252,14 @@ impl Chunk {
{
let ScratchReader { buff, io } = stream;

io.seek(SeekFrom::Start(self.pos + 8))?;
io.seek(SeekFrom::Start(self.content_offset()))?;

buff.resize(self.len as usize, 0);
io.read_exact(buff)?;

Ok(buff)
}

/// Reads the entirety of the contents of a chunk.
pub fn read_to_vec<T>(&self, stream: &mut T) -> std::io::Result<Vec<u8>>
where
T: Read + Seek,
{
stream.seek(SeekFrom::Start(self.pos + 8))?;

let mut data: Vec<u8> = vec![0; self.len as usize];
stream.read_exact(&mut data)?;

Ok(data)
}

/// Returns an iterator over the children of the chunk.
pub fn iter(&self) -> Iter {
Iter {
Expand Down

0 comments on commit fce4750

Please sign in to comment.