rustysynth/
sample_header.rs

1#![allow(dead_code)]
2
3use std::io::Read;
4
5use crate::binary_reader::BinaryReader;
6use crate::error::SoundFontError;
7
8/// Represents a sample in the SoundFont.
9#[derive(Debug)]
10#[non_exhaustive]
11pub struct SampleHeader {
12    pub(crate) name: String,
13    pub(crate) start: i32,
14    pub(crate) end: i32,
15    pub(crate) start_loop: i32,
16    pub(crate) end_loop: i32,
17    pub(crate) sample_rate: i32,
18    pub(crate) original_pitch: u8,
19    pub(crate) pitch_correction: i8,
20    pub(crate) link: u16,
21    pub(crate) sample_type: u16,
22}
23
24impl SampleHeader {
25    fn new<R: Read>(reader: &mut R) -> Result<Self, SoundFontError> {
26        let name = BinaryReader::read_fixed_length_string(reader, 20)?;
27        let start = BinaryReader::read_i32(reader)?;
28        let end = BinaryReader::read_i32(reader)?;
29        let start_loop = BinaryReader::read_i32(reader)?;
30        let end_loop = BinaryReader::read_i32(reader)?;
31        let sample_rate = BinaryReader::read_i32(reader)?;
32        let original_pitch = BinaryReader::read_u8(reader)?;
33        let pitch_correction = BinaryReader::read_i8(reader)?;
34        let link = BinaryReader::read_u16(reader)?;
35        let sample_type = BinaryReader::read_u16(reader)?;
36
37        Ok(Self {
38            name,
39            start,
40            end,
41            start_loop,
42            end_loop,
43            sample_rate,
44            original_pitch,
45            pitch_correction,
46            link,
47            sample_type,
48        })
49    }
50
51    pub(crate) fn read_from_chunk<R: Read>(
52        reader: &mut R,
53        size: usize,
54    ) -> Result<Vec<SampleHeader>, SoundFontError> {
55        if size == 0 || size % 46 != 0 {
56            return Err(SoundFontError::InvalidSampleHeaderList);
57        }
58
59        let count = size / 46 - 1;
60
61        let mut headers: Vec<SampleHeader> = Vec::new();
62        for _i in 0..count {
63            headers.push(SampleHeader::new(reader)?);
64        }
65
66        // The last one is the terminator.
67        SampleHeader::new(reader)?;
68
69        Ok(headers)
70    }
71
72    /// Gets the name of the sample.
73    pub fn get_name(&self) -> &str {
74        &self.name
75    }
76
77    /// Gets the start point of the sample in the sample data.
78    pub fn get_start(&self) -> i32 {
79        self.start
80    }
81
82    /// Gets the end point of the sample in the sample data.
83    pub fn get_end(&self) -> i32 {
84        self.end
85    }
86
87    /// Gets the loop start point of the sample in the sample data.
88    pub fn get_start_loop(&self) -> i32 {
89        self.start_loop
90    }
91
92    /// Gets the loop end point of the sample in the sample data.
93    pub fn get_end_loop(&self) -> i32 {
94        self.end_loop
95    }
96
97    /// Gets the sample rate of the sample.
98    pub fn get_sample_rate(&self) -> i32 {
99        self.sample_rate
100    }
101
102    /// Gets the key number of the recorded pitch of the sample.
103    pub fn get_original_pitch(&self) -> i32 {
104        self.original_pitch as i32
105    }
106
107    /// Gets the pitch correction in cents that should be applied to the sample on playback.
108    pub fn get_pitch_correction(&self) -> i32 {
109        self.pitch_correction as i32
110    }
111
112    /// Gets the link info.
113    pub fn get_link(&self) -> i32 {
114        self.link as i32
115    }
116
117    /// Gets the sample type.
118    pub fn get_sample_type(&self) -> i32 {
119        self.sample_type as i32
120    }
121}