CS 107: Pictures and Sounds: Programming with Multimedia

Kalamazoo College

Winter 2009

Mini-Lab: Appending, Mirroring, Adding, Blending Sounds

 


Introduction

In this mini-lab you will gain practice with the techniques of mirroring and adding sounds and working with python lists.



Appending Sounds

  1. It is often useful to take two sounds and combine them into a single longer sound. This can be done easily by making use of the copySoundInto function. Fill in the following code skeleton to create function that combines two sounds end to end.
    def appendSound(sound1, sound2):
      # Make an empty sound long enough to contain both source sounds.
    
    
      # Copy sound1 into the beginning of the new sound using copySoundInto. 
    
    
      # Copy sound2 into the end of the new sound using copySoundInto.
    
    
      # Return the new sound. 
    

Mirroring Sounds

  1. Recipe #61 in the text is a function that mirrors the first half of a sound over the second half of a sound. We will write a function that will create a new sound that is twice the length of the original sound. The new sound will have the original sound in the first half, and the reverse of the original sound in the second half. This can be accomplished by creating a reversed copy of our original sound, and appending it to the original sound using the appendSound function. You may use the backwards function given below instead of writing your own. Fill in the missing sections of code below. You may use the backwards function given below instead of writing your own.
    # Mirror entire sound (new sound is original sound
    # followed by backwards original sound)
    def mirrorEntireSound(sound):
      # Reverse the original sound
    
      # Append sound and reverseSound
    
      # Return the mirrored sound
    
    
    
  2. You should copy the following version of backwards, which has been modified to take a sound as a parameter instead of a filename, into JES to use.
    
      def backwards(source):
        numSamples = getNumSamples(source) 
        target = makeEmptySound(numSamples, int(getSamplingRate(source)))
        # Go backwards through source and write into target
        sourceIndex = getLength(source)
        for targetIndex in range1(1,getLength(source)):
          sourceValue = getSampleValueAt(source, sourceIndex)
          setSampleValueAt(target, targetIndex, sourceValue)
          sourceIndex = sourceIndex - 1
        return target
    
    

Adding Sounds Together

Adding sounds together is very simple using a computer - just add the sample values at the same index numbers in each wave!
  1. Write a function that adds two sounds together. It has been started for you below:
    # Add sound1 to sound2
    # return the resulting sound
    def addSounds(sound1, sound2):
      if getSamplingRate(sound1) != getSamplingRate(sound2):
        print "Error! Sounds must have the same sampling rate."
        return
    
      # Determine which sound has minimum length
    
      # Create a new sound of that length
    
      for index in range(  ,         ):
        # Get the appropriate sample values from each sound
    
    
    
    
        # Add the sample values together
    
    
    
        # Set the sample value at this index in newSound to be the new value
    
    
    

Adding Without Clipping

The addSounds function you wrote above will probably work fine most of the time, but if two loud sounds are added together, the resulting sound could suffer from clipping. One way around this is to store the summed sample values into a python list of numbers rather than directly into the sound. (A python list can store much larger numbers than can be stored in sound samples.) We can then check the summed values to see if any are above the maximum allowed for sounds: 32767. If there are, the list of numbers can be normalized, and the resulting list can be converted back into a sound. In this case, we are using normalization not to create the loudest sound possible, but to ensure that the sound is no louder than it should be.
  1. Complete the addSoundsNoClipping function below. I've provided two helper functions: listToSound which creates a sound object from a list of numbers, and normalizeList which rescales a list of numbers so that it has the desired maximum value.
    #-----------------------------
    #Takes a python list of numbers, and a sampling rate
    #and returns a sound object. 
    #-----------------------------
    def listToSound(list, samplingRate):
      newSound = makeEmptySound(len(list), int(samplingRate))
      for pos in range1(getNumSamples(newSound)):
        setSampleValueAt(newSound, pos, list[pos-1])
      return newSound
    
    #-----------------------------
    #Normalizes a list of numbers so that the maximum value
    #in the list will be newMax. 
    #THIS FUNCTION DOES NOT RETURN ANYTHING. IT CHANGES THE 
    #LIST THAT IS PASSED IN AS A PARAMETER. 
    #-----------------------------
    def normalizeList(list, newMax):
      oldMax = max(list)
      for pos in range(len(list)):
        list[pos] = list[pos] * newMax/oldMax
    
    
    #-----------------------------
    #Add two sounds together, rescaling the resulting sound if necessary 
    #to avoid clipping. 
    #-----------------------------
    def addSoundsNoClipping(sound1, sound2):
      if getSamplingRate(sound1) != getSamplingRate(sound2):
        print "Error! Sounds must have the same sampling rate."
        return
    
      minLength = min(getNumSamples(sound1), getNumSamples(sound2))
      newSoundList = [0.0] * minLength 
    
      #Now add the two sounds together, placing the result in newSoundList
      for pos in range1(1,minLength):
         #ADD CODE HERE TO SUM UP THE SOUNDS
    
      maxVal = max(newSoundList) #calculate the maximum sample value
    
      #ADD CODE TO COMPLETE THE FOLLOWING THREE STEPS...
      #If maxVal> 32767, there has been clipping, normalize the sound.
      #Use listToSound to create the final sound from newSoundList.
      #Return the resulting sound.
    
    
    
  2. Try adding together two loud sounds using both addSounds and addSoundsNoClipping, can you hear a difference in the result?

Print your results

  1. Print the functions in this file and hand them in.