For this mini-project, you will continue extending the basic synthesizer you developed last week into a more full-featured synthesizer. In particular, you’ll implement two features:
With these features, we are getting closer to emulating how real synthesizers work, such as the legendary Minimoog Model-D. Note in the picture of the Model-D the collections of dials for the “Oscillator Bank” and “Modifiers.” These control the voices produced by the Moog as well as the ASDR envelope the Moog uses to shape its sound!
As a starting point, you should use the synthesize-square-wave-note function from your ASDR lab and their associated helper functions.
And their associated helper functions.
Note that you will be expected to use these functions as a basis for your mini-project.
Feel free to edit and modify them as you see fit to achieve the functionality described below.
Because you are using code that you used from your previous work, you should cite yourself and your partner to be clear where your code came from. In a comment at the top of your file give a brief acknowledgement describing what code you have adapted from the lab and who worked on it. The format of these acknowledgments is less important than ensuring that you write some acknowledgment in your file!
Write your program in a file called synthesizer.scm and submit it to Gradescope when you are done.
We saw that the various fundamental waveforms produce different timbre of sound.
One way to create even more varied timbres is to mix together different waveforms at different frequencies together into a single clip.
In the lab, your synthesize-square-wave-note function generated a note from a square wave.
For this part, generalize synthesize-square-wave-note to generate-note.
generate-note has the same parameters as synthesize-square-wave-note, but instead of generating a note from a square wave, it generates a note by combining a square wave and a sine wave.
To generate the sine wave portion of the clip, you should leverage your lab code for making a sine wave appropriately.
To perform this superposition of waves, each sample generate-note creates is the result pointwise averaging the samples from a square wave and sine wave.
That is, the first samples from the square and sine wave are averaged together, then the second samples of each clip are averaged together, and so forth.
The resulting values, by the nature of averaging, will be valid amplitude values in the range (-1.0, 1.0).
In lab, our volume envelope was a simple envelope that had an instantaneous attack and no sustain or decay. Let’s enhance our envelope to a true ADSR envelope that allows you to customize the attack, sustain, decay, and subsequent release. For reference, here is the shape of an ADSR envelope from Wikipedia:
The way that we’ll proceed is to specify the durations of the first three periods of the envelope, attack, sustain, and decay, with the fourth period, release, being implied by the first three periods.
Augment generate-note to also take a list of three floating point numbers in the range 0.0 to 1.0 that represent the relative percentages of time that the envelope, attack, and sustain should take; the release takes up the remaining time.
For example, if we pass the list (list 0.1 0.3 0.2), then the envelope should have:
0.1 of the samples of the envelope,0.3 of the samples,0.2 of the samples, and1.0 - 0.1 - 0.3 - 0.2 = 0.4 of the samples.To create this generalized envelope, break up the envelope into its pieces:
For reference, note that our original envelope from synthesize-square-wave-note can be obtained by passing (list 0.0 0.0 0.0) for the envelope list.
For this mini-project, we are being less specific about how you approach the tasks at hand because there are a variety of ways to approach these problems. We’re concerned less about how you approach a problem, but whether your implementation reads like the solution you intend to write down. When in doubt, follow our basic principles for style: