N6 07 Sound
N6 07 Sound
David Cairns
Sound Concepts
• Sound Generation
• Mixing Sound
• Playing a Sound in Java
• Sound Effects / Filters
• Playing Multiple Sounds
• MIDI Music
30000
22500
15000
7500
0
-7500
-15000
-22500
-30000
Sound Mixing
When we hear sound, it is a blend of many signals all
combined together. Our ears and brain do a rather amazing
job of splitting it into its original parts.
40000 18000
30000 13500
20000 9000
10000 4500
0 0
-10000 -4500
-20000 -9000
-30000 -13500
-40000 -18000
But your brain is able to pick it apart to determine that it was formed from this:
30000
22500
15000
7500
0
-7500
-15000
-22500
-30000
Why so complicated?
– The breakdown of the sound into its components provides us with a lot of
flexibility
– We can create our own sound effects / filters / mixers
• This would not be possible if all you could do was play a sound file without access to its
contents
clip.open(stream);
clip.start();
Thread.sleep(100); // Give it a chance to start playing….
while (clip.isRunning()) { Thread.sleep(100); }
clip.close();
}
catch (Exception e) { return false; }
return true;
}
}
– You could record all the different types of sound you might wish to play before
loading them into your game, however this is not very flexible.
– A better solution is to record a standard sample and then apply a particular filter to
provide the distortion you want at run time (e.g. Muffle a sound if it passes
through a wall).
– This becomes more important the bigger and more dynamic a game is, particularly
with 3D games. In 3D it is usually not possible to anticipate all possible sounds
(with distortions applied) that a user might hear.
Amplitude
Time Time
Reverse Filter
An alternative filter could be to reverse the signal (play it
backwards) such that the signal that is at the start, becomes
the one at the end:
Amplitude
Amplitude
Time Time
00000010 11000011
00000010 11000011
FadeFilterStream - 1
import java.io.*;
FadeFilterStream - 3
public class FadePlay {
Multiple Sounds
The previous examples did not return control until they had finished
playing a sound. This is not very useful.
– What if you want to play multiple sounds?
– What if the player wants to move?
– What about updating the screen?
ThreadPlay(String fname) {
filename = fname;
finished = false;
}
s1.start();
s2.start();
Options
– Uncompressed
• CD, WAV
– Compressed
• LA, FLAC
– Lossy Compressed
• MP3, Ogg Vorbis, Real
– Music Notation
• MIDI
Sound Formats
Uncompressed
– CD Audio, WAV
– Sound signal is saved at the same rate it was recorded
– Highest sound quality
– Largest file size
Compressed
– LA : Lossless Audio
– FLAC : Free Lossless Audio Codec (Coder / Decoder)
– Decoded sound signal is the same quality as original recording (no loss)
– Encoded file is significantly smaller than original recording (~50%)
– Requires decompression before it can be sent to sound device (uses extra
CPU time)
MIDI
– Music is stored as a form of notation
• Multiple tracks, for each track: instrument bank, note on, note off, volume
– Very compact, files are a few K rather than MB
– Reproduced sound dependent on quality of sound bank for the reproduced instrument
– Allows a track recorded via a keyboard to be played back as a guitar...
– Only records music – not vocals
You need:
– Sequence
• the MIDI data encoding the musical score
– Sequencer
• reads the sequence and sends it to the synthesiser
Soundbanks
– A MIDI sequencer uses a soundbank (a database of sound samples) to play each
note listed in the MIDI file.
– The default soundbank in Java is not great but you can download a better version
from :
https://www.oracle.com/java/technologies/sound-banks.html
Tempo
– You can alter the tempo of the musical piece
• setTempoFactor(float factor)
– A factor > 1 speeds up the music, a factor < 1 slows it down