package jmsltestsuite; import java.awt.event.*; import com.didkovsky.portview.PVFrame; import com.softsynth.jmsl.MusicShape; import com.softsynth.jmsl.util.*; import com.softsynth.jmsl.view.*; /** Use JMSL's FFT utility class to calculate spectra of some shapes. Display spectra and shapes in MusicShapeEditor @author Nick Didkovsky */ public class FFTTest { public static void main(String args[]) { int size = 512; double ampInc = (Math.PI * 2) / size; // CHANGE THESE TWO ARRAYS TO PLAY WITH DIFFERENT SPECTRA!!!!!!!!!!!!!!!!!!!!!! double amps[] = { 0.5, 0.125 }; double freqs[] = { 1, 20 }; // load data[] with sine waves of various freqs and amps double data[] = new double[size * 2 + 2]; // Pad your array with an extra pair; FFT algo is 1-based array FIXME for (int i = 1; i < size; i++) { for (int j = 0; j < amps.length; j++) { data[i * 2] += amps[j] * Math.sin(ampInc * i * freqs[j]); } } // Set up a MusicShape so data[] and FFT results can be viewed in ShapeEditor MusicShape s = new MusicShape(2); for (int i = 0; i < data.length / 2; i++) { s.add(0.0, 0); // stuff with zeros to be overwritten with real data later } s.setDimensionName(0, "Time Domain"); s.setDimensionName(1, "Harmonics"); FFT.copyToShape(s, data, 0, true); // shape, data[], dimension to copy to, true=timedomain FFT.fft(data, size, 1); FFT.copyToShape(s, data, 1, false); // shape, data[], dimension to copy to, false=harmonics, so load with magnitudes of (real,imag) data[] pairs // Now test 1/f noise for (int i = 0; i < data.length; i++) { data[i] = 0.0; } int bits = 8; Oof oof = new Oof(bits); for (int i = 1; i < data.length / 2; i++) { data[i * 2] = (double) oof.next() / (2 << bits); } // Set up another MusicShape so data[] and FFT results can be viewed in ShapeEditor MusicShape s2 = new MusicShape(2); for (int i = 0; i < data.length / 2; i++) { s2.add(0.0, 0); // stuff with zeros to be overwritten with real data later } s2.setDimensionName(0, "1/f Time Domain"); s2.setDimensionName(1, "1/f Harmonics"); FFT.copyToShape(s2, data, 0, true); // shape, data[], dimension to copy to, true=timedomain FFT.fft(data, size, 1); FFT.copyToShape(s2, data, 1, false); // shape, data[], dimension to copy to, false=harmonics, so load with magnitudes of (real,imag) data[] pairs MusicShapeEditor se = new MusicShapeEditor(); se.addMusicShape(s); se.addMusicShape(s2); PVFrame f = new PVFrameAdapter("Close to Exit"); f.add(se.getComponent()); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setVisible(true); } }