Skip to content

Commit

Permalink
Wrap comments
Browse files Browse the repository at this point in the history
  • Loading branch information
feldspath committed Oct 10, 2024
1 parent ef44909 commit 0cb9e6d
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 43 deletions.
17 changes: 8 additions & 9 deletions src/acid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ pub enum Timing {
Rest,
}

/// Trig used to create acid tracks with [`DeteTrack::new_acid`]. Each Trig represents one
/// sixteenth step. `AcidTrig` provides a similar interface to the original [`Roland TB-303`] with
/// some slight modifications.
/// Trig used to create acid tracks with [`DeteTrack::new_acid`]. Each Trig represents one sixteenth
/// step. `AcidTrig` provides a similar interface to the original [`Roland TB-303`] with some slight
/// modifications.
///
/// [`Roland TB-303`]: https://en.wikipedia.org/wiki/Roland_TB-303
#[derive(Debug, serde::Deserialize)]
Expand All @@ -31,9 +31,8 @@ pub struct AcidTrig {
use Timing::*;

impl DeteTrack {
/// Create a new acid track following the trigs in `pattern`.
/// The `root` note is used for transposition. The track will be played on the MIDI channel
/// with `channel_id`.
/// Create a new acid track following the trigs in `pattern`. The `root` note is used for
/// transposition. The track will be played on the MIDI channel with `channel_id`.
pub fn new_acid(pattern: Vec<AcidTrig>, root: Note, channel_id: u8, name: &str) -> Self {
if pattern.is_empty() {
return DeteTrack::new(0, vec![], root, channel_id, name);
Expand Down Expand Up @@ -98,9 +97,9 @@ impl DeteTrack {
DeteTrack::new(6 * pattern.len() as u32, notes, root, channel_id, name)
}

/// Load an acid track from a csv file (`filename`). Refer to this
/// [`example`] for an example file. The `root` note is used for transposition. The track
/// will be played on the MIDI channel with `channel_id`.
/// Load an acid track from a csv file (`filename`). Refer to this [`example`] for an example
/// file. The `root` note is used for transposition. The track will be played on the MIDI
/// channel with `channel_id`.
///
/// [`example`]: https://github.com/MF-Room/mseq/tree/main/examples/res/acid_0.csv
pub fn load_acid_from_file<P: AsRef<Path>>(
Expand Down
10 changes: 5 additions & 5 deletions src/arp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ pub enum ArpDiv {
}

impl DeteTrack {
/// Create a new arpeggiator track following the notes in `pattern` with the `div` time division.
/// The `root` note is used for transposition. The track will be played on the MIDI channel
/// with `channel_id`.
/// Create a new arpeggiator track following the notes in `pattern` with the `div` time
/// division. The `root` note is used for transposition. The track will be played on the MIDI
/// channel with `channel_id`.
pub fn new_arp(
pattern: Vec<MidiNote>,
div: ArpDiv,
Expand All @@ -39,8 +39,8 @@ impl DeteTrack {
DeteTrack::new(len, notes, root, channel_id, name)
}

/// Load an arpeggiator track from a csv file (`filename`) and a time division (`div`). Refer to this
/// [`example`] for an example file. The `root` note is used for transposition. The track
/// Load an arpeggiator track from a csv file (`filename`) and a time division (`div`). Refer to
/// this [`example`] for an example file. The `root` note is used for transposition. The track
/// will be played on the MIDI channel with `channel_id`.
///
/// [`example`]: https://github.com/MF-Room/mseq/tree/main/examples/res/arp_0.csv
Expand Down
14 changes: 8 additions & 6 deletions src/conductor.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use crate::{Context, MidiConnection};

/// The Conductor trait is the trait that the user has to implement to be able to use mseq. The
/// user has to implement [`Conductor::init`] and [`Conductor::update`], then pass the Conductor to the main entry point
/// [`crate::run`]. Refer to these [`examples`] for complete implementation examples.
/// The Conductor trait is the trait that the user has to implement to be able to use mseq. The user
/// has to implement [`Conductor::init`] and [`Conductor::update`], then pass the Conductor to the
/// main entry point [`crate::run`]. Refer to these [`examples`] for complete implementation
/// examples.
///
/// [`examples`]: https://github.com/MF-Room/mseq/tree/main/examples
pub trait Conductor {
/// This function will be called only once at the start when the Conductor is passed to [`crate::run`] (the main entry point).
/// This function will be called only once at the start when the Conductor is passed to
/// [`crate::run`] (the main entry point).
fn init(&mut self, context: &mut Context<impl MidiConnection>);
/// This function will be called at every midi clock cycle. All the notes sent to the [`Context::midi`]
/// will be played at the beginning of the next midi clock cycle.
/// This function will be called at every midi clock cycle. All the notes sent to the
/// [`Context::midi`] will be played at the beginning of the next midi clock cycle.
///
/// __Warning: if this function takes too long, the midi clock might be late. Be careful not to
/// do any intensive computation, ot block the thread.__
Expand Down
31 changes: 17 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
//! To start using `mseq`, create a struct that implements the [`Conductor`] trait.
//!
//! You can then add tracks to your sequencer by adding fields (to your struct that implements the
//! [`Conductor`] trait) of type [`DeteTrack`] or more generally fields that implement the trait [`Track`].
//! [`Conductor`] trait) of type [`DeteTrack`] or more generally fields that implement the trait
//! [`Track`].
//!
//! Once this is done, you can play your track in the [`Conductor::update`] function of your struct that
//! implements the [`Conductor`] trait. To do so, call the method [`MidiController::play_track`] (of
//! the [`Context::midi`]) with the track you want to play as a parameter.
//! Once this is done, you can play your track in the [`Conductor::update`] function of your struct
//! that implements the [`Conductor`] trait. To do so, call the method
//! [`MidiController::play_track`] (of the [`Context::midi`]) with the track you want to play as a
//! parameter.
//!
//! You can find some examples in the [`examples`] directory.
//!
Expand Down Expand Up @@ -54,11 +56,12 @@ pub enum MSeqError {
Track(#[from] track::TrackError),
}

/// An object of type [`Context`] is passed to the user [`Conductor`] at each clock tick through the method
/// [`Conductor::update`]. This structure provides the user with a friendly MIDI interface. The user
/// can set some MIDI System Parameters (e.g., [`Context::set_bpm`]) or send some MIDI System
/// Messages (e.g., [`Context::start`]) using directly the [`Context`] methods. The user can also send MIDI Channel
/// Messages (e.g., [`MidiController::play_note`] or [`MidiController::play_track`]) using the field [`Context::midi`].
/// An object of type [`Context`] is passed to the user [`Conductor`] at each clock tick through the
/// method [`Conductor::update`]. This structure provides the user with a friendly MIDI interface.
/// The user can set some MIDI System Parameters (e.g., [`Context::set_bpm`]) or send some MIDI
/// System Messages (e.g., [`Context::start`]) using directly the [`Context`] methods. The user can
/// also send MIDI Channel Messages (e.g., [`MidiController::play_note`] or
/// [`MidiController::play_track`]) using the field [`Context::midi`].
pub struct Context<T: MidiConnection> {
/// Field used to send MIDI Channel Messages.
pub midi: MidiController<T>,
Expand Down Expand Up @@ -130,9 +133,9 @@ impl<T: MidiConnection> Context<T> {
}
}

/// `mseq` entry point. Run the sequencer by providing a conductor implementation. `port` is the MIDI
/// port id used to send the midi messages. If set to `None`, information about the MIDI ports will
/// be displayed and the output port will be asked to the user with a prompt.
/// `mseq` entry point. Run the sequencer by providing a conductor implementation. `port` is the
/// MIDI port id used to send the midi messages. If set to `None`, information about the MIDI ports
/// will be displayed and the output port will be asked to the user with a prompt.
pub fn run(mut conductor: impl Conductor, port: Option<u32>) -> Result<(), MSeqError> {
let conn = MidirConnection::new(port)?;
let midi = MidiController::new(conn);
Expand All @@ -153,8 +156,8 @@ pub fn run(mut conductor: impl Conductor, port: Option<u32>) -> Result<(), MSeqE
}

/// Perform a linear conversion from `[0.0, 1.0]` to [0, 127]. If `v` is smaller than `0.0` return
/// 0. If `v` is greater than `1.0` return 127. The main purpose of this function is to be used
/// with MIDI control changes (CC).
/// 0. If `v` is greater than `1.0` return 127. The main purpose of this function is to be used with
/// MIDI control changes (CC).
pub fn param_value(v: f32) -> u8 {
if v < -1.0 {
return 0;
Expand Down
21 changes: 12 additions & 9 deletions src/midi_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ impl Hash for NotePlay {
pub struct MidiController<T: MidiConnection> {
step: u32,

// Every note currently being played triggered by play_note. The key is the step at which to stop the note.
// Every note currently being played triggered by play_note. The key is the step at which to
// stop the note.
play_note_set: HashMap<u32, Vec<NotePlay>>,

// Every note currently being played triggered by start_note.
Expand All @@ -88,14 +89,14 @@ impl<T: MidiConnection> MidiController<T> {
}
}

/// Request the [`MidiController`] to play `track`. This method has to be called at every MIDI step
/// the user wants the track to be played.
/// Request the [`MidiController`] to play `track`. This method has to be called at every MIDI
/// step the user wants the track to be played.
pub fn play_track(&mut self, track: &mut impl Track) {
track.play_step(self.step, self);
}

/// Request the MIDI controller to play a note at the current MIDI step. Specify the length (`len`) of the
/// note and the MIDI channel id (`channel_id`) on which to send the note.
/// Request the MIDI controller to play a note at the current MIDI step. Specify the length
/// (`len`) of the note and the MIDI channel id (`channel_id`) on which to send the note.
pub fn play_note(&mut self, midi_note: MidiNote, len: u32, channel_id: u8) {
if len == 0 {
return;
Expand All @@ -109,8 +110,9 @@ impl<T: MidiConnection> MidiController<T> {
self.stop_note_at_step(note_play, self.step + len);
}

/// Request the MIDI controller to start playing a note. Specify the MIDI channel id (`channel_id`). The note will
/// not stop until [`MidiController::stop_note`] is called with the same note, ocatve and MIDI channel id.
/// Request the MIDI controller to start playing a note. Specify the MIDI channel id
/// (`channel_id`). The note will not stop until [`MidiController::stop_note`] is called with
/// the same note, ocatve and MIDI channel id.
pub fn start_note(&mut self, midi_note: MidiNote, channel_id: u8) {
let note_play = NotePlay {
midi_note,
Expand All @@ -120,8 +122,9 @@ impl<T: MidiConnection> MidiController<T> {
self.start_note_set.insert(note_play);
}

/// Request the MIDI controller to stop playing a note that was started by [`MidiController::start_note`]. The note
/// will stop only if the note, ocatave and MIDI channel are identical to what was used in [`MidiController::start_note`].
/// Request the MIDI controller to stop playing a note that was started by
/// [`MidiController::start_note`]. The note will stop only if the note, ocatave and MIDI
/// channel are identical to what was used in [`MidiController::start_note`].
pub fn stop_note(&mut self, midi_note: MidiNote, channel_id: u8) {
let note_play = NotePlay {
midi_note,
Expand Down

0 comments on commit 0cb9e6d

Please sign in to comment.