Skip to content

Commit

Permalink
several updates and fixes
Browse files Browse the repository at this point in the history
- fix clippy warnings.
- derive more traits, specially Clone, PartialEq, Eq, Default.
- update comments.
- update example.
- rustfmt.
  • Loading branch information
joseluis committed Sep 30, 2022
1 parent 71bc0c6 commit 3ea276c
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 21 deletions.
5 changes: 5 additions & 0 deletions examples/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ fn main() {
Please run the example from the examples/ directory",
);

// for region in &i.regions {
// println!("{:?}", region);
// }


println!("{:#?}", i);

println!("groups: {}\nregions: {}", i.groups(), i.regions());
Expand Down
4 changes: 3 additions & 1 deletion src/sfz/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::sfz::{Opcode, OpcodeMap};
/// A group is defined with the <group> opcode, and the parameters enumerated
/// on it last till the next group opcode, or till the end of the file.
///
#[derive(Debug, Default)]
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Group {
/// This list of opcodes overwrites the default ones.
pub opcodes: OpcodeMap,
Expand All @@ -17,10 +17,12 @@ pub struct Group {
}

impl Group {
/// New group.
pub fn new() -> Self {
Self::default()
}

/// Add an opcode to the group.
pub fn add_opcode(&mut self, o: &Opcode) {
self.opcodes.insert(o.str_name(), o.clone());
}
Expand Down
2 changes: 1 addition & 1 deletion src/sfz/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::sfz::SfzToken;
///
/// [sfzformat.com/headers/](https://sfzformat.com/headers/)
#[derive(Debug, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Header {
// sfz v1 headers
/// The basic component of an instrument. An instrument is defined by one or more regions.
Expand Down
4 changes: 2 additions & 2 deletions src/sfz/instrument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
/// International Pitch Notation (IPN) convention. According to this rules,
/// middle C in the keyboard is C4 and the MIDI note number 60.
///
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct Instrument {
/// The default opcodes for this instrument.
pub global: OpcodeMap,
Expand Down Expand Up @@ -341,7 +341,7 @@ impl Instrument {
}

/// The current status of the parsing of the instrument
#[derive(Debug)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
struct InstrumentParsingStatus {
is_header_control: bool,
is_header_global: bool,
Expand Down
2 changes: 1 addition & 1 deletion src/sfz/opcodes/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::sfz::types::{
/// - [Cakewalk Extensions Opcodes](https://sfzformat.com/extensions/cakewalk/)
///
#[allow(non_camel_case_types)]
#[derive(Debug, PartialEq, Clone)]
#[derive(Clone, Debug, PartialEq)]
pub enum Opcode {
// sfz v1 opcodes -----------------------------------------------------------
// https://sfzformat.com/misc/sfz2
Expand Down
14 changes: 6 additions & 8 deletions src/sfz/opcodes/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl Opcode {
("cutoff", _) => {
utils::check_f32_between(value, 0., MAX_SAMPLE_RATE).map(Opcode::cutoff)
}
("fil_type", _) => fil_type::from_str(value).map(Opcode::fil_type),
("fil_type", _) => fil_type::from_name(value).map(Opcode::fil_type),
("fil_veltrack", _) => {
utils::check_i16_between(value, -9600, 9600).map(Opcode::fil_veltrack)
}
Expand All @@ -183,16 +183,14 @@ impl Opcode {
// NOTE: lokey v2 accepts i8, from -1:
("lokey", _) => utils::check_midi_note(value).map(Opcode::lokey),
("lovel", _) => utils::check_u8_between(value, 0, 127).map(Opcode::lovel),
("loop_mode", _) => loop_mode::from_str(value).map(Opcode::loop_mode),
("loop_mode", _) => loop_mode::from_name(value).map(Opcode::loop_mode),
("lorand", _) => utils::check_f32_between(value, 0., 1.).map(Opcode::lorand),
("off_by", _) => utils::check_u32_between(value, 0, u32::MAX).map(Opcode::off_by),
("offset", _) => utils::check_u32_between(value, 0, u32::MAX).map(Opcode::offset),
("on_loccN", _) => utils::check_i8_between(value, 0, 127).map(Opcode::on_loccN),
("on_hiccN", _) => utils::check_i8_between(value, 0, 127).map(Opcode::on_hiccN),
("pan", _) => utils::check_f32_between(value, 0., 100.).map(Opcode::pan),
("pitch_keycenter", _) => {
utils::check_midi_note(value).map(Opcode::pitch_keycenter)
}
("pitch_keycenter", _) => utils::check_midi_note(value).map(Opcode::pitch_keycenter),
("pitch_keytrack", _) => {
utils::check_i16_between(value, -1200, 1200).map(Opcode::pitch_keytrack)
}
Expand All @@ -203,7 +201,7 @@ impl Opcode {
("sample", _) => Some(Opcode::sample(utils::fix_path_separators(value))),
("seq_lenght", _) => utils::check_u8_between(value, 1, 100).map(Opcode::seq_length),
("seq_position", _) => utils::check_u8_between(value, 1, 100).map(Opcode::seq_position),
("trigger", _) => trigger::from_str(value).map(Opcode::trigger),
("trigger", _) => trigger::from_name(value).map(Opcode::trigger),
("sw_hikey", _) => utils::check_midi_note(value).map(Opcode::sw_hikey),
("sw_last", _) => utils::check_u8_between(value, 0, 127).map(Opcode::sw_last),
("sw_lokey", _) => utils::check_midi_note(value).map(Opcode::sw_lokey),
Expand Down Expand Up @@ -232,7 +230,7 @@ impl Opcode {

/// Token for parsing SFZ format elements like headers and tokens
///
#[derive(Logos, Debug, PartialEq)]
#[derive(Logos, Clone, Debug, PartialEq)]
pub(crate) enum SfzToken {
/// Parses a Header
///
Expand Down Expand Up @@ -266,7 +264,7 @@ pub(crate) enum SfzToken {
/// Some opcode names contains numbers that must not be interpreted as parameters.
/// It makes sure to filter out false positives,
/// as parameters,
#[derive(Logos, Debug, PartialEq)]
#[derive(Logos, Clone, Debug, PartialEq)]
pub(crate) enum OpcodeParameter {
/// Skip numbers that must not be recognized as parameters,
/// since they are part of the opcode's name.
Expand Down
4 changes: 3 additions & 1 deletion src/sfz/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::sfz::{Opcode, OpcodeMap};
/// All Input Controls defined in a region act using the AND boolean operator.
/// Consequently, all conditions must be matched for the region to play.
///
#[derive(Debug, Default)]
#[derive(Clone, Debug, Default)]
pub struct Region {
/// The opcodes of this group are applied and will override the defaults.
pub group: Option<usize>,
Expand All @@ -30,10 +30,12 @@ pub struct Region {
}

impl Region {
/// New region.
pub fn new() -> Self {
Self::default()
}

/// New region with some group.
// FIXME (add group at posteriori)
pub fn with_group(group: usize) -> Self {
Self {
Expand Down
67 changes: 60 additions & 7 deletions src/sfz/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub const MAX_SAMPLE_RATE: f32 = 384_000.0;

/// All the possible types allowed in an Opcode
#[allow(non_camel_case_types)]
#[derive(Debug, Clone)]
#[derive(Clone, Debug, PartialEq, Eq)]

This comment has been minimized.

Copy link
@deermichel

deermichel Sep 30, 2022

Contributor

@joseluis this seems to cause a compilation issue. It compiles if I remove the Eq trait.

image

This comment has been minimized.

Copy link
@deermichel

deermichel Sep 30, 2022

Contributor

fix: #6

pub enum OpcodeType {
i8(Option<i8>),
u8(Option<u8>),
Expand All @@ -43,17 +43,41 @@ pub type OpcodeMap = HashMap<String, Opcode>;
/// Allows playing samples with loops defined in the unlooped mode.
///
/// - info: [loop_mode](https://sfzformat.com/opcodes/loop_mode)
#[derive(Debug, Clone, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum loop_mode {
/// no looping will be performed. Sample will play straight from start to end,
/// or until note off, whatever reaches first.
///
/// This is the default.
no_loop,

/// sample will play from start to end, ignoring note off. This is commonly
/// used for drums. This mode is engaged automatically if the count opcode
/// is defined.
one_shot,

/// once the player reaches sample loop point, the loop will play until note
/// expiration. This includes looping during the release phase.
loop_continuous,

/// the player will play the loop while the note is held, by keeping it
/// depressed or by using the sustain pedal (CC64). During the release phase,
/// there’s no looping.
loop_sustain,
}

// IMPROVE: `no_loop` for samples without a loop defined,
// `loop_continuous` for samples with defined loop(s).
impl Default for loop_mode {
fn default() -> loop_mode {
Self::no_loop
}
}

impl loop_mode {
/// Constructor from the variant name, as a string
pub fn from_str(name: &str) -> Option<Self> {
pub fn from_name(name: &str) -> Option<Self> {
match name {
"no_loop" => Some(Self::no_loop),
"one_shot" => Some(Self::one_shot),
Expand All @@ -67,18 +91,38 @@ impl loop_mode {
/// Sets the trigger which will be used for the sample to play.
///
/// - info: [trigger](https://sfzformat.com/opcodes/trigger)
#[derive(Debug, Clone, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum trigger {
/// (Default): Region will play on note-on.
attack,

/// Region will play on note-off or sustain pedal off. The velocity used to
/// play the note-off sample is the velocity value of the corresponding
/// (previous) note-on message.
release,

/// Region will play on note-on, but if there’s no other note going on
/// (comoonly used for or first note in a legato phrase).
first,

/// Region will play on note-on, but only if there’s a note going on
/// (notes after first note in a legato phrase).
legato,

/// Region will play on note-off. Ignores sustain pedal.
release_key, // aria
}

impl Default for trigger {
fn default() -> trigger {
Self::attack
}
}

impl trigger {
/// Constructor from the variant name, as a string
pub fn from_str(name: &str) -> Option<Self> {
pub fn from_name(name: &str) -> Option<Self> {
match name {
"attack" => Some(Self::attack),
"release" => Some(Self::release),
Expand All @@ -93,7 +137,7 @@ impl trigger {
/// Allows you to choose which type of filter you use if not specified
///
/// - info: [fil_type](https://sfzformat.com/opcodes/fil_type)
#[derive(Debug, Clone, PartialEq)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub enum fil_type {
/// One-pole low pass filter (6dB/octave)
Expand All @@ -108,6 +152,8 @@ pub enum fil_type {

/// Two-pole low pass filter (12dB/octave)
///
/// This is the default.
///
/// - version: v1
lpf_2p,

Expand Down Expand Up @@ -211,9 +257,16 @@ pub enum fil_type {
/// - version: ARIA
peq,
}

impl Default for fil_type {
fn default() -> fil_type {
Self::lpf_2p
}
}

impl fil_type {
/// Constructor from the variant name, as a string
pub fn from_str(name: &str) -> Option<Self> {
pub fn from_name(name: &str) -> Option<Self> {
match name {
"lpf_1p" => Some(Self::lpf_1p),
"hpf_1p" => Some(Self::hpf_1p),
Expand Down

0 comments on commit 3ea276c

Please sign in to comment.