ppt

advertisement
CS 177 Week 8 Recitation Slides
JES Sound functions
and
Modifying Sounds
Increasing/Decreasing Volume
Maximizing (Normalizing)
Splicing
Reversing
Mirroring
1
ANY QUESTIONS?
2
Let’s remember Sound

We store sounds as array of integer values
 Each value is stored as 16 bits
 The range is from –2(16-1) to +2(16-1) – 1
 i.e from –32768 to 32767
59
28
-123
0
-32768
20456
32767
0
1
2
3
4
5
6
The length of this sound is 7
3
JES Functions about Sound
pickAFile()
makeSound(file)
play(sound)
Let the user pick a sound file
(.wav file)
Takes a filename as input, reads the file,
and creates a sound from it. Returns the
sound.
Plays a sound provided as input. No return
value.
getLength(sound)
Takes a sound as input and returns the
number of samples in that sound.
getSamplingRate(sound)
Takes a sound as input and returns the
number representing the number of
samples in each second for the sound.
getSamples(sound)
Takes a sound as input and returns the
Samples in that sound.
writeSoundTo(sound, path)
4
Takes a sound and a filename (a string) and
writes the sound to that file as a WAV file.
(Make sure that the filename ends in '.wav'
if you want the operating system to treat it
right.)
JES Functions about Sound
getSampleValueAt(sound, index)
Takes a sound and an index (an integer
value), and returns the value of the sample
(between -32768 and 32767) for that object.
setSampleValueAt(sound, index, value)
Takes a sound, an index, and a value
(should be between -32768 and 32767), and
sets the value of the sample at the given
index in the given sound to the given value.
getSampleObjectAt(sound, index)
Takes a sound and an index (an integer
value), and returns the Sample object at
that index.
getSampleValue(sample)
getSample (sample)
Takes a Sample object and returns its value
(between -32768 and 32767).
setSampleValue(sample, value)
setSample (sample, value)
Takes a Sample object and a value (should
be between -32768 and 32767), and sets the
sample to that value.
getSound(sample)
Takes a Sample object and returns the
Sound that it belongs to.
A sample object remembers its sound, so if you
change the sample object, the sound gets changed.
5
Demonstrating Working with
Sound in JES
>>> filename=pickAFile()
>>> print filename
/Users/guzdial/mediasources/preamble.wav
>>> sound=makeSound(filename)
>>> print sound
Sound of length 421109
>>> samples=getSamples(sound)
>>> print samples
Samples, length 421109
>>> print getSampleValueAt(sound,1)
36
>>> print getSampleValueAt(sound,2)
29
>>> explore(sound)
6
Demonstrating working with
samples
>>> print getLength(sound)
220568
>>> print getSamplingRate(sound)
22050.0
>>> print getSampleValueAt(sound,220567)
68
>>> print getSampleValueAt(sound,220568)
I wasn't able to do what you wanted.
The error java.lang.ArrayIndexOutOfBoundsException has occurred
Please check line 0 of
>>> print getSampleValueAt(sound,1)
36
>>> setSampleValueAt(sound,1,12)
>>> print getSampleValueAt(sound,1)
12
7
Example: Changing Samples
>>> soundfile=pickAFile()
>>> sound=makeSound(soundfile)
>>> sample=getSampleObjectAt(sound,1)
>>> print sample
Sample at 1 value at 59
>>> print sound
Sound of length 387573
>>> print getSound(sample)
Sound of length 387573
>>> print getSample(sample)
59
>>> setSample(sample,29)
>>> print getSample(sample)
29
8
Increasing and Decreasing the
Volume
def increaseVolume(sound):
for sample in getSamples(sound):
value = getSampleValue(sample)
setSampleValue(sample,value * 2)
>>> f=pickAFile()
>>> s=makeSound(f)
>>> increaseVolume(s)
def decreaseVolume(sound):
for sample in getSamples(sound):
value = getSampleValue(sample)
setSampleValue(sample,value * 0.5)
>>> f=pickAFile()
>>> s=makeSound(f)
>>> decreaseVolume(s)
9
Recognize some similarities?
def increaseVolume(sound):
for sample in getSamples(sound):
value = getSampleValue(sample)
setSampleValue(sample, value*2)
def increaseRed(picture):
for p in getPixels(picture):
value=getRed(p)
setRed(p,value*1.2)
def decreaseVolume(sound):
for sample in getSamples(sound):
value = getSampleValue(sample)
setSampleValue(sample, value*0.5)
def decreaseRed(picture):
for p in getPixels(picture):
value=getRed(p)
setRed(p,value*0.5)
10
Maximizing (Normalizing) sound


First, figure out the loudest sound (largest sample).
Next, figure out how much we have to increase/decrease
that sound to fill the available space

We want to find the amplification factor amp, where
amp * loudest = 32767


11
In other words:
amp = 32767/loudest
Finally, amplify each sample by multiplying it by amp
Maxing (normalizing) the sound
This loop finds the loudest
def normalize(sound):
sample
largest = 0
for s in getSamples(sound):
largest = max(largest, getSampleValue(s))
amplification = 32767.0 / largest
Why 32767.0 but not 32767?
print "Largest sample value in original sound was",
print "Amplification multiplier is", amplification
largest
for s in getSamples(sound):
louder = amplification * getSampleValue(s)
setSampleValue(s, louder)
We’re making an assumption here
that the maximum positive value is
also the maximum negative value.
12
This loop amplifies the sound
Note that the largest sample will be
updated with 32767
Avoiding clipping


13
Why are we being so careful to stay within range? What
if we just multiplied all the samples by some big number
and let some of them go over 32,767?
The result then is clipping
 Clipping: The awful, buzzing noise whenever the
sound volume is beyond the maximum that your
sound system can handle.
Processing only part of the
sound


What if we wanted to increase or decrease the volume of
only part of the sound?
 use a range() function with our for loop
Let’s increase volume by sample index (using range)
def increaseVolumeByRange(sound):
for sampleNumber in range(0, getLength(sound)):
value = getSampleValueAt(sound, sampleNumber)
setSampleValueAt(sound, sampleNumber, value * 2)
SAME AS
14
def increaseVolume(sound):
for sample in getSamples(sound):
value = getSample(sample)
setSample(sample,value * 2)
Modify different sound sections
Here we increase the volume in the first half,
and decrease it in the second half.
def increaseAndDecrease(sound):
length = getLength(sound)
for index in range(0, length/2):
value = getSampleValueAt(sound, index)
setSampleValueAt(sound, index, value*2)
for sampleIndex in range(length/2, length):
value = getSampleValueAt(sound, index)
setSampleValueAt(sound, index, value*0.2)
15
Splicing Sounds




16
Splicing gets its name from literally cutting and pasting
pieces of magnetic tape together
The easiest kind of splicing is when the component
sounds are in separate files.
All we need to do is copy each sound, in order, into a
target sound.
Here’s a recipe that creates the start of a sentence,
“Guzdial is …” (You may complete the sentence.)
Splicing whole sound files
def merge():
guzdial = makeSound(getMediaPath("guzdial.wav"))
isSound = makeSound(getMediaPath("is.wav"))
target = makeSound(getMediaPath("sec3silence.wav"))
index = 0
for source in range(0, getLength(guzdial)):
value = getSampleValueAt(guzdial, source)
setSampleValueAt(target, index, value)
index = index + 1
for source in range(0, int(0.1*getSamplingRate(target))):
setSampleValueAt(target, index, 0)
index = index + 1
for source in range(0, getLength(isSound)):
value = getSampleValueAt(isSound, source)
setSampleValueAt(target, index, value)
index = index + 1
normalize(target)
play(target)
return target
17
How it works

Creates sound objects for the words “Guzdial”, “is” and
the target silence

Set target’s index to 0, then let each loop increment
index and end the loop by leaving index at the next
empty sample ready for the next loop

The 1st loop copies “Guzdial” into the target

The 2nd loop creates 0.1 seconds of silence

The 3rd loop copies “is” into the target

Then we normalize the sound to make it louder
18
Reversing Sounds

We can also modify sounds by reversing them
def reverse(source):
target = makeEmptySound(getLength(source))
sourceIndex = getLength(source) - 1 # start at end
for targetIndex in range(0, getLength(target)):
value = getSampleValueAt(source, sourceIndex)
setSampleValueAt(target, targetIndex, value)
sourceIndex = sourceIndex - 1 # move backwards
return target
19
Mirroring

We can mirror sounds in exactly the same way
we mirrored pictures
def mirrorSound(sound):
len = getLength(sound)
mirrorpoint = len/2
for index in range(0, mirrorpoint):
left = getSampleObjectAt(sound, index)
right = getSampleObjectAt(sound, len-index-1)
value = getSampleValue(left)
setSampleValue(right, value)
return (sound)
20
Final QUESTIONS???
21
Download