// FFTSpectrum.java import java.awt.*; public class FFTSpectrum extends Canvas { private static final int MAX_HARMONICS = 64; private double[] data = null; private double min, max; private String errStr = null; public FFTSpectrum() { setBackground(Color.black); } public Dimension getPreferredSize() { return new Dimension(250, 100); } public void plot(double[] ar, double[] ai, int numOfPoints) { errStr = null; if (numOfPoints > MAX_HARMONICS) errStr = "Too many harmonics to display."; else if (numOfPoints > 0) { data = new double[numOfPoints]; max = min = data[0] = Math.sqrt(ar[1] * ar[1] + ai[1] * ai[1]); for(int i = 1; i < numOfPoints; i++) { data[i] = Math.sqrt(ar[i+1] * ar[i+1] + ai[i+1] * ai[i+1]); if (data[i] > max) max = data[i]; if (data[i] < min) min = data[i]; } } else errStr = "All harmonics are filtered out."; repaint(); } private int scalePoint(double point) { int heightOfMax = (int)(0.95 * this.getSize().height); return (int)(point / max * heightOfMax); } public void paint(Graphics g) { g.setColor(Color.black); g.fillRect(0, 0, this.getSize().width, this.getSize().height); if (errStr != null) { Font font = new Font("Monospaced", Font.PLAIN, 16); int length = getFontMetrics(font).stringWidth(errStr); g.setColor(Color.white); g.setFont(font); g.drawString(errStr, (this.getSize().width - length) / 2, this.getSize().height / 2); } else if (data != null) { int width = this.getSize().width / data.length; for(int i = 0; i < data.length; i++) { int height = scalePoint(data[i]), x = i * width, y = this.getSize().height - height; g.setColor(Color.red); g.fillRect(x + 2, y, width - 4, height); } } } }