package de.tu.darmstadt.seemoo.ansian.drawables; import android.graphics.Canvas; import android.util.Log; import de.tu.darmstadt.seemoo.ansian.control.DataHandler; import de.tu.darmstadt.seemoo.ansian.control.StateHandler; import de.tu.darmstadt.seemoo.ansian.model.FFTDrawData; import de.tu.darmstadt.seemoo.ansian.model.preferences.ColorPreference; import de.tu.darmstadt.seemoo.ansian.model.preferences.MiscPreferences; import de.tu.darmstadt.seemoo.ansian.model.preferences.Preferences; /** * * Drawable for the frequency spectrum in AnalyzerSurface * * @author Steffen Kreis * */ public class FftSpectrumDrawable extends MyDrawable { MiscPreferences preferences; private int fftHeight; private int fftWidth; public FftSpectrumDrawable() { preferences = Preferences.MISC_PREFERENCE; } private float[] peaks; // peak hold points private static final String LOGTAG = "FftSpectrumDrawable"; public void init(int fftHeight, int fftWidth) { this.fftHeight = fftHeight; this.fftWidth = fftWidth; } @Override public void draw(Canvas canvas) { FFTDrawData fftDrawData; if (StateHandler.isScanning()) { fftDrawData = DataHandler.getInstance().getScannerDrawData(fftWidth); } else { fftDrawData = DataHandler.getInstance().getFrequencyDrawData(fftWidth); } float[] mag = null; int startX = 0; if (fftWidth != 0 && fftDrawData != null) { mag = fftDrawData.getValues(); startX = fftDrawData.getStart(); } if (mag != null) { final float minDB = Preferences.GUI_PREFERENCE.getCurMinDB(); final float maxDB = Preferences.GUI_PREFERENCE.getCurMaxDB(); // Log.d(LOGTAG, "checkScaletotalXscale: " + // analyzerSurface.getTotalXScale()); // float[] peaks = analyzerSurface.getCurrentPeaks(); float dbDiff = maxDB - minDB; // Size (in pixel) per 1dB in the fft float dbWidth = fftHeight / dbDiff; // y coordinate of the previously processed pixel (only used with // drawing type line) float previousY = fftHeight; // y coordinate of the currently processed pixel float currentY; // Update Peak Hold if (Preferences.GUI_PREFERENCE.isPeakHold()) { // First verify that the array is initialized correctly: if (peaks == null || peaks.length != mag.length) { peaks = new float[mag.length]; for (int i = 0; i < peaks.length; i++) peaks[i] = -999999F; // == no peak ;) } // Update the peaks: for (int i = 0; i < mag.length; i++) peaks[i] = Math.max(peaks[i], mag[i]); } else { peaks = null; } for (int pos = 0; pos < mag.length; pos++) { // FFT: if (pos >= 0) { if (mag[pos] > minDB) { int currentX = pos + startX; currentY = fftHeight - (mag[pos] - minDB) * dbWidth; if (currentY < 0) currentY = 0; switch (Preferences.GUI_PREFERENCE.getFftDrawingType()) { case 1: canvas.drawLine(currentX, fftHeight, currentX, currentY, ColorPreference.FFT_PAINT); break; case 2: if (currentX == startX) { canvas.drawPoint(currentX, currentY, ColorPreference.FFT_PAINT); } else { canvas.drawLine(currentX - 1, previousY, currentX, currentY, ColorPreference.FFT_PAINT); } previousY = currentY; if (currentX + 1 == startX + mag.length) canvas.drawPoint(currentX, currentY, ColorPreference.FFT_PAINT); break; default: Log.e(LOGTAG, "drawFFT: Invalid fft drawing type"); } } } } } } public void resetPeaks() { // Check if the frequency or sample rate of the incoming signals // is // different from the ones before: if (peaks != null) { for (int i = 0; i < peaks.length; i++) peaks[i] = -999999F; // reset peaks. We could also shift // and // scale. But for now they are // simply reset. } } }