10 May 2024

Project 4

Granular Synthesis

Due Monday, March 13, 2023 by 11:59PM Eastern
(NOTE: This due date is the Monday after Spring Break. Although this gives 3 weeks for this project from its posting date, it is designed to be completed within 2 weeks like prior projects. If you work on this in the two weeks leading to Spring Break, you should be able to enjoy Spring Break without any homework from this class. So please start early!)

Peer Grading Due: Monday March 20, 2023 by 11:59PM Eastern

IMPORTANT HANDIN NOTE: We are asking students to include a .wav for each section of part1( ), part2( ), part3( ), and part4( ) in their submission. This is to make the peer grading process easier for everyone (and to avoid safety issues in running other students’ code directly). 

Granular synthesis is an extremely versatile technique to create sounds closely associated with the world of electronic and computer music.

In this project, you will experiment with some of the possibilities by creating 4 directed examples and a short but open-ended composition.

We will introduce two techniques: Grains from sound files, and synthesized grains.

Grains from Sound Files

  1. The file p4.zip contains everything you need to get started. You might begin by loading proj4base.sal file, which should process the included sample.wav. See the .sal code for documentation on how it works. As is, proj4base.sal uses file-grain to produce individual grains and make-granulate-score to make a Nyquist score consisting of many grains.
  2. Copy proj4base.sal to proj4.sal, which you will hand in.
  3. Find some sounds of your own choosing to granulate. Often, non-music sources are the most interesting. Sometimes, music works well if it is highly stretched (see below). Use a mono (1-channel) sound file as input. If you have a stereo file, convert it to mono before you continue.
  4. Try it out: Modify proj4.sal to granulate your sound. Note how the code references sample.wav as "./sample.wav". The "./" means “in the current directory”; otherwise, Nyquist will look in the default sound file directory, so be sure to use the "./" prefix to reference your sound file, and put your sound file in the same directory as proj4.sal.
  5. Edit your sound to have a length of at most 10s (that’s all you need, and it will conserve our server disk space).

Part 1 – Simple Granular Stretch

  1. In proj4.sal define the function part1() that will produce a granular synthesis sound (taking grains from your chosen sound file) with the following parameters:
    • Grain duration = 100ms
    • Grain IOI = 50ms
    • Total resulting sound duration = (approximately) 3s
    • Stretch factor = 3 (thus the grains are taken from a roughly 1s interval of the sound file, which is “stretched” by a factor of 3 to produce about 3s of sound).
    • Do not change the playback speed of grains and include all the grains in the sound (density is 1.0).
    • The use of randomization of the file time of each grain is optional. You can use the default randomness value of 1s (from proj4base.sal‘s make-granulate-score function, but you might also like to hear a less scrambled time-stretch effect by setting randomness to 0.
  2. When you are finished, play part1() should play about 3s of sound. Store this sound wave in part1.wav.

Part 2 – Pitch Shifted Grains by Changing Sample Rates

  1. Changing Pitch: Rather than playing the grains back at the original speed, grain pitch can be changed by resampling them so that they play faster or slower. Recall that sounds are immutable, so how do you play a sound faster or slower? Answer: the sound behavior makes a sound stretchable and shiftable. Grain is already in an environment with a stretch factor and the stretch factor has already been applied to compute grain, so if we just wrote sound(grain) or sound(grain) ~ 1.5, the current environment stretch factor would be applied again – not good. Instead, we use “absolute stretch” (~~) to replace the stretch factor in the environment with an absolute value while evaluating stretch(). The result is that the grain is resampled to make it longer or shorter, depending on the value of the stretch factor. Find the expression (sound(grain) ~~ (1.0 / speed) in the function file-grain to see how this works in the code.
  2. In proj4.sal modify make-granulate-score to accept a speed: keyword parameter (default value 1) that passes the speed value through the score to calls on file-grain so that you can control the pitch shifting of grains.
  3. In proj4.sal define the function part2() that will produce a granular synthesis sound (taking grains from your chosen sound file) with the following parameters:
    • Grains are transposed up by one octave (a factor of 2)
    • [The remaining parameters are the same as in Part 1.]
    • Grain duration = 100ms
    • Grain IOI = 50ms
    • Total resulting sound duration = (approximately) 3s
    • Stretch factor = 3 (thus the grains are taken from a roughly 1s interval of the sound file, which is “stretched” by a factor of 3 to produce about 3s of sound).
    • Include all the grains in the sound (density is 1.0).
    • The use of randomization of the file time of each grain is optional. You can use the default randomness value of 1s (from proj4base.sal‘s make-granulate-score function, but you might also like to hear a less scrambled time-stretch effect by setting randomness to 0.
  4. When you are finished, play part2() should play about 3s of sound. The sound should of course be an octave higher (but the same duration) as in Part 1. Store this sound wave in part2.wav.

Part 3 – Lower Density, Sparse Grains

  1. Rather than playing all the grains, creating a dense overlapped texture, you can randomly drop grains to produce a sparser texture. The make-granulate-score function includes a density parameter that gives the probability (from 0 to 1) of appending any given grain to the score as it is constructed.
  2. In proj4.sal define the function part3() that will produce a granular synthesis sound (taking grains from your chosen sound file) with the following parameters:
    • Density is 10% (0.1)
    • [Note that many of the remaining parameters are also different from Parts 1 and 2.]
    • Grain duration = 20ms
    • Grain IOI = 10ms
    • Total resulting sound duration = (approximately) 3s
    • Stretch factor = 0.3 (thus the grains are taken from a roughly 10s interval of the sound file, which is “stretched” by a factor of 0.3 to produce about 3s of sound). If the sound you chose to granulate is shorter than 10s, then adjust the parameters to granulate all of your sound and produce about 3s of output.
    • The use of randomization of the file time of each grain is optional.
      • When you are finished, play part3() should play about 3s of sound. The sound should be about the original pitch of your sound file, but the sound should be stuttering or pulsing irregularly with short grains of sound. Store this sound wave in part3.wav.

Part 4 – Synthesized Grains

  1. Rather than pulling grains from a sound file, you can synthesize grains. It is common to use simple techniques such as sine tones, table-lookup oscillators or FM, and granular synthesis gives many additional parameters including grain density, grain duration, pitch distributions, etc.
  2. In proj4.sal, modify make-granulate-score to accept another parameter to select synthesized grains. E.g. you can add a boolean parameter sinegrain (default #f) to enable calling sine-grain instead of file-grain. Alternatively, you could provide the name of the grain function to use in a parameter to make-granulate-score, e.g. grainfunc (default quote(file-grain)).
  3. In addition, the grains in the score generated by make-granulate-score should be different when synthesized grains are selected. The function sine-grain is already (partially) implemented, and has two keyword parameters: low and high. In make-granulate-score, you can put these parameters into the score, or you can just use the default values.
  4. You will need to complete the implementation of sine-grain to randomly choose the pitch to synthesize, based on the keyword parameters low and high.
  5. In proj4.sal define the function part4() that will produce a granular synthesis sound using synthesized grains with the following parameters (which are otherwise the same as Part 1):
    • Grain duration = 100ms
    • Grain IOI = 50ms
    • Total resulting sound duration = (approximately) 3s
  6. When you are finished, play part4() should play about 3s of sound. The sound should consist of clean, rapid, bubbly sinusoidal sounds with a diversity random pitches. Store this sound wave in part4.wav.
  7. Notice how different this sounds from Part 1, even thought the grain parameters are about the same and only the content of the short (100ms) grains is different.

At this point, since you have modified proj4.sal for each part of the project, you should go back and test part1(), part2(), part3() and part4() to make sure they all still work as expected. Merely loading proj4.sal should not play sounds automatically.

Composition With Granular Synthesis

Copy your proj4.sal file to proj4comp.sal so that you do not “break” anything in Parts 1-4.

Using all the tools that you have built, create a 20- to 40-second composition. In your piece, you should at least include:

  • Substantial use of granular synthesis, with
  • Dynamic amplitude, and
  • Dynamic pitch control

You may wish to alter your code further to incorporate amplitude and pitch control. Pattern generators (see Chapter 5) are an excellent way to get some control over variations in parameters. You should also experiment with other parameters. In fact, ALL parameters should be considered fair game for experimentation. Shorter and longer grains have a very different sound. Very high stretch factors, very small ioi, and other changes can be very interesting, so please spend some time to find amazing sounds.

You are also free to make many granular synthesis sounds and mix them in Nyquist or in an audio editor such as Audacity.

Create the plain text file proj4comp.txt to explain:

  1. how you vary the amplitude and pitch.
  2. Also include any additional effects that you added.
  3. Lastly include your motivation or inspiration behind your composition.

Grading Criteria

Grading will be based on meeting the technical specifications of the assignment:

  • the code should work, it should be readable, and it should have well-chosen parameters that indicate you understand what all the parameters mean.
    • be sure to define part1, part2, part3 and part4 functions in your proj4.sal.
    • loading your proj4.sal code should not immediately compute sounds.
  • submissions are anonymous.
  • It’s best to envision what you want to do, write it down in comments, then implement your design. You can use the sample code, but should show understanding of what you are doing — make this your own creation.
  • Your composition should be 20 to 40 seconds long.
  • the use of granular synthesis should be clearly audible and clearly related to the sound that you analyzed.
  • Your piece should show musical results, effective granular synthesis, mixing quality, and general effort. Bonus points may also be awarded for exceptional work.

Turning In Your Work

Please hand in a zip file containing the following anonymous files (in the top level, not inside an extra directory). Note that the following must be strictly adhered to for the convenience of machine and human graders (including you as a peer grader):

  • Code for parts 1-4, named proj4.sal
  • Code created for your composition, named proj4comp.sal, Note: Code should be clearly commented in case we want to run it.
  • 4 Sound Files (.wavs), one each for parts1-4 named part1.wav, part2.wav, part3.wav, and part4.wav
  • Your composition audio, named proj4comp.wav (or .aiff).
  • Input sound for parts 1-4, named whatever you want, but it should be the filename assumed in parts 1, 2 and 3 so that part1(), part2() and part3() will run.
  • A text file containing a statement about your composition (be sure to include the 3 points mentioned above), named proj4comp.txt
  • Please DO NOT include or submit sample.wav from p4.zip! It should not be needed to run your code, and we do not need another copy from every student, thank you.