Java Reference
In-Depth Information
data from decodedAudio , which contains our decoded audio data and writes it to both line and
audioConsumer . The variable line is the Java Sound object that actually makes the sound. The write
method on line is interesting because it blocks until it is ready for more data, which in effect keeps this
loop in sync with what you are hearing. audioConsumer is responsible for actually doing the digital signal
processing.
I am going to leave out the details of how the audio data is actually processed, because it is a rather
complex topic and I didn't write the class that does the work. The class comes from a subproject of the
JDesktop Integration Components (JDIC) project called the Music Player Control API. You can find the
JDIC project at https://jdic.dev.java.net .
In general, though, the DSP classes take the audio data as it is being written and break the signal up
into 20 values. Each value represents how much of the sound is coming from a particular frequency in
the audio, which is known as a spectral analysis . The values are stored in the variable levels of the class
SoundHelper . The variable levels is simply an array of 20 doubles, each having a value between 0.0 and
1.0. A value of 0.0 indicates that that particular frequency is not contributing at all to what you are
hearing, and a value 1.0 indicates that it is contributing as much as possible.
JavaFX and Java
The class SoundHelper now provides us with the ability to play an audio file and get information about
which levels are high or low as the music is being played. The next step is to expose this functionality to a
JavaFX application. When creating applications that bridge the two environments of JavaFX and Java, it
is recommended that the Observer/Observable pattern be used.
The Observer/Observable pattern is pretty simple; it just states that an observable object should be
able to inform observers when some value has changed. Let's look at the classes and interfaces provided
by Java to implement this pattern. First the class java.lang.Observable implements a number of
methods, but the three we are interested in are addObserver , setChanged , and notifyObservers . The
method addObserver takes an Observer that should be informed whenever the Observable 's data
changes. To inform the Observer that changes have taken place, the Observable should first call
setChanged and then notifyObservers . Calling these two methods causes the update method from the
interface Observer to be called. This pattern is very much like the listener pattern common in Swing
programming.
Looking at Listing 9-2 we can see that the class SoundHelper extends Observable . This means it can
inform any observers that a change has happened. If we look at the JavaFX class SoundPlayer in Listing 9-
4, we can see the other half of this relationship.
Listing 9-4. SoundPlayer.fx
public class SoundPlayer extends Observer{
public var volume:Number = 1.0 on replace {
soundHelper.setVolume(volume);
}
public var currentTime:Duration;
public var songDuration:Duration;
public var url:String;
public var file:File;
Search WWH ::




Custom Search