private float[] GetFrecuencySampleFromAudioData(float[] audioData) { var frecuencySample = new float[SAMPLES / DIVISOR]; _values = new float[2 * SAMPLES]; for (var i = 0; i < SAMPLES; i++) { _values[2 * i] = audioData[i]; _values[2 * i + 1] = 0; } _fourierTransform = new LomontFFT(); _fourierTransform.FFT(_values, true); var maxValue = 0f; for (var i = 0; i < SAMPLES / DIVISOR; i++) { var value = Magnitude(_values[2 * i], _values[2 * i + 1]); if (maxValue < value) { maxValue = value; } } for (var i = 0; i < SAMPLES / DIVISOR; i++) { frecuencySample[i] = Magnitude(_values[2 * i], _values[2 * i + 1]) / maxValue; } return(frecuencySample); }
void Update() { //can use these variables that appear in the inspector, or can call the public functions directly from other scripts if (m_stopMicrophoneListener) { StopMicrophoneListener(); } if (m_startMicrophoneListener) { StartMicrophoneListener(); } //reset paramters to false because only want to execute once m_stopMicrophoneListener = false; m_startMicrophoneListener = false; //must run in update otherwise it doesnt seem to work MicrophoneIntoAudioSource(m_microphoneListenerOn); //can choose to unmute sound from inspector if desired DisableSound(!m_disableOutputSound); m_audioSource.GetOutputData(m_extractedData, 0); double[] doubleData = Array.ConvertAll(m_extractedData, x => (double)x); m_fft.FFT(doubleData, true); m_extractedData = Array.ConvertAll(doubleData, x => (float)x); }
/// <summary> /// This method duplicates exactly the function /// ifft(input) in MATLAB /// Requires a complex input number to be able to exactly /// transform back to an orginal signal /// i.e. x = ifft(fft(x)) /// </summary> /// <param name="input"></param> /// <param name="inputComplex">If true, the input array is a complex arrray. /// i.e. the array alternates between a real and an imaginary value. /// If false, the array contains only real values</param> /// <param name="returnComplex">If true, return a complex return arrray. /// i.e. the array alternates between a real and an imaginary value. /// If false, return only the positive real value /// </param> /// <returns>signal (complex or only positive real values)</returns> public static double[] IFFT(double[] input, bool inputComplex = true, bool returnComplex = true) { var fft = new LomontFFT(); double[] complexSignal; if (inputComplex) { complexSignal = input; } else { complexSignal = DoubleToComplexDouble(input); } fft.FFT(complexSignal, false); if (returnComplex) { return(complexSignal); } else { return(Real(complexSignal)); } }
public double[] Spectrum(double[] input, bool scale) { var fft = new LomontFFT(); var data = Helper.ToComplex(input); fft.FFT(data, true); var spectrum = Helper.ComputeSpectrum(data); fft.FFT(data, false); Helper.ToDouble(data, input); return(spectrum); }
/// <summary> /// This method duplicates exactly the function /// fft(input) in MATLAB /// </summary> /// <param name="input">e.g. an audio signal</param> /// <returns>a complex array (the array alternates between a real and an imaginary value)</returns> public static double[] FFT(double[] input) { var fft = new LomontFFT(); var complexSignal = DoubleToComplexDouble(input); fft.FFT(complexSignal, true); return(complexSignal); }
/// <summary> /// Generate a spectrogram array spaced linearily /// </summary> /// <param name="samples">audio data</param> /// <param name="fftWindowsSize">fft window size</param> /// <param name="fftOverlap">overlap in number of samples (normaly half of the fft window size) [low number = high overlap]</param> /// <returns>spectrogram jagged array</returns> public static double[][] CreateSpectrogramLomont(float[] samples, int fftWindowsSize, int fftOverlap) { var fft = new LomontFFT(); int numberOfSamples = samples.Length; // overlap must be an integer smaller than the window size // half the windows size is quite normal double[] windowArray = FFTWindow.GetWindowFunction(FFTWindowType.HANNING, fftWindowsSize); // width of the segment - e.g. split the file into 78 time slots (numberOfSegments) and do analysis on each slot int numberOfSegments = (numberOfSamples - fftWindowsSize) / fftOverlap; var frames = new double[numberOfSegments][]; // since we are dealing with small buffer sizes (1024) but are trying to detect peaks at low frequency ranges // octaves 0 .. 2 for example, zero padding is nessessary to improve the interpolation resolution of the FFT // otherwise FFT bins will be quite large making it impossible to distinguish between low octave notes which // are seperated by only a few Hz in these ranges. //const int ZERO_PAD_MULTIPLIER = 4; // zero padding adds interpolation resolution to the FFT, it also dilutes the magnitude of the bins // TODO: figure out how to properly use zero_padding // even - Re, odd - Img var complexSignal = new double[2 * fftWindowsSize]; //var complexSignal = new double[2*fftWindowsSize*ZERO_PAD_MULTIPLIER*2]; // zero pad double lengthSqrt = Math.Sqrt(fftWindowsSize); for (int i = 0; i < numberOfSegments; i++) { // apply Hanning Window for (int j = 0; j < fftWindowsSize; j++) { // Weight by Hann Window complexSignal[2 * j] = (double)(windowArray[j] * samples[i * fftOverlap + j]); // need to clear out as fft modifies buffer (phase) complexSignal[2 * j + 1] = 0; } // FFT transform for gathering the spectrum fft.FFT(complexSignal, true); // get the ABS of the complex signal var band = new double[fftWindowsSize / 2]; for (int j = 0; j < fftWindowsSize / 2; j++) { double re = complexSignal[2 * j]; double img = complexSignal[2 * j + 1]; // do the Abs calculation and add with Math.Sqrt(audio_data.Length); // i.e. the magnitude spectrum band[j] = (double)(Math.Sqrt(re * re + img * img) * lengthSqrt); } frames[i] = band; } return(frames); }
/// <summary> /// Generate a spectrum graph array spaced linearily /// </summary> /// <param name="samples">audio data</param> /// <param name="fftWindowsSize">fft window size</param> /// <returns>spectrum graph array</returns> public static double[] CreateSpectrumAnalysisLomont(float[] samples, int fftWindowsSize) { var fft = new LomontFFT(); int numberOfSamples = samples.Length; // overlap must be an integer smaller than the window size // half the windows size is quite normal double[] windowArray = FFTWindow.GetWindowFunction(FFTWindowType.HANNING, fftWindowsSize); // even - Re, odd - Img var complexSignal = new double[2 * fftWindowsSize]; // apply Hanning Window // e.g. take 371 ms each 11.6 ms (2048 samples each 64 samples) for (int j = 0; (j < fftWindowsSize) && (samples.Length > j); j++) { // Weight by Hann Window complexSignal[2 * j] = (double)(windowArray[j] * samples[j]); // need to clear out as fft modifies buffer (phase) complexSignal[2 * j + 1] = 0; } // FFT transform for gathering the spectrum fft.FFT(complexSignal, true); var band = new double[fftWindowsSize / 2]; double lengthSqrt = Math.Sqrt(fftWindowsSize); for (int j = 0; j < fftWindowsSize / 2; j++) { double re = complexSignal[2 * j] * lengthSqrt; double img = complexSignal[2 * j + 1] * lengthSqrt; // do the Abs calculation and add with Math.Sqrt(audio_data.Length); // i.e. the magnitude spectrum band[j] = (double)(Math.Sqrt(re * re + img * img) * lengthSqrt); } return(band); }
public void Start() { var audioSource = GetComponent <AudioSource>(); _audioData = new float[audioSource.clip.samples * audioSource.clip.channels]; audioSource.clip.GetData(_audioData, 0); _values = new float[2 * SAMPLES]; for (var i = 0; i < SAMPLES; i++) { _values[2 * i] = _audioData[i]; _values[2 * i + 1] = 0; } _fourierTransform = new LomontFFT(); _fourierTransform.FFT(_values, true); var lineRenderer = GetComponent <LineRenderer>(); lineRenderer.useWorldSpace = false; var points = new Vector3[SAMPLES / DIVISOR]; var maxValue = 0f; for (var i = 0; i < SAMPLES / DIVISOR; i++) { var value = Magnitude(_values[2 * i], _values[2 * i + 1]); if (maxValue < value) { maxValue = value; } } for (var i = 0; i < SAMPLES / DIVISOR; i++) { points[i] = new Vector3(0.0004f * i, Magnitude(_values[2 * i], _values[2 * i + 1]) / maxValue, 0); } lineRenderer.positionCount = SAMPLES / DIVISOR; lineRenderer.SetPositions(points); }
public void TimetoFreq(ref double[] audioSamples, int fftType = 0) { switch (fftType) { case 0: { _fft.FFT(audioSamples, true); } break; case 1: { _fft.RealFFT(ref audioSamples, true); } break; case 2: { _fft.TableFFT(audioSamples, true); } break; } }
Dictionary <int, bool> instantiatedBeatMap; //prevent duplicate beat creation // Use this for initialization void Start() { audioSource = GetComponent <AudioSource>(); clip = audioSource.clip; fft = new LomontFFT(); float[] samples = new float[clip.samples * clip.channels]; clip.GetData(samples, 0); //convert float to double double[] samplesD = new double[samples.Length]; for (int i = 0; i < samplesD.Length; i++) { samplesD[i] = (double)samples[i]; } Debug.Log("clip samples: " + clip.samples); //debug Debug.Log("clip channels: " + clip.channels); //debug Debug.Log("clip duration: " + clip.length); //debug steps = Mathf.RoundToInt(samplingInterval / secondInMilliseconds * clip.frequency); Debug.Log("steps: " + steps); //debug int n = samplingWindowSize; int k = 0; for (int j = 0; j < samplingWindowSize; j++) { n = n / 2; if (n <= 0) { break; } k++; } band = new float[k + 1]; g = new GameObject[k + 1]; positions = new Dictionary <int, Vector3[]>(); for (int i = 0; i < band.Length; i++) { band[i] = 0; g[i] = GameObject.CreatePrimitive(PrimitiveType.Sphere); g[i].GetComponent <Renderer>().material.SetColor("_Color", Color.cyan); g[i].transform.position = new Vector3(i, 0, 0); } for (int i = 0; i < samplesD.Length; i = i + steps) { double[] samplingWindow = new double[samplingWindowSize]; if (i > samplingWindowSize) { Array.Copy(samplesD, i - samplingWindowSize / 2, samplingWindow, 0, samplingWindowSize); } else //i = 0 { Array.Copy(samplesD, i, samplingWindow, 0, samplingWindowSize); } fft.FFT(samplingWindow, true); //convert double to float float[] samplingWindowF = new float[samplingWindow.Length]; for (int j = 0; j < samplingWindow.Length; j++) { samplingWindowF[j] = (float)samplingWindow[j]; } checkWindow(i, samplingWindowF); /* * if (i > 70000) * { * break; * }*/ } /* * using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\wgwong\Desktop\out2.txt")) * { * foreach (var entry in positions) * { * file.WriteLine("position: " + entry.Key); * for (int i = 0; i < entry.Value.Length; i++) { * var element = entry.Value[i]; * file.WriteLine("element[" + i + "]: " + element.x + ", " + element.y + ", " + element.z); * } * file.WriteLine("\n"); * } * }*/ leftLaneBalls = new ArrayList(); midLaneBalls = new ArrayList(); rightLaneBalls = new ArrayList(); leftBumper = new Bumper(new Vector3(12, 0, 2), Color.red); midBumper = new Bumper(new Vector3(14, 0, 2), Color.blue); rightBumper = new Bumper(new Vector3(16, 0, 2), Color.green); beatMap = new Dictionary <int, bool[]>(); instantiatedBeatMap = new Dictionary <int, bool>(); createBeatMap(); audioSource.Play(); }
void fftThat() { /* * while (decoder.readSamples(samples) > 0) * { * fft.forward(samples); * fft.FFT * * source.GetSpectrumData(samples, 0, FFTWindow.BlackmanHarris); * * * spectrum.CopyTo(lastSpectrum, 0); * samples.CopyTo(spectrum, 0); * * float flux = 0; * for (int i = 0; i < spectrum.Length; i++) * { * float value = (spectrum[i] - lastSpectrum[i]); * flux += value < 0 ? 0 : value; * } * spectralFlux.Add(flux); * } */ int currentIndex = 0;//index sample Debug.Log("audio length: " + audioSamples.Length); while (currentIndex < audioSamples.Length) { moveForwardSamples(currentIndex); currentIndex += precision; currentSamples = Hamming(currentSamples); fft.FFT(currentSamples, true); spectrum.CopyTo(lastSpectrum, 0); Array.Copy(currentSamples, 0, spectrum, 0, spectrum.Length); float flux = 0; for (int i = 0; i < spectrum.Length; i++) { //Debug.Log("spectrum " + spectrum[i]); float value = (float)(spectrum[i] - lastSpectrum[i]); flux += value < 0 ? 0 : value; } spectralFlux.Add(flux); //Debug.Log("flux " + flux); /* * for (int i = 1; i < spectrum.Length - 1; i++) * { * Debug.DrawLine(new Vector3(i - 1, (float) spectrum[i] + 10, 0), new Vector3(i, (float)spectrum[i + 1] + 10, 0), Color.red); * Debug.DrawLine(new Vector3(i - 1, Mathf.Log((float)spectrum[i - 1]) + 10, 2), new Vector3(i, Mathf.Log((float)spectrum[i]) + 10, 2), Color.cyan); * Debug.DrawLine(new Vector3(Mathf.Log(i - 1), (float)spectrum[i - 1] - 10, 1), new Vector3(Mathf.Log(i), (float)spectrum[i] - 10, 1), Color.green); * Debug.DrawLine(new Vector3(Mathf.Log(i - 1), Mathf.Log((float)spectrum[i - 1]), 3), new Vector3(Mathf.Log(i), Mathf.Log((float)spectrum[i]), 3), Color.blue); * } */ } for (int i = 0; i < spectralFlux.Count; i++) { int start = Mathf.Max(0, i - THRESHOLD_WINDOW_SIZE); int end = Mathf.Min(spectralFlux.Count - 1, i + THRESHOLD_WINDOW_SIZE); double mean = 0; for (int j = start; j <= end; j++) { mean += spectralFlux[j]; } mean /= (end - start); threshold.Add(mean * MULTIPLIER); } for (int i = 0; i < threshold.Count; i++) { if (threshold[i] <= spectralFlux[i]) { prunnedSpectralFlux.Add(spectralFlux[i] - threshold[i]); } else { prunnedSpectralFlux.Add((float)0); } } for (int i = 0; i < prunnedSpectralFlux.Count - 1; i++) { if (prunnedSpectralFlux[i] > prunnedSpectralFlux[i + 1]) { peaks.Add(prunnedSpectralFlux[i]); } else { peaks.Add((float)0); } } string showMe = ""; for (int i = 0; i < peaks.Count; i++) { float time; if (peaks[i] > 0) { time = i * ((float)precision / samplingRate); showMe += time + "/" + peaks[i] + " - "; } } Debug.Log(showMe); showMe = "Prunned : "; for (int i = 0; i < prunnedSpectralFlux.Count; i++) { showMe += prunnedSpectralFlux[i] + " - "; } Debug.Log(showMe); showMe = "threshold : "; for (int i = 0; i < threshold.Count; i++) { showMe += threshold[i] + " - "; } Debug.Log(showMe); }
public void FFT(bool forward) { data.CopyTo(copy, 0); fft.FFT(copy, forward); }