👎Deprecated since 0.1.1: Deprecated in favour of the dedicated
polyphony
crate.Expand description
Utility to facilitate genarating different sounds at the same time (polyphony).
Polyphony consists of different steps:
- 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 theEventDispatchClassifier
trait. - Next, a voice should be assigned to the event.
The
VoiceAssigner
trait defines this action. - Then, the event can be dispatched.
The
EventDispatcher
trait and theContextualEventDispatcher
trait define methods for doing this.
Example of using polyphony
The following example illustrates a plugin (or application) that has multiple voices that correspond to different tones.
use rsynth::utilities::polyphony::{Voice, EventDispatchClassifier, ToneIdentifier,
RawMidiEventToneIdentifierDispatchClassifier, ContextualEventDispatcher};
use rsynth::utilities::polyphony::simple_event_dispatching::SimpleVoiceState;
use rsynth::utilities::polyphony::simple_event_dispatching::SimpleEventDispatcher;
use rsynth::event::{ContextualEventHandler, Indexed, Timed, RawMidiEvent};
use rsynth::ContextualAudioRenderer;
use rsynth::buffer::AudioBufferInOut;
struct MyVoice {
// ...
}
impl Voice<SimpleVoiceState<ToneIdentifier>> for MyVoice {
fn state(&self) -> SimpleVoiceState<ToneIdentifier> {
// Let the event dispatcher know what state this voice is in.
unimplemented!();
}
}
impl<Context> ContextualEventHandler<Timed<RawMidiEvent>, Context> for MyVoice {
fn handle_event(&mut self, event: Timed<RawMidiEvent>, context: &mut Context) {
// Here you typically change the state of the voice.
unimplemented!()
}
}
impl<Context> ContextualAudioRenderer<f32, Context> for MyVoice {
fn render_buffer(&mut self, buffer: &mut AudioBufferInOut<f32>, context: &mut Context) {
// Render one voice.
unimplemented!()
}
}
struct MyPlugin {
voices: Vec<MyVoice>,
// ...
}
impl<Context> ContextualEventHandler<Indexed<Timed<RawMidiEvent>>, Context> for MyPlugin
{
fn handle_event(&mut self, event: Indexed<Timed<RawMidiEvent>>, context: &mut Context) {
let mut dispatcher = SimpleEventDispatcher::new(RawMidiEventToneIdentifierDispatchClassifier);
// Here we simply pass the context that we're given, but you can also pass a custom
// context that uses shared data that is stored in `self`.
dispatcher.dispatch_contextual_event(event.event, &mut self.voices, context);
}
}
impl<Context> ContextualAudioRenderer<f32, Context> for MyPlugin
{
fn render_buffer(&mut self, buffer: &mut AudioBufferInOut<f32>, context: &mut Context) {
for voice in self.voices.iter_mut() {
// Here we simply pass the context that we're given, but you can also pass a custom
// context that uses shared data that is stored in `self`.
voice.render_buffer(buffer, context);
}
}
}
Modules
- simple_event_dispatchingDeprecatedSome basic event dispatching.
Structs
- ToneIdentifierDeprecatedUsed to dispatch polyphonic event to the correct voice, based on the tone of the event.
Enums
- EventDispatchClassDeprecated
- VoiceAssignmentDeprecated
Traits
- ContextualEventDispatcherDeprecated
- EventDispatchClassifierDeprecated
- EventDispatcherDeprecated
- VoiceDeprecatedImplement this trait to inform the polyphonic event dispatcher what state this voice is in.
- VoiceAssignerDeprecated