Delay and Reverb
Assign: Thursday, October 28
Due: Thursday, November 4
Assignment Policies
All assignments are partner assignments. Please make sure to review the policies and guidelines about discussing assignments with those other than your partner. Assignments are usually, but not always, a combination of paper and coded exercises. Please make two submissions (one for paper exercises and one for coded exercises) to Gradescope. Paper exercises are marked with HW to indicate a handwritten question and C to indicate a coded question. Paper submissions can receive an extra 2% bonus if they are typed. Please visit the tools section of the website for more information.
Starter Code
Download the starter code here.
Handwritten Exercises HW
-
Consider the following table of samples below where $n$ is the sample number:
$n$ 0 1 2 3 4 5 $x[n]$ 0.25 0.20 0.10 0.00 -0.40 -0.15 -
State the first six samples of a delay network with the differential equation $x[n] + x[n - 1]$.
-
State the first six samples of a delay network with the differential equation $x[n] + x[n - 1.5]$. Fractional delays should use linear interpolation to estimate.
-
-
Explain how to create a passband filter from just a low-pass filter and high-pass filter.
Exercises C
-
A popular audio effect is “flanging”. Flanging is a technique where an audio signal undergoes a fluctuating delay controlled by either a sine wave or triangle wave. The technique has been popularized in many rock songs including Bold As Love by Jimi Hendrix and And The Cradle Will Rock… by Van Halen. Flanging produces a sweeping of the harmonics by restricting the delay time to something quite small (usually under 20ms). The fluctuating delay time at such small delays produces a changing comb filter. For more information about flanging, click here.
The simplest flanger is built using a feedforward network as shown in the image below.
Notice that we are showing $M(n)$ where $M$ is the delay as a function of $n$. Remember that the delay should be modulated by either a sine wave of triangle wave and that $M$ is not constant. Therefore, using
DelayN
will not work in this context becauseDelayN
quantizes the delay length to the nearest sample. Modulating the delay length ofDelayN
will not be smooth due to the quantization. If you want to smoothly modulate the delay, you will need to useDelayL
which employs linear interpolation. Use the following SynthDef construction in your implementation:( SynthDef(\flanger, { arg in, out = 0, depth = 1, rate = 0.5, sweep = 0.0045, centerDelay = 0.005, amp = 1; // Your implementation }).add; )
depth
is the triangle in the diagram above and represents a multiplicative factor controlling the amount of delayed signal that should be added to the original signal.rate
refers to the frequency (in Hz) of the modulating wave. For example, a rate of 2 means that the modulating wave will cycle through its period twice in one second.sweep
andcenterDelay
work together to create the range of the delay fromcenterDelay - sweep
tocenterDelay + sweep
. We can assume that the maximum delay (i.e.,centerDelay + sweep
) does not exceed 1 second. Useamp
to control the amplitude of the summed signal.As a final note, design your flanger to take a mono input signal like white noise.
in
represents the bus number of the incoming signal. Your flanger should then output a stereo signal.Here is an audio example of a guitar loop without flanging:
Here is an audio example of the guitar loop with the flanger above with
depth = 0.5
andrate = 0.25
. -
In this exercise, we are going to build a channel vocoder. The original purpose of a vocoder (a portmanteau of voice and encoder) was to compress vocal audio data. The original vocoder was developed by Homer Dudley in 1928. It worked by taking an analysis of the vocal signal using bandpass filters. The filters would cover the audio spectrum and each filter would track the strength of the spectrum. The output of the vocoder was the amplitude of each band covered by each bandpass filter at regular time slices. Later, the vocoder was used as an audio effect to impart the spectrum of one sound called the modulator onto the spectrum of another called the carrier. The most common usage is to impart the spectrum of speech onto a rich audio signal like a sawtooth wave. This creates a robotic like effect and has been popularized in many songs such as Get Lucky by Daft Punk or Compton by Kendrick Lamar.
As an audio effect, the vocoder works by doing an analysis of the modulator’s frequency spectrum using bandpass filters where each filter covers a different portion of the spectrum. The spacing of the bandpass filters should be evenly spread on a logarithmic scale. The Q value which controls the width of the bandpass filter is set high so that the peak of each bandpass filter does not overlap. That way each portion of the frequency spectrum is captured in exactly one filter. The picture below shows a visual representation of the filters.
As the modulator signal plays, each bandpass filter outputs a portion of the frequency spectrum. The vocoder works by tracking the amplitude of the signal outputted by each bandpass filter. To track the amplitude of each analysis filter you can use the UGen Amplitude.ar with its default arguments.
The carrier signal uses a set of bandpass filters with the same parameters (i.e., center frequency and q) as those applied to the modulator signal. The amplitude of each bandpass filter for the carrier is controlled by tracked the amplitude of the corresponding filter of the modulator. In this way, the spectrum of the carrier is altered by a set of bandpass filters shaped from the spectrum of the modulator. The output signal of the vocoder is the summed result of all the bandpass filters applied to the carrier signal.
In this task, you will be write a SynthDef for the vocoder. The SynthDef will need to construct the necessary bandpass filters. A typical vocoder will have many bandpass filters. Therefore, it is prudent to use a loop to accomplish this task. Each pass through the loop should take the following steps:
- Calculate the center frequency of the next bandpass filter.
- Compute the amplitude of the bandpass filter applied to the modulator.
- Use the amplitude to scale the bandpass filter applied to the carrier signal.
- Add that portion of the carrier signal to the overall signal.
Below is the header for the SynthDef:
( SynthDef(\vocoder, { arg out = 0, modulatorInBus, carrierInBus, amp = 0.5, q = 50; // More starter code and your code }).add; )
A description of the arguments:
out
: the output bus of the SynthDef.modulatorInBus
: the bus of the modulator signal. This bus will be stereo.carrierInBus
: the bus of the carrier signal. This bus will be stereo.amp
: the amplitude of the output signal.q
: The q factor for the bandpass filters.
Some other helpful hints and requirements:
- Our vocoder will use speech as the modulator signal. Create a set of 41 bandpass filters that covers the range from 300Hz to 8000Hz where most vocal speech lies. Each bandpass filter should be centered on this range, inclusive (i.e., the first bandpass filter should be on 300 and the 41st should be at 8000Hz). Remember that the filters should evenly cover this range on a logarithmic/exponential scale.
- Be careful. The
BPF.ar
UGen takes the reciprocal of Q as a parameter. - The bandpass filters applied to the carrier signal significantly
reduce the amplitude of the output signal even when the amplitude
is modulated by the modulator. In my implementation, I boosted
the output of each bandpass filter by a factor of nearly 20 and
boosted the output amplitude of the final signal by a similar
amount. This way the parameter
amp
can control the output signal on a more reasonable scale. - The output should be a stereo signal. Note that both the carrier and modulator signals are expected to be stereo as well.
As a sanity check, here is a recording of the modulator, carrier and vocoder output from my vocoder implementation.
Carrier:
Modulator:
Vocoder Output:
Submission
Feedback
When you are finished with the problem set, please fill out the form linked here to provide feedback on how long the problem set took you and how difficult you found it. Note that you must fill out this form to receive credit for the problem set.
Submission Guidelines
All assignments in this course are submitted through Gradescope. There are two kinds of assignments in this course: paper assignments and code assignments. Both are submitted to Gradescope. Most assignments are a mix of code and paper assignments. Each question or question part will be marked either “code” or “paper” to indicate which kind of question it is. For paper assignments, note that typed answers will receive a small additional bonus of 2%.