public void ComputeMatrixUsingLomontRealFFT(ref Matrix m, int column, float[] audiodata, int pos) { // apply the window method (e.g HammingWindow, HannWindow etc) win.Apply(ref data, audiodata, pos); var fft = new double[data.Length / 2]; Array.Copy(data, fft, data.Length / 2); lomonFFT.RealFFT(fft, true); // fft input will now contain the FFT values // r0, r(n/2), r1, i1, r2, i2 ... m.MatrixData[0][column] = Math.Sqrt(fft[0] * fft[0] * winSize); m.MatrixData[winSize / 2 - 1][column] = Math.Sqrt(fft[1] * fft[1] * winSize); for (int row = 1; row < winSize / 2; row++) { // amplitude (or magnitude) is the square root of the power spectrum // the magnitude spectrum is abs(fft), i.e. Math.Sqrt(re*re + img*img) // use 20*log10(Y) to get dB from amplitude // the power spectrum is the magnitude spectrum squared // use 10*log10(Y) to get dB from power spectrum m.MatrixData[row][column] = Math.Sqrt((fft[2 * row] * fft[2 * row] + fft[2 * row + 1] * fft[2 * row + 1]) * winSize); } }
public void SineWaveTest() { var sineWave = new[] { 0, 0.707f, 1, 0.707f, 0, -0.707f, -1, -0.707f }; lomontFFT.RealFFT(sineWave, true); lomontFFT.RealFFT(sineWave, false); CollectionAssert.AreEqual(new float[] { 0, 0.707f, 1, 0.707f, 0, -0.707f, -1, -0.707f }, sineWave, floatComparer); }
public double[] Spectrum(double[] input, bool scale) { var fft = new LomontFFT(); fft.RealFFT(input, true); var spectrum = Helper.ComputeSpectrum(input); fft.RealFFT(input, false); return(spectrum); }
/// <summary> /// Transforms time domain samples to the frequency domain. /// </summary> /// <param name="timeDomainSamples">The time domain samples.</param> /// <returns>The frequency domain samples.</returns> public SampleSequence TransformForward(SampleSequence timeDomainSamples) { var fftValues = timeDomainSamples.Values.ToArray(); var sampleRate = timeDomainSamples.SampleRate; // FFT frequency resolution is (sample rate) / (FFT window size). var frequencyResolution = sampleRate / fftValues.Length; _fft.RealFFT(fftValues, true); // fftValues is modified in place var amplitudes = ComputeAmplitudes(fftValues).ToArray(); return(new SampleSequence(frequencyResolution, amplitudes)); }
public void SineWaveTest() { var sineWave = new[] { 0, 0.707f, 1, 0.707f, 0, -0.707f, -1, -0.707f }; unsafe { float *input = stackalloc float[sineWave.Length]; for (int i = 0; i < sineWave.Length; ++i) { input[i] = sineWave[i]; } lomontFFT.RealFFT(input, true, sineWave.Length); lomontFFT.RealFFT(input, false, sineWave.Length); for (int i = 0; i < sineWave.Length; ++i) { sineWave[i] = input[i]; } } CollectionAssert.AreEqual(new float[] { 0, 0.707f, 1, 0.707f, 0, -0.707f, -1, -0.707f }, sineWave, floatComparer); }
public override void Pull(int count) { var real = FFFTDataReal.Value; var imag = FFFTDataImag.Value; var copyCount = Math.Min(count / 2, Math.Max(real.Length, imag.Length)); var j = 0; if (real.Length > imag.Length) { for (int i = 0; i < copyCount; i++) { RealImagData[j++] = real[i]; RealImagData[j++] = imag[AudioUtils.Zmod(i, imag.Length)]; } } else if (real.Length == imag.Length) { for (int i = 0; i < copyCount; i++) { RealImagData[j++] = real[i]; RealImagData[j++] = imag[i]; } } else { for (int i = 0; i < copyCount; i++) { RealImagData[j++] = real[AudioUtils.Zmod(i, real.Length)]; RealImagData[j++] = imag[i]; } } if (copyCount < count / 2) { for (int i = copyCount; i < count / 2; i++) { RealImagData[j++] = 0; RealImagData[j++] = 0; } } FFFT.RealFFT(RealImagData, false); //RealImagData[0] = RealImagData[1]; TimeDomain.WriteDoubleWindowed(RealImagData, Window, 0, count, Gain); Write(TimeDomain, 0, count); }
public static float[] GetSpectrum(float[] samples) { if (mono.Length != samples.Length / 2) { mono = new float[samples.Length / 2]; } for (int i = 0; i < mono.Length; i++) { float monoSample = (samples[i * 2] + samples[i * 2 + 1]) * .5f; mono[i] = monoSample * 1.4f; } fft.RealFFT(mono, true); return(SpectrumMagnitude(mono)); }
public void PerformTask() { // perform the fft for each of the chosen window sizes // m_maxwid = 2048 (8192) // m_w = 512, 1024, 2048 (1024, 2048, 4096, 8192) for (int i = 0; i < m_maxwid / m_w; ++i) { int origin = m_maxwid / 4 - m_w / 4; // for 50% overlap for (int j = 0; j < m_w; ++j) { int index = origin + i * m_w / 2 + j; if (index > m_in.Length - 1) { break; } m_rin[j] = m_in[index]; } // perform windowing m_window.Apply(m_rin); var fft = new double[m_rin.Length]; Array.Copy(m_rin, fft, m_rin.Length); m_fft.RealFFT(fft, true); // fft input will now contain the FFT values // r0, r(n/2), r1, i1, r2, i2 ... // Include Nyquist but not DC //m_s.spectrograms[m_res].data[i][0] = Math.Sqrt(fft[0] * fft[0]) / (m_w/2); // DC m_s.spectrograms[m_res].data[i][m_w / 2 - 1] = Math.Sqrt(fft[1] * fft[1]) / (m_w / 2); // Nyquist for (int j = 1; j < m_w / 2; ++j) { double mag = Math.Sqrt(fft[2 * j] * fft[2 * j] + fft[2 * j + 1] * fft[2 * j + 1]); double scaled = mag / (m_w / 2); m_s.spectrograms[m_res].data[i][j] = scaled; } } }
private void CalculateFourierTransform() { PowerSpectra = new List <double>(); int len = Data.Count(); len = (int)Math.Pow(2, Math.Floor(Math.Log((double)len, 2)) + 1); List <double> D = Data.ToList(); while (D.Count() < len) { D.Add(0); } double[] dat = D.ToArray(); fft.RealFFT(dat, true); PowerSpectra.Add(dat[0] * dat[0]); for (int i = 2; i < dat.Length; i += 2) { PowerSpectra.Add(dat[i] * dat[i] + dat[i + 1] * dat[i + 1]); } PowerSpectra.Add(dat[1] * dat[1]); }
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; } }
protected override void FillBuffer(float[] buffer, int offset, int count) { if (InputSignal.Value != null) { InputSignal.Read(buffer, offset, count); //write to buffer FRingBuffer.Write(buffer, offset, count); //calc fft var fftSize = FRingBuffer.Size; if (FFFTBuffer.Length != fftSize) { FFFTBuffer = new double[fftSize]; FFTOut = new double[fftSize]; FWindow = AudioUtils.CreateWindowDouble(fftSize, WindowFunc); } FRingBuffer.ReadDoubleWindowed(FFFTBuffer, FWindow, 0, fftSize); FFFT.RealFFT(FFFTBuffer, true); Array.Copy(FFFTBuffer, FFTOut, fftSize); } }
/// <summary> /// Performs the FFT on the provided samples. /// Will bin channels internally /// </summary> /// <returns>The FF.</returns> /// <param name="dAudioSamples">D audio samples.</param> /// <param name="fftType">Fft type.</param> /// <param name="forwardFFT">If set to <c>true</c> forward FF.</param> public double[] GetFFTOutputBins(ref double[] dAudioSamples, int fftType = 1, bool forwardFFT = true, bool applyHannWindowing = true) { if (!IsInitialized) { return(null); } if (_fftScript == null) { _fftScript = new LomontFFT(); _fftScript.A = 1; _fftScript.B = -1; } if (_fftBinsOutput == null || _fftBinsOutput.Length != FFTBinCount) { _fftBinsOutput = new double[FFTBinCount]; _fftBinsActual = new double[_fftBinsOutput.Length / ChannelCount]; } System.Array.Clear(_fftBinsOutput, 0, _fftBinsOutput.Length); for (int sampleIndex = 0; sampleIndex < _dAudioSamples.Length; sampleIndex += ChannelCount) { for (int channelIndex = 0; channelIndex < ChannelCount; ++channelIndex) { int binIndex = sampleIndex == 0 ? 0 : sampleIndex / ChannelCount; double valToAdd = Mathf.Pow((float)_dAudioSamples [sampleIndex + channelIndex], 4); //double valToAdd = _dAudioSamples [sampleIndex + channelIndex]; _fftBinsOutput [binIndex] += _dAudioSamples [sampleIndex + channelIndex]; } } for (int i = 0; i < _fftBinsOutput.Length; ++i) { _fftBinsOutput [i] /= ChannelCount; } //apply hanning window if (applyHannWindowing) { Utilities.Hann(ref _fftBinsOutput); } switch (fftType) { case 0: { Debug.LogWarning("COMPLEXFFT NOT SUPPORTED YET"); //_fftScript.FFT (_fftBinsOutput, forwardFFT); } break; case 1: { _fftScript.RealFFT(ref _fftBinsOutput, forwardFFT); _fftBinsOutput [0] = 0; _fftBinsOutput [1] = 0; for (int i = 2; i < _fftBinsOutput.Length; i += 2) { float real = (float)_fftBinsOutput [i]; float im = (float)_fftBinsOutput [i + 1]; float val = Mathf.Sqrt(Mathf.Pow(real, 2) + Mathf.Pow(im, 2)); if (i == 2) { _fftBinsActual [0] = val; } else { _fftBinsActual [(i / 2) - 1] = val; } } } break; case 2: { Debug.LogWarning("TABLEFFT NOT SUPPORTED YET"); //_fftScript.TableFFT (_fftBinsOutput, forwardFFT); } break; } return(_fftBinsActual); }
public static void GetSpectrum(float[] samples) { fft.RealFFT(samples, true); }
void saveFile() { float[] samples = new float[4096]; //aud.GetOutputData (samples, 0); aud.clip.GetData(samples, Microphone.GetPosition(Microphone.devices[0]) - 4096); float maxAmp = (float)samples.Max() * 2; if (maxAmp > 0.001f) { LomontFFT fftMe = new LomontFFT(); double[] sampleFFT = Array.ConvertAll(samples, x => (double)x); fftMe.RealFFT(sampleFFT, true); float[] frequences = new float[5]; frequences[0] = (float)sampleFFT.Take(25).Max(); frequences[1] = (float)sampleFFT.Skip(25).Take(50).Max(); frequences[2] = (float)sampleFFT.Skip(75).Take(75).Max(); frequences[3] = (float)sampleFFT.Skip(150).Take(100).Max(); frequences[4] = (float)sampleFFT.Skip(250).Take(125).Max(); float maxFreq = frequences.Max(); int maxFreqIndex = frequences.ToList().IndexOf(maxFreq); if (maxFreqIndex == 0) { //float noise = (UnityEngine.Random.value - 0.5f) / 5f; float noise = 0f; makeOrb(maxFreq, new Vector3(22 + noise, -5, 20)); makeOrb(maxFreq, new Vector3(-22 + noise, -5, 20)); } if (maxFreqIndex == 1) { //float noise = (UnityEngine.Random.value - 0.5f) / 5f; float noise = 0f; makeOrb(maxFreq, new Vector3(20 + noise, -2, 20)); makeOrb(maxFreq, new Vector3(-20 + noise, -2, 20)); //makeOrb (maxFreq, new Vector3 (-35+ noise, -1, -15)); //makeOrb (maxFreq, new Vector3 (35+ noise, -1, -15)); } if (maxFreqIndex == 2) { //float noise = (UnityEngine.Random.value - 0.5f) / 5f; float noise = 0f; makeOrb(maxFreq, new Vector3(15 + noise, 3, 20)); makeOrb(maxFreq, new Vector3(-15 + noise, 3, 20)); //makeOrb(maxFreq,new Vector3(-25+ noise,0,-25)); //makeOrb(maxFreq,new Vector3(25+ noise,0,-25)); } if (maxFreqIndex == 3) { //float noise = (UnityEngine.Random.value - 0.5f) / 5f; float noise = 0f; makeOrb(maxFreq, new Vector3(10 + noise, 7, 25)); makeOrb(maxFreq, new Vector3(-10 + noise, 7, 25)); //makeOrb (maxFreq, new Vector3 (-15+ noise, 1, -35)); //makeOrb (maxFreq, new Vector3 (15+ noise, 1, -35)); } if (maxFreqIndex == 4) { //float noise = (UnityEngine.Random.value - 0.5f) / 5f; float noise = 0f; makeOrb(maxFreq, new Vector3(0 + noise, 10, 30)); //makeOrb (maxFreq, new Vector3 (0+ noise, 2, -45)); } } }
public void UpdatePLP(ref double[] dAudioSamples, int channelCount, int sampleRate, bool applyHannWindow = true) { if (dAudioSamples == null) { return; } if (_fftScript == null) { _fftScript = new LomontFFT(); _fftScript.A = 1; _fftScript.B = -1; } System.Array.Clear(_fftBinsRaw, 0, _fftBinsRaw.Length); System.Array.Clear(_fftBinsActual, 0, _fftBinsActual.Length); //channel bin the data for (int sampleIndex = 0; sampleIndex < dAudioSamples.Length; sampleIndex += channelCount) { int binIndex = sampleIndex == 0 ? 0 : sampleIndex / channelCount; for (int channelIndex = 0; channelIndex < channelCount; ++channelIndex) { _fftBinsRaw [binIndex] = dAudioSamples [sampleIndex + channelIndex]; } _fftBinsRaw [binIndex] /= channelCount; } //apply hanning window on audio samples if (applyHannWindow) { Utilities.Hann(ref _fftBinsRaw); } //perform fft. _fftScript.RealFFT(ref _fftBinsRaw, true); //aggregate fft output into fftActual for (int i = 2; i < _fftBinsRaw.Length; i += 2) { float real = (float)_fftBinsRaw [i]; float im = (float)_fftBinsRaw [i + 1]; float val = Mathf.Sqrt(Mathf.Pow(real, 2) + Mathf.Pow(im, 2)); if (i == 2) { _fftBinsActual [0] = val; } else { _fftBinsActual [(i / 2) - 1] = val; } } //left shift the spectrogram for (int i = 1; i < _spectrogram.Length; ++i) { LeftShiftArray <float> (ref _spectrogram [i]); /*for (int j = 0; j < _spectrogram [i - 1].Length; ++j) { * _spectrogram [i - 1][j] = _spectrogram [i][j]; * }*/ } //apply logarithmic compression and fill in place float[] toFill = _spectrogram [_spectrogram.Length - 1]; for (int i = 0; i < toFill.Length; ++i) { toFill [i] = _fftBinsActual [i]; //Mathf.Log ((float)(1+_fftBinsActual [i])); } //compute discrete derivative if (_frameIndex > 0) { float[] prev = _frameIndex > _spectrogram.Length - 1? _spectrogram[_spectrogram.Length - 2]:_spectrogram [_frameIndex - 1]; float[] curr = _frameIndex > _spectrogram.Length - 1 ? _spectrogram [_spectrogram.Length - 1] : _spectrogram [_frameIndex]; for (int i = 0; i < curr.Length; ++i) { float diff = curr[i] - prev[i]; if (diff > 0) { curr[i] = diff; } else { curr[i] = 0; } } } ++_frameIndex; if (_frameIndex > _spectrogram.Length) { bool firstRun = _frameIndex == _spectrogram.Length + 1; ComputeNoveltyCurve(firstRun); ComputeTempogram(false, firstRun); UpdateBPM(); ComputePeriodicLocalPulse(firstRun); //CorrelateNoveltyCurveWithSinCurve (); LeftShiftArray <double> (ref _noveltyCurve); //LeftShiftArray<double> (ref _tempogramActual); for (int i = 1; i < _tempogramActual.Length; ++i) { LeftShiftArray <double> (ref _tempogramActual[i]); } LeftShiftArray <double> (ref _tempo); LeftShiftArray <double> (ref _tempoMaxCoeff); LeftShiftArray <double> (ref _plpCurve); } }
public void FFT(bool forward) { data.CopyTo(copy, 0); fft.RealFFT(copy, forward); }