Harmonic Analysis

Summary

This demo illustrates how the JMSL Library can be used to perform spectral analysis of time series data. The signals are recordings of the four open strings of a cello being bowed. Each signal is of approximately constant pitch and thus has an easily interpretable spectral signal. These were obtained from www.cello.org.

Usage

Select one of the strings in using the ButtonGroup in the top panel. Press "Calculate FFT" to perform the spectral analysis and display the results in a new window. Only the first 0.8 seconds of the time series is displayed by default. To see the entire signal (about 3.5 seconds), click "Show full sample". "Reset View" resets the x axis range to [0.0, 0.8].

Click and drag in the chart region to zoom in on the data. Note that the y axis range does not change; i.e., you only zoom in the x direction.

JMSL Library Math/Stat Classes

com.imsl.math.FFT - this class computes the discrete Fourier transform of the selected sound signal using a variant of the Cooley-Tukey algorithm. Using this class is quite easy and takes only a few lines of code:

double[] a;
FFT transform = new FFT(y.length);
a = transform.forward(y);

Creating a power spectrum from the transform results requires a few more lines of code:

// Calculate the power spectrum, as per documentation,
// including a factor normalizing to the length of the input:

double
[] power = new double[y.length/2];
double
[] f = new double[power.length];
f[0] = 0.0d;
power
[0] = Math.abs(a[0])/y.length;
for
(int i = 1; i < power.length; i++) {
    f
[i] = i/(t_lim[1] - t_lim[0]);
    power
[i] = Math.sqrt(a[2*i-1]*a[2*i-1] + a[2*i]*a[2*i])/y.length;
}

JMSL Library Charting Classes

The chart in the main page is a normal line graph and is created in the drawGraph() method of Harmonic.java. The FFT chart is created in the draw() method of PlotFFT.java and is created as a filled line graph:

data.setDataType(Data.DATA_TYPE_FILL);
data
.setLineColor(java.awt.Color.black);
data
.setFillColor(plotColor);

Java Code

The PlotFFT JDialog uses the parent object passed as a parameter to its constructor to position itself on the screen.

public PlotFFT(java.awt.Frame parent) {
    super
(parent, false);
    initComponents
();
    java
.awt.Dimension parentSize = parent.getSize();
    java
.awt.Point parentLoc = parent.getLocationOnScreen();
    parentLoc
.x += parentSize.width/2.5;
    parentLoc
.y += parentSize.height/2.5;
    setLocation
(parentLoc.x, parentLoc.y);

Links to Source Code

Harmonic.java This is the main class that extends JFrameChart. It sets up the main chart and the JPanel of options. The Fourier Transform is also computed and passed to PlotFFT via the draw() method.
PlotFFT.java This JDialog uses the parent to position itself and displays a line chart using data passed in through the draw() method.
AccessWaveFile.java This class uses classes from javax.sound.sampled to read in .wav files. It is called from getWaveData() in Harmonic.java.

Running This Demo

Two alternatives are available to run this demo:

1) Use the source code in your development environment as any other Java code. More information is available in the How To.

2) An executable jar file containing all of the demos referenced in this guide is included in the jmsl/lib directory. On Windows, you may double-click the file to run it if files with a ".jar" extension are properly registered with javaw.exe. Alternatively, for both Windows and UNIX environments, the jar file may be executed from the command line using java -jar gallery.jar.

As list of buttons, one for each demo, is created. Demos can be subsetted as they relate to specific areas (Math, Stat, Finance, Charting) by choosing the appropriate selection on the JComboBox. To run the Additional Demos, select Quick Start in the JComboBox.