CS 111 - PROGRAM DESIGN I

Lab 12

This lab will have you combine two sound files to add a "background" soundtrack to a foreground sound. The following files of the Gettysburg Address and the Preamble of the U.S. Constitution are great foreground sound files.

The background file should be repeated it if is not as long as the foreground file. To do this, if the current index from the foreground sound is a value bigger than the length of the background sound, you need to subtract the length of the background sound from the current index until the result produces a valid array index for background sound. The use of the modulus operator % may help perform this calculation - see notes at bottom of lab write-up.

We will also want to make the background sound quieter than it originally is, so we wish to make its volume a third of its original value. Here are some good files for the background sound:

Combining Two Sounds Together

To combine two sound files, you simply just add the sample values together. Assuming s1 and s2 are both Sound objects, the following will combine the two sounds in s1 and s2 together and have the result placed back into s1.

First set up a list of samples for each sound:

sampleList1 = getSamples( s1 )
sampleList2 = getSamples( s2 )

As you loop through the locations in the list using the variable i, the following code will do the actual combining of the amplitudes at each location:

amp1 = getSampleValue ( sampleList1 [i] )
amp2 = getSampleValue ( sampleList2 [i] )
amp3 = amp1 + amp2
setSampleValue ( sampleList1 [i], amp3 )

The only problem occurs if the resulting value goes above 32,767 or below -32,768. A simple solution is to use an if statement to check for this. Two simple if statements can check for this and correct the problem if it occurs. To correct this, just set the value to either 32,767 if the value was greater than 32,767 or set the value to -32768. if the value was less than -32,768.

Another issue is the two sounds are not the same length. If s1 is shorter, no real problem occurs (we just don't get the end of s2). However, if s2 is shorter, the above code has problems (which you are to fix for this lab).

To determine the length of a sound (which is the same as the number of samples a sound contains) you can use the getLength( ) function from the JES Library. (Note that the getNumSamples( ) function gives you the same thing.) To set up a loop to allow a variable, i, to loop through all of the locations in the list of Sound Samples.

    sampleList1 = getSamples ( s1 )
len = getLength ( s1 )
for i in range ( 0, len, 1 ):
# access the sample value from each sample in s1
sample = sampleList[i]
amp1 = getSampleValues ( sample )

Lab Assignment 11

Due: Wednesday 4/18/2018 by 11:59 pm

Create a Python program that will:

  1. Be written using good programming style which includes:
    • Good variable names
    • In-line commenting
    • Proper indentation of program statements
    • Use of blank lines to separate blocks of code.
    • Header block commenting for the program and each method written
Your header block comment for the program must include the following:
Your Name,
Net-ID,
Course Name,
Assignment Name and
Day and time of your CS 101 lab section (i.e. Monday at 2:00pm)
A short description of the assignment.

Header block comments for each method must include the following:
A description of the purpose of the method
A listing of the name, type and purpose of every parameter
A description of the return value and its type

  • Your program must contain the main() method that will
    • Prompt the user for the "Foreground" sound file and make a sound object from this file.
    • Prompt the user for the "Background" sound file and make a sound object from this file.
    • Call a method combineSounds()
    • play (or explore) the resulting sound and
    • Prompt the user to save the resulting sound in a file

  • Contain the method combineSounds() that will
    • Take two sound objects as parameters: the foreground sound and the background sound.
    • Add the background sound to the foreground sound, but the volume of the background sound should be one-third of its original volume. To do this, first divide the background sound sample values by 3 before adding the two values together.
    • check for and correct any "clipping" that may result from the resulting value being greater than 32,767 or less than -32,768.
    • Note: if the background sound file is shorter than the foreground sound file, repeat the background sound as often as needed to give a background sound to the entire foreground sound. Use the 3 second version of the Star Wars Theme in StarWars3.wav or the 3 second version of CantinaBand3.wav to test this out. This is the hard part of this assignment. First use a background sound file that is longer than the foreground sound to verify that the combining works, then worry about the getting the backbround sound to repeat if the background sound is shorter than the foreground sound.
You are also to submit the Java file electronically via the assignment link for Lab 11 in BLackboard.

Here are some example sound files you can use with this assignment.

More on Getting a Sound File to Repeat

This part of the write-up addresses the issue when the background sound is shorter than the foreground sound. When this happens, we need to make the background sound repeats (perhaps multiple times) while the foreground sound is being processed.

Assume the length of the foreground sound is 100 samples (which has valid positions 0 - 99) and the length of the backgound sound is 14 samples (which has valid positions 0 - 13). (In reality, the foreground sound might have closer to 1000000 samples and the background sound might have about 140000 samples, but using 100 and 14 makes the discussion simpler.)

For samples at positions 0-13 of the foreground sound, we add the samples from same positions (0-13) from the background sound. This is simple.

However, once we get the samples in position 14 and above in the foreground sound, there is not a corresponding position in the background sound. So at position 14 in the foreground, we must access the position at the beginning of the background sound (position 0). At position 15 in the foreground, we must access the second position of the background sound (position 1). At position 16 in the foreground, we must access the third position of the background sound (position 2). Etc.

Once we get to position 28 in the foreground sound, we will again need to access the position at the beginning of the background sound (position 0). Etc.

  • Position 14 in foreground added with position 0 in the background
  • Position 15 in foreground added with position 1 in the background
  • Position 16 in foreground added with position 2 in the background
  • Position 17 in foreground added with position 3 in the background
  • ...
  • Position 26 in foreground added with position 12 in the background
  • Position 27 in foreground added with position 13 in the background
  • Position 28 in foreground added with position 0 in the background (start over again)
  • Position 29 in foreground added with position 1 in the background
  • Position 30 in foreground added with position 2 in the background
  • ...
  • Position 40 in foreground added with position 12 in the background
  • Position 41 in foreground added with position 0 in the background (start over again)
  • Position 42 in foreground added with position 1 in the background
  • ...
Note that we start accessing from the beginning of the background sound when we are at position 0, 14, 28, 42, 56, 70, ... in the foreground sound. These values are multiples of the length of the background sound:
  • Background sound length * 0 = 14 * 0 = 0
  • Background sound length * 1 = 14 * 1 = 14
  • Background sound length * 2 = 14 * 2 = 28
  • Background sound length * 3 = 14 * 3 = 42
  • ...
When trying to determine if one number is a multiple of another number, the modulus operator % is useful. IF the result of the % operation is zero, then the number on the left hand side of the operator is a multiple of the number on the right hand side:
if ( a % b == 0 ):

// then a is a multiple of b

We can use this information and the modulus operator to help make the code so a short background sound will repeat.

Topic revision: r1 - 2018-04-12 - 21:34:06 - Main.troy
 
Copyright 2016 The Board of Trustees
of the University of Illinois.webmaster@cs.uic.edu
WISEST
Helping Women Faculty Advance
Funded by NSF