15-110 SUMMER SESSION TWO - 2014

Lab 8 - Wednesday, July 23 - earbuds or headphones required

Goals

This lab is intended to develop your understanding of encodings and how to exploit them. Specifically, you will work with a sound encoding, but the ideas are more widely applicable. Warning: If you don't use the linux server for this lab you will have to be able listen to .wav files on your personal machine. (The Chrome browser will play them for you, for instance.)

When you are done, you should be able to do the following:

  1. Explain what you will hear when you play a sound file created by adding (arithmetically) two pre-existing sound files of the same length.
  2. Explain in terms of sampling and sampling rate, how splicing two lists of numbers together can create a longer sound out of two shorter ones.
  3. Choose a number to speed up or slow down a sound by a predictable amount and explain your reasoning in terms of samples and sampling rate.

Deliverables

  1. chord.py
  2. melody.py
  3. speed.py

Place these files in a lab8 folder. Before leaving lab, zip up the lab8 folder and hand the zip file in.

Python Audio Information

This lab uses module snd110 which is in snd110.py. Download this file into your working folder. (Right click if necessary and save.)

CA-Led Activities/Demonstration

Self-Directed Activities

  1. You have just seen how sine_tone(1000, 0.5, 0.3) creates a single tone. Write a program in chord.py to create a chord (multiple tones at once) as follows:

    1. Write a function named sound_add(aa, bb) that adds sounds aa and bb. We will assume aa and bb have the same length and that aa is not needed by the caller so it is OK to modify it.
    2. For each value of i from 0 to the length of aa - 1, add bb[i] to aa[i]. Now aa contains the sum of aa and bb.
    3. Return aa from the function.

    Test your function using the following:

    write_wave("chord.wav",
               sound_add(sine_tone(220, 1.5, 0.3),
                         sound_add(sine_tone(540, 1.5, 0.2),
                                   sine_tone(660, 1.5, 0.2))))
          
  2. Write a function named melody() in melody.py to generate a sequence of 20 random tones. Since tones are lists of samples, you can form the sequence of two tones by simply splicing the lists together using the "+" operator. In melody you should write a loop to splice together the results of 10 calls to sine_tone(freq, 0.5, 0.2), where freq is a random number between 500 and 2000. Hint: here is an example that generates one random number between 10 and 20:

    from random import randint
    print(randint(10, 20))
    
    Test your program by calling:
    write_wave("melody.wav", melody())     
          
  3. Write a function named speed(sound, factor) that changes the speed of a sound. Here's how it works: each number in the list is a sample, and the sound is played at the rate of 44100 samples per second. If we take a given sound and repeat some of the samples at regular intervals, we get a slowed-down version of the sound. And if we skip some of the samples at regular intervals, we get a speeded-up version. So you can implement speed(sound, factor) as follows:

    1. Initially, set result to an empty list and set loc to zero.
    2. While loc is less than the length of sound, use the integer part of loc to index sound and append the value to result. (Use the function int.)
    3. (Still within the while loop:) Increment loc by factor. If factor is greater than one, this will step through the sound more quickly. If factor is less than one, this will step through sound more slowly.
    4. When the loop exits, return the result.

    Test the function using the following. You can use this voice.wav file. (If your browser plays rather than downloading this link, try right clicking on the link and choose ``Save Link Target As...''.)

    write_wave("speed75.wav", speed(read_wave("voice.wav"), 0.75))
    write_wave("speed200.wav", speed(read_wave("voice.wav"), 2.0))
    

    What factor would you pass to speed if you wanted the sound to be slowed down by one half? Sped up 120%?