Skip to content
This repository has been archived by the owner on Jul 27, 2021. It is now read-only.

Add a simple A440 synth example #46

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

ulfmagnetics
Copy link

Just taking a crack at solving #18. I'm a Rust newbie, but this was pretty straightforward.

I couldn't figure out a way to specify an oscillator frequency without using the synth::dynamic module... if there's a simpler way I'd love to know about it!

use synth::dynamic::{Oscillator, Waveform, Amplitude, Frequency, FreqWarp};

// Create our oscillator at A440
let oscillator = Oscillator::new(Waveform::Sine,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative to using the synth::dynamic::Oscillator would be to make a synth::Oscillator with constant amplitude and frequency types, i.e.

let waveform = synth::oscillator::waveform::Sine;
let amp = 1.0;
let hz = 440.0;
let freq_warp = ();
let oscillator = synth::Oscillator::new(waveform, amp, hz, freq_warp);

Using synth::dynamic::Oscillator always produces an Oscillator<waveform::Dynamic, amplitude::Dynamic, frequency::Dynamic, freq_warp::Dynamic> - meaning that the type of waveform, amplitude, frequency or freq_warp providers is change-able at run-time in exchange for the slight run-time cost of checking which of each is used.

In the example I've given above however, the type is Oscillator<waveform::Sine, amplitude::Constant, frequency::Hz, ()>, meaning that we know at compile-time the Oscillator will always produce sine waves at some constant amplitude and hz, with no freq_warp. This should allow for slightly greater performance at the cost of less run-time flexibility.

Note that when producing a dynamic Synth (i.e. synth::dynamic::new(), as you've done below), it will always expect a dynamic Oscillator type as well. Using the regular Synth::new() constructor should allow you to pass the Oscillator type in the example I gave above.

By the way, I noticed that you're setting the Oscillator's constant frequency to 440.0hz, while setting the base_pitch to C1 and giving the note_on as C1. This is probably fine for this example, however I think a user might expect the synth to play back at the frequency of the note that was given. Perhaps it might be more intuitive to have the oscillator frequency match the base_pitch frequency, so that the frequency given at note_on always matches the frequency that plays back? I.e. if base_pitch and oscillator frequency were both C1 and note_on was given an A4, the synth should produce a 440hz sine wave.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, now I see, I missed the impl Amplitude for f32 and impl Frequency for f64 blocks before. I hadn't considered that numeric types could implement traits -- very useful in this case!

@mitchmindtree
Copy link
Member

Thanks! 😸

I left a comment inline re- avoiding the synth::dynamic module, hopefully it makes sense and is useful!

BTW, I'll have a PR within the next few days that removes the dynamic module all together in favour of Synth::dynamic and Oscillator::dynamic methods and making better use of rust's impl blocks in general, along with some other slight improvements. I'm happy to merge this though (with those alterations I mentioned in the comment) and then make any necessary adjustments in my PR 👍

@ulfmagnetics
Copy link
Author

Thanks for the very clear explanation! Hopefully this'll get the job done now..

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants