Java tutorial
/* * DataWave Library - A library that allows data to be sent between nodes via sound. * Copyright (C) 2015 Jesse Prescott (BleedObsidian) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.bleedobsidian.datawave.utils; import org.apache.commons.math3.complex.Complex; import org.apache.commons.math3.transform.DftNormalization; import org.apache.commons.math3.transform.FastFourierTransformer; import org.apache.commons.math3.transform.TransformType; import com.bleedobsidian.datawave.Audio; /** * A utility class for manipulating sine waves. * * @author Jesse Prescott (BleedObsidian) */ public class Sinewave { /** * Produce sound data from a sine wave. * * @param sampleRate Sample rate. * @param frequency Frequency in Hertz. * @param duration Duration in seconds. * @param amplitude Volume scale. * * @return Samples. */ public static double[] generateSound(double sampleRate, double frequency, double duration, double amplitude) { int n = (int) (sampleRate * duration); double[] a = new double[n + 1]; for (int i = 0; i <= n; i++) { a[i] = amplitude * Math.sin(2 * Math.PI * i * frequency / sampleRate); } return a; } /** * Calculate the frequency of sine wave from sound data. * * @param sampleRate Sample rate. * @param samples Samples. * * @return Frequency. */ public static double calculateFrequency(double sampleRate, double[] samples) { FastFourierTransformer transformer = new FastFourierTransformer(DftNormalization.STANDARD); Complex[] complex = transformer.transform(samples, TransformType.FORWARD); double real; double im; double mag[] = new double[complex.length]; for (int i = 0; i < complex.length; i++) { real = complex[i].getReal(); im = complex[i].getImaginary(); mag[i] = Math.sqrt((real * real) + (im * im)); } double peak = 0.2; int index = -1; for (int i = 0; i < complex.length; i++) { if (peak < mag[i]) { index = i; peak = mag[i]; } } return ((sampleRate * index) / Audio.SAMPLE_BUFFER_SIZE) * 2; } }