Due 23:59 pm Sep 23, Peer grading due 23:59 pm Sep 30
Download
Envelopes
Envelopes are very important in sound synthesis. Envelopes are the primary way to “shape” sounds from various sound sources so that the sounds do not suddenly pop on and off or blast at a constant level.
You should have learned to use both “pwl” and “env” for envelopes in the on-line lessons. Hint: Look up “pwl” and “env” in the Nyquist Reference Manual and pay attention to their behaviors under different stretch environments.
Composition Programming
The following code creates a short score and plays it when you click the “F2” button in the Nyquist IDE (maybe your keyboard F2 key will work too):
variable *ascore* = {{0 1 {note pitch: c2 vel: 50}} {1 0.3 {note pitch: d2 vel: 70}} {1.2 0.3 {note pitch: f2 vel: 90}} {1.4 0.3 {note pitch: g2 vel: 110}} {1.6 0.3 {note pitch: a2 vel: 127}} {1.8 2 {note pitch: g2 vel: 100}} {3.5 2 {note pitch: d2 vel: 30}} {3.7 2 {note pitch: d4 vel: 70}} {3.9 2 {note pitch: d5 vel: 70}} {4.1 2 {note pitch: d6 vel: 50}} {4.9 0.5 {note pitch: g4 vel: 40}} {5.2 2.5 {note pitch: a4 vel: 30}}} function f2() play timed-seq(*ascore*) variable *bscore* ; to be initialized from *ascore* function f3() play timed-seq(*bscore*)
Create a file named instr.sal
, paste this code in, and try it.
Define an Instrument
Your first task is to define a new instrument, also in the file instr.sal
, that multiplies the output of a table-lookup oscillator by an envelope. The instrument should consist of
- a table created as shown in the lectures using the
build-harmonic
function and containing at least 8 harmonics, - an oscillator (use
osc
), and - an envelope.
The instrument should be encapsulated in a function named simple-note
that at least has the two keyword parameters seen in *ascore*
(pitch:
and vel:
). The vel:
parameter represents velocity, a loudness control based on MIDI key velocity which ranges from 1 to 127. Convert MIDI key velocity to amplitude using the vel-to-linear
function (see the Nyquist Reference Manual). Your simple-note
instrument function should satisfy these requirements:
- starting time is of course the default start time from the environment,
- duration is determined by the stretch factor in the environment, e.g.
simple-note(pitch: c2, vel: 100) ~ 2.6
should have a duration of 2.6s, - maximum amplitude is proportional to
vel-to-linear(vel)
, wherevel
is the value of thevel
keyword parameter, - pitch is controlled by the
pitch
keyword parameter, which gives pitch in “steps”, e.g. C4 produces middle-C. - Any “instrument” function should return a sound (and not play the sound).
Play *ascore*
with your instrument
To show off your instrument, transform *ascore*
using one of the score-*
functions to use your instrument rather than note. (It is your task to become familiar with the score-*
functions and find the one that replaces function names.) Assign the transformed score to *bscore*
at the top level of instr.sal
; for example, you might have something like the following in your code:
set *bscore* = function-to-transform-a-score(*ascore*, perhaps-other-parameters)
You may add one or more additional functions to instr.sal
as needed.
Now, F3 (as defined above) should play the altered score, and it should use your simple-note
instead of the built-in piano note function note
. The resulting sound should demonstrate your instrument playing different pitches, durations, and velocities.
Record Tapping
Record a short period of rhythmic tapping sound (<10 sec) and save as tapping.wav
. This can be your own tapping or some other source.
Tap Detection
Download the P2.zip
file, which contains code, a test sound, and some documentation.
You will now create a new file named tapcomp.sal
, which will use the tapping.wav
data to create a composition. In tapcomp.sal
, load the given code tap-detect.sal
to detect a list of tap times and tap amplitudes of tapping.wav
. You must use load tap-detect.sal
, e.g. do not specify any path such as load P2/tap-detect.sal
. Refer to the HTML documentation for tap-detect
and inspect the tap-detect
code to get an idea of how you can generate a score based on this code.
Convert Taps to Score
Add your own functions to tapcomp.sal
to map the list of tap times and amplitudes into a Nyquist score named *tapscore*
that plays your instrument from instr.sal
(so of course, you should have the statement load "instr.sal"
to define your instrument). When you are done, loading tapcomp.sal
should immediately run your code and produce *tapscore*
, which should be a direct 1-to-1 translation of the taps to a score.
NOTE 1: Do NOT use score-gen
. Instead, you must use loop and list primitives to construct a score. You may use the linear-to-vel
function to convert tap strength to a velocity parameter.
NOTE 2: Note duration is up to you. It fixed, random, or related to the tap inter-onset times.
Make Music
Create between 20 and 40 seconds of music using your code. You can create new scores based on your tapscore (but please do not modify *tapscore*
), mix multiple sounds or “tracks,” you can create sounds by other means (as long as at least one “track” is derived according to the recipe above), and you can manipulate your results in an audio editor (again, as long as the tap-driven instrument is clearly heard). Keep all the code for your piece in tapcomp.sal
, but do not compute your piece immediately when the code is loaded (at least not in the version you hand in). It may be convenient to use F4
and other buttons in the IDE to run different pieces of your code. E.g. you could add something like this to tapcomp.sal
:
function F4() play compute-my-tap-piece(*tapscore*)
Do NOT write any play
command or commands to compute your piece at the top-level. E.g. do NOT write something like
play compute-my-tap-piece(*tapscore*)
unless it is inside a function (like F4 above), and the function does not get called when the file is loaded.
Name your composition sound file p2comp.wav
(AIFF format is acceptable too.)
Describe Your Intentions
Create a simple ASCII text file p2comp_README.txt
or pdf file p2comp_README.pdf
with a sentence or two describing your goals or musical intentions in creating p2comp.wav
.
Submission
Submit files in a zip file to ATutor. The following files should be at the top level in your zip file (you may use .aiff sound files instead of .wav sound files):
instr.sal: A SAL program implementing your table-lookup instrument,
tapping.wav: The recorded taps used as input to tap-detect.sal
,
tapcomp.sal: A SAL program to convert tap times to a Nyquist score.
p2comp.wav: Your project 2 composition (at least 20 seconds).
p2comp_README.txt: Optional additional info on your composition.
Decibels
Since you are reading this, you should now be familiar with Decibels. You can (re)read “The Bell Scale”, “The Decibel Scale (dB),” and “Decibels for Comparing Amplitude Levels” in Loudness Concepts and Panning Laws, but to summarize some important points:
- Decibels are a unit-less measure of the ratio of power. Each Bel represents a factor of 10.
- Since power increases with the square of amplitude, a factor of 10 change in amplitude gives a factor of 100 in power, which is 2 Bels (log10(100) = 2), which is 20dB.
- A very useful number is: A factor of 2 in amplitude is very nearly 6dB.
Remember that 6 dB represents a factor of 2 in amplitude!
Grading Criteria
Here are some things you might want to check before your final submission. Some criteria will be checked automatically. Some will be the basis of peer grading:
- Your
simple-note
is as directed, accepts 2 keyword parameters, and has proper pitch, amplitude, time and duration control. - You define and convert
*ascore*
to*bscore*
that callssimple-note
wheninstr.sal
is loaded. tapping.wav
contains at least 10 taps.*tapscore*
, generated by loadingtapcomp.sal
, should be a valid Nyquist score. (You can usescore-print
to see it nicely formatted.)- Your submission should be complete and anonymous.
- The audio should have acceptable quality (no clipping or unintended distortion, no bad splices, adequate overall level, etc.)