manipulating-sounds.ppt: uploaded 1 April 2016 at 4:01 pm

Download Report

Transcript manipulating-sounds.ppt: uploaded 1 April 2016 at 4:01 pm

Manipulating Sound
CS1316: Representing
Structure and Behavior
Story

Programming Sampled Sounds in Java

Manipulating an array
• Manipulating sounds in-place
• Returning a new sound
• Inserting a sound
• Deleting a sound segment
Loading and playing sounds
Welcome to DrJava.
> Sound s = new
Sound(“C:/cs1316/MediaSources/thisisat
est.wav")
> s.increaseVolume(2.0);
> s.play();
increaseVolume method
/**
* Increase the volume of a sound
**/
public void increaseVolume(double factor){
SoundSample [] samples = this.getSamples();
SoundSample current = null;
for (int i=0; i < samples.length; i++) {
current = samples[i];
current.setValue((int) (factor * current.getValue()));
}
}
increaseVolume: How it works

SoundSample is the name of the class for
samples.
•

There’s something named Sample already in Java, so
it would get confusing.
getSamples(), getValue(), and setValue() work
just the same as in CS1315 Python.
•
They (respectively) return an array of all the samples,
get the value of a given sample object, and set the
value of a given sample object.
Methods that return sounds
> Sound s = new
Sound("D:/cs1316/MediaSources/
thisisatest.wav")
> s.play()
> s.reverse()
Sound number of samples: 64513
Why do
you think
we’re
seeing
this?
Reverse returns a Sound!
/**
* Method to reverse a sound.
**/
public Sound reverse()
{
Sound target = new Sound(getLength());
int sampleValue;
for (int srcIndex=0,trgIndex=getLength()-1;
srcIndex < getLength();
srcIndex++,trgIndex--)
{
sampleValue = this.getSampleValueAt(srcIndex);
target.setSampleValueAt(trgIndex,sampleValue);
};
return target;
}
Methods that cascade nicely in
Sound




public Sound reverse()
public Sound append(Sound
appendSound)
public Sound mix(Sound mixIn, double
ratio)
public Sound scale(double factor)
Little sounds in MediaSources
-h: Half second
-q: Quarter second
-1 or -2: 1 or 2 seconds
-tenth: 1/10 second
-twentieth: 1/20 second
public class MySoundCollage {
Making
collages
public static void main(String [] args){
Sound snap = new
Sound(FileChooser.getMediaPath("snap-tenth.wav"));
Sound drum = new
Sound(FileChooser.getMediaPath("drumroll-1.wav"));
Sound clink = new
Sound(FileChooser.getMediaPath("clink-tenth.wav"));
Sound clap = new
Sound(FileChooser.getMediaPath("clap-q.wav"));
Sound drumRev = drum.reverse().scale(0.5);
Sound soundA =
snap.append(clink).append(clink).append(clap).append(d
rumRev);
Sound soundB =
clink.append(clap).append(clap).append(drum).append(s
nap).append(snap);
Sound collage =
soundA.append(soundB).append(soundB).append(soun
dA).append(soundA).append(soundB);
collage.play();
}
}
How do we insert and delete
sound?
Welcome to DrJava.
> Sound test = new
Sound("D:/cs1316/MediaSources/thisisatest.wav");
> test.getLength()
64513
> Sound clink = new Sound("D:/cs1316/MediaSources/clinktenth.wav");
> clink.getLength()
2184
> test.insertAfter(clink,40000)
> test.play()
Handling the error cases
> Sound test2 = new
Sound("D:/cs1316/MediaSources/thisisat
est.wav");
> test.insertAfter(test2,40000)
> test.play()
First, making room
0
1
2
3
this.getLength()
start
12
94
-152
-27
11
inSound.getLength()
0
1
2
3
start
start+inSound.getLength()
12
94
…
Second, copying in
0
1
2
3
start
start+inSound.getLength()
12
inSound.getLength()
94
…
insertAfter
method
/**
* insert the input Sound after the nth sample (input integer).
* Modifies the given sound
* @param insound Sound to insert
* @param start index where to start inserting the new sound
**/
public void insertAfter(Sound inSound, int start){
SoundSample current=null;
// Find how long insound is
int amtToCopy = inSound.getLength();
int endOfThis = this.getLength()-1;
if (start + amtToCopy > endOfThis)
{// If too long, copy only as much as will fit
amtToCopy = endOfThis-start-1;}
else {
// If short enough, need to clear out room.
// Copy from endOfThis-amtToCopy;, moving backwards
// (toward front of list) to start,
// moving UP (toward back) to endOfThis
// KEY INSIGHT: How much gets lost off the end of the
// array? Same size as what we're inserting -- amtToCopy
for (int source=endOfThis-amtToCopy; source >= start ; source--)
{
// current is the TARGET -- where we're copying to
current = this.getSample(source+amtToCopy);
current.setValue(this.getSampleValueAt(source));
}
}
// NOW, copy in inSound up to amtToCopy
for (int target=start,source=0;
source < amtToCopy;
target++, source++) {
current = this.getSample(target);
current.setValue(inSound.getSampleValueAt(source));
}
}
Setting up the variables
SoundSample current=null;
// Find how long insound is
int amtToCopy =
inSound.getLength();
int endOfThis = this.getLength()-1;
Checking for room
if (start + amtToCopy > endOfThis)
{// If too long, copy only as much as will fit
amtToCopy = endOfThis-start-1;}
else {
// If short enough, need to clear out room.
Now, copy down
else {
// If short enough, need to clear out room.
// Copy from endOfThis-amtToCopy;, moving backwards
// (toward front of list) to start,
// moving UP (toward back) to endOfThis
// KEY INSIGHT: How much gets lost off the end of the
// array? Same size as what we're inserting -- amtToCopy
for (int source=endOfThis-amtToCopy; source >= start ; source--)
{
// current is the TARGET -- where we're copying to
current = this.getSample(source+amtToCopy);
current.setValue(this.getSampleValueAt(source));
}
}
Finally, copy in the new sound
//** Second, copy in inSound up to amtToCopy
for (int target=start,source=0;
source < amtToCopy;
target++, source++) {
current = this.getSample(target);
current.setValue(
inSound.getSampleValueAt(source));
}
How do we delete?
> Sound test = new
Sound("D:/cs1316/MediaSources/thisisat
est.wav");
> test.getLength()
64513
> test.delete(2000,30000)
> test.play() // We hear “This test”
First, copy from end to
getLength, back to start
start
end
This distance is start-end
this.getLength()
Then, clear out the end
start
end
this.getLength()
00000000…
This distance is start-end.
And we’ll go from the
length, backwards.
Deleting
method
/**
* Delete from start to end in this sound
* @param start where to start deletion
* @param end where to stop deletion
**/
public void delete(int start, int end){
int value = 0;
// Basically, we simply copy from "end" to
getLength back to start
for (int source=end, target=start;
source < this.getLength();
source++, target++)
{value = this.getSampleValueAt(source);
this.setSampleValueAt(target,value);}
// Then clear out the rest. Gap is end-start
length
int gap = end-start;
for (int i=1; i <= gap ; i++) {
this.setSampleValueAt(this.getLength()-i,0);}
}
First, copy up—over the start to
end gap
// Basically, we simply copy from "end" to
getLength back to start
for (int source=end, target=start;
source < this.getLength();
source++, target++)
{value = this.getSampleValueAt(source);
this.setSampleValueAt(target,value);}
Then, clear out the gap at the
end
// Then clear out the rest. Gap is end-start
length
int gap = end-start;
for (int i=1; i <= gap ; i++) {
this.setSampleValueAt(
this.getLength()-i, 0);}
Arrays: Strengths and
weaknesses

Strengths:

Weaknesses:
• Easy to understand
• Very efficient
• “Static”—it’s always the same length (shape?)
• Any change in the middle is hard to do
• Expensive in complexity and processing
• “Static”—it’s always the same length (shape?)