CS116      Lab 6 - Sounds

Objectives:

  1. Before starting this lab you should have read chapters 8, 9 and 10 in your text.
     
  2. Open Eclipse and import the cs116 project. 
     
  3. Take a look at the Sound class.  We can open a sound file with the FileChooser and then use the play method to play a sound.  (It would be appreciated if you bring headphones to class so that all of you can experiment with sounds easily).
     
  4. A Sound object is made up of an array of SoundSamples which are taken at discrete units of time.  We can manipulate the sound by manipulating the values of the samples.

    The volume of a sound can be modified by changing the amplitude of the sound wave - i.e. multiplying the value of the samples by a factor.

    /**
    * Method to change the volume (amplitude) of the sound
    * @param factor the factor to muliply by
    */
    public void changeVolume(double factor)
    {
        SoundSample[] sampleArray = this.getSamples();
        SoundSample sample = null;
        int value = 0;
        // loop through all the samples in the array
        for (int i=0; i<sampleArray.length; i++){
            sample = sampleArray[i];
            value = sample.getValue();
            sample.setValue((int)(value * factor));
        }
    }


    Add this method to the Sound class and try it out.
     
  5. Normalizing a sound is making it as loud as possible.  The maximum value allowed is 32767 so we can only multiply the amplitude so that it does not increase beyond the value. 
    Consider the following code:

    /**
    * Method to normalize (make as loud as possible) a sound
    */
    public void normalize()
    {
        int largest = 0;
        int maxIndex = 0;
        SoundSample[] sampleArray = this.getSamples();
        SoundSample sample = null;
        int value = 0;
        // loop comparing the absolute value of the current value
        // to the current largest
        for (int i=0; i<sampleArray.length; i++){
            sample = sampleArray[i];
            value = Math.abs(sample.getValue());
            if (value > largest){
                largest = value;
                maxIndex = i;
            }
        }
        // now calculate the multiplier
        double multiplier = 32767.0 / largest;
        // print out the largest value and the multiplier
        System.out.println("The largest value was "+largest +
            " at index "+ maxIndex);
        System.out.println("The multiplier is "+ multiplier);

        // loop through all the samples and multiply by multiplier
        for (int i=0; i<sampleArray.length; i++){
            sample = sampleArray[i];
            sample.setValue((int) (sample.getValue() * multiplier));
        }
    }

    This code searches through the array of samples to find the largest value.  This value is used for the multiplier.
    Try it out.

     


  6.  

    Assignment:
    Write a method
      public Sound setVolume(double fraction)
    which returns a new sound that is the same as the calling sound except that the volume is a fraction of the maximum possible volume.  For example if the fraction is .25 the volume will be set to one quarter of the maximum.  Make sure that the value of fraction is between 0 and 1 inclusive.


     


  7.  

    Assignment:
    Write a method
      public Sound taperEnd(int num)
    which returns a new sound that is the same as the calling sound except that the last num samples taper off to zero volume at a constant rate.


     

  8. We can combine two sounds together simply by adding their values.

    Assignment:
    Write a method
      public Sound add(int start, Sound overlaySound)
    which creates a new sound of the appropriate length.  It contains all parts of both sounds.  The calling sound is copied to the new sound and then starting at the sample indicated by start, the overlaySound will also be played (both at the same time).  If the overlay sound extends beyond the length of the calling sound, then be sure your combined sound is long enough.


     

  9. Try out the code for changing the frequency of a sound.

    /**
    * Method to change the frequency of a sound
    * @param factor the factor by which the frequency is change
    * A value > 1 makes the sound higher, <1 lower.
    * @return the new sound with changed frequency
    */
    public Sound changeFreq(double factor){
        Sound result = new Sound((int)(this.getLength() / factor));
        // loop through the sound and increment target index
        // by 1 but source index by factor
        for (double sourceIndex=0,targetIndex=0;
            targetIndex<result.getLength();
            sourceIndex=sourceIndex+factor, targetIndex++){
            if (sourceIndex >= this.getLength())
                sourceIndex = 0;
            result.setSampleValueAt((int)targetIndex,
            this.getSampleValueAt((int)sourceIndex));
        }
        return result;
    }
     

  10.  

    Assignment:
    Write a method
      public Sound stutter(int start, int end, int numRepeats)
    which creates a new sound that is the same as the calling sound except that the portion of the calling sound between start and end (inclusive) is now repeated numRepeats times.


     


  11.  

    Assignment:
    Write a program Audio which creates an audio collage.  Your collage should contain multiple sounds that are transformed in several different ways.  You may use the methods we wrote here, those which are contained in the text, or any others that you devise.  The result of the program should be a single audio file containing your collage.


     

  12. Email your modified Sound.java, Audio.java, and your resulting audio collage file to me at jill.zimmerman@goucher.edu