Crate polyphony

Source
Expand description

Library to facilitate generating different sounds at the same time (polyphony).

Polyphony consists of different steps:

  1. Classify how the event should be dispatched. How exactly it should be classified, is defined by the EventDispatchClass enum. The dispatching itself is done by a type that implements the EventDispatchClassifier trait.
  2. Next, using the classification, voices are assigned to the event. The assigned voice(s) are described by the VoiceAssignment enum. The VoiceAssigner trait defines this action.
  3. Then, the event can be dispatched by calling the dispatch method on the VoiceAssignment.

§Example of using polyphony

The following example illustrates a plugin (or application) that has multiple voices that correspond to different tones.

Remark the example assumes the polyphony crate is compiled with the midi feature.

use polyphony::{Voice, EventDispatchClassifier, VoiceAssigner};
use polyphony::midi::{ToneIdentifier, RawMidiEventToneIdentifierDispatchClassifier};
use polyphony::simple_event_dispatching::SimpleVoiceState;
use polyphony::simple_event_dispatching::SimpleEventDispatcher;

struct MyVoice {
     // ...
}

impl MyVoice {
   fn handle_raw_midi_event(&mut self, event: &[u8; 3]) {
        // Here you typically change the state of the voice.
        unimplemented!();
   }

   fn render_buffer(&mut self, audio_buffer: &mut[f32]) {
       unimplemented!();
   }
}

impl Voice<SimpleVoiceState<ToneIdentifier>> for MyVoice {
    fn state(&self) -> SimpleVoiceState<ToneIdentifier> {
        // Let the event dispatcher know what state this voice is in.
        unimplemented!();
    }
}

struct MyPlugin {
    voices: Vec<MyVoice>,
    // ...
}

impl MyPlugin
{
    fn handle_event(&mut self, raw_midi_event: &[u8;3]) {
        let mut classifier = RawMidiEventToneIdentifierDispatchClassifier;
        let classification = classifier.classify(raw_midi_event);
        let mut dispatcher = SimpleEventDispatcher;
        let assignment = dispatcher.assign(classification, &mut self.voices);
        assignment.dispatch(raw_midi_event, &mut self.voices, MyVoice::handle_raw_midi_event);
    }

    fn render_buffer(&mut self, buffer: &mut [f32]) {
        for voice in self.voices.iter_mut() {
            voice.render_buffer(buffer);
        }
    }
}

Modules§

midi
simple_event_dispatching
Some basic event dispatching.

Enums§

EventDispatchClass
Describe how an event should be dispatched.
VoiceAssignment
Describe to what particular voice an event should be assigned.

Traits§

EventDispatchClassifier
Determine to what voices the event should be dispatched.
Voice
A trait used by some dispatchers.
VoiceAssigner
Define to which particular voice(s) the event should be assigned, based on the EventDispatchClass.
VoiceAssignerHelper
Trait used to facilitate implementing a VoiceAssigner.