/** * Class that represents a sound. This class is used by the students * to extend the capabilities of SimpleSound. * * Copyright Georgia Institute of Technology 2004 * @author Barbara Ericson ericson@cc.gatech.edu */ public class Sound extends SimpleSound { /////////////// consructors //////////////////////////////////// /** * Constructor that takes a file name * @param fileName the name of the file to read the sound from */ public Sound(String fileName) { // let the parent class handle setting the file name super(fileName); } /** * Constructor that takes the number of seconds that this * sound will have * @param numSeconds the number of seconds desired */ public Sound (int numSeconds) { // let the parent class handle this super(numSeconds); } /** * Constructor that takes a sound to copy */ public Sound (Sound copySound) { // let the parent class handle this super(copySound); } ////////////////// methods //////////////////////////////////// /** * Method to return the string representation of this sound * @return a string with information about this sound */ public String toString() { String output = "Sound"; String fileName = getFileName(); // if there is a file name then add that to the output if (fileName != null) output = output + " file: " + fileName; // add the length in frames output = output + " number of samples: " + getLengthInFrames(); return output; } // ----- Methods for Session 17 ------------------------------ public Sound makeSound1( int seconds ) { int length = framesFor(seconds); Sound result = new Sound( length ); for (int i = 0; i < length; i++ ) result.setSampleValueAt( i, 10*i ); // try 10*i, too! return result; } public Sound makeSound2( int seconds ) { int length = framesFor(seconds); Sound result = new Sound( length ); for (int i = 0; i < length; i++ ) result.setSampleValueAt( i, i*i*i ); // turn down volume... return result; } public Sound deepenTheVoiceV1() { Sound source = new Sound( "/Users/wallingf/Desktop/the-voice-clipped-and-pitched.aiff" ); Sound target = new Sound( source.getLength() * 3/2 ); for ( int i = 0, j = 0; i < source.getLength(); i+=2, j+=3 ) { target.setSampleValueAt( j , source.getSampleValueAt(i ) ); target.setSampleValueAt( j+1, source.getSampleValueAt(i+1) ); target.setSampleValueAt( j+2, source.getSampleValueAt(i+1) ); } return target; } public Sound deepenTheVoice() { Sound source = new Sound( "/Users/wallingf/Desktop/the-voice-clipped-and-pitched.aiff" ); Sound target = new Sound( source.getLength() * 3/2 ); int firstSample, secondSample, average; for ( int i = 0, j = 0; i < source.getLength(); i+=2, j+=3 ) { firstSample = source.getSampleValueAt(i ); secondSample = source.getSampleValueAt(i+1); average = (firstSample + secondSample)/2; target.setSampleValueAt( j , firstSample ); target.setSampleValueAt( j+1, average ); target.setSampleValueAt( j+2, secondSample ); } return target; } public void invertAtMidpoint() { int max = maximumValue(); int min = minimumValue(); int range = max - min; int midpoint = max - range/2; int value, excess, newValue; for (int i = 0; i < this.getLength(); i++ ) { value = this.getSampleValueAt( i ); excess = value - midpoint; newValue = midpoint - excess; this.setSampleValueAt( i, newValue ); } } public void negate() { int value; for (int i = 0; i < this.getLength(); i++ ) { value = this.getSampleValueAt( i ); this.setSampleValueAt( i, 32767 - value ); } } public void forcePositive() { int value; for (int i = 0; i < this.getLength(); i++ ) { value = this.getSampleValueAt( i ); this.setSampleValueAt( i, Math.abs(value) ); } } public Sound reverse() // different than textbook -- create new sound { int length = this.getLength(); Sound result = new Sound( this.getFileName() ); int value, slot; for ( int i = 0; i < length; i++ ) { value = this.getSampleValueAt( i ); slot = length - 1 - i; result.setSampleValueAt( slot, value ); } return result; } // ----- Helper Methods for Session 17 ----------------------- private int framesFor( int seconds ) { return (int) (seconds * this.getSamplingRate()); } public int maximumValue() { int largestSoFar = this.getSampleValueAt(0); for (int i = 1; i < this.getLength(); i++ ) { int value = this.getSampleValueAt(i); if ( value > largestSoFar ) { largestSoFar = value; } } return largestSoFar; } public int minimumValue() { int smallestSoFar = this.getSampleValueAt(0); for (int i = 1; i < this.getLength(); i++ ) { int value = this.getSampleValueAt(i); if ( value < smallestSoFar ) { smallestSoFar = value; } } return smallestSoFar; } // ----- Methods for Session 16 ------------------------------ public void posterize() { int maximumValue = this.maximumAbsoluteValue(); int threshold = maximumValue / 3; int newValue; for ( int i = 0; i < this.getLength(); i++ ) { int value = this.getSampleValueAt( i ); if ( value > threshold ) newValue = maximumValue; else if ( value < -threshold ) newValue = -maximumValue; else newValue = 0; this.setSampleValueAt( i, newValue ); } } public Sound clip( int start, int end ) { int lengthInSamples = end - start - 1; Sound result = new Sound( lengthInSamples ); int value; for (int i = 0; i < lengthInSamples; i++ ) { value = this.getSampleValueAt( start + i ); result.setSampleValueAt( i, value ); } return result; } public void increaseAndDecrease() { int half = this.getLength() / 2; int value; for ( int i = 0; i < half; i++ ) { value = this.getSampleValueAt(i); this.setSampleValueAt( i, value*2 ); } for ( int i = half; i < this.getLength(); i++ ) { value = this.getSampleValueAt(i); this.setSampleValueAt( i, value/2 ); } } public void riseAndFall() { int half = this.getLength() / 2; int value; double factor; for ( int i = 0; i < half; i++ ) { value = this.getSampleValueAt(i); factor = ((double) i / half) * 3; this.setSampleValueAt( i, (int) (value*factor) ); } for ( int i = half; i < this.getLength(); i++ ) { value = this.getSampleValueAt(i); factor = 3.0 - ((double) (i - half) / half) * 3; this.setSampleValueAt( i, value/2 ); } } // ----- Methods from Session 15 ----------------------------- // This didn't change the sound we heard. Do you know why? public void invert() { for (int i = 0; i < this.getLength(); i++ ) { int value = this.getSampleValueAt( i ); this.setSampleValueAt( i, value * -1 ); } } public int maximumAbsoluteValue() { int largestSoFar = Math.abs( this.getSampleValueAt(0) ); for (int i = 1; i < this.getLength(); i++ ) { int value = Math.abs( this.getSampleValueAt(i) ); if ( value > largestSoFar ) { largestSoFar = value; } } return largestSoFar; } public void normalize() { int maximumValue = this.maximumAbsoluteValue(); double multiplier = 32767.0 / maximumValue; for ( SoundSample sample : this.getSamples() ) sample.setValue( (int) (sample.getValue() * multiplier) ); } // ----- Methods for Session 14 ------------------------------ public void displaySamples( int count ) { SoundSample[] samples = this.getSamples(); for (int i = 0; i < count; i++ ) System.out.println( samples[i] ); } public void amplify( double increase ) { for (int i = 0; i < this.getLength(); i++ ) { int value = this.getSampleValueAt( i ); this.setSampleValueAt( i, (int) (value * (1 + increase)) ); } } } // end of class Sound, put all new methods before this