using Microsoft.Xna.Framework; using NAudio.Dsp; using NAudio.Wave; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace RhythmBullet.Audio { public class TransparentSampleProvider : ISampleProvider { private const int FFT_SIZE = 2048; private readonly int m; private ISampleProvider source; private Complex[] fftBuffer; private volatile bool updatedSpectrum; private readonly float[] currentSpectrum; private int channelCount; public bool performFFT; public TransparentSampleProvider(ISampleProvider sampleProvider) { m = (int)Math.Log(FFT_SIZE); source = sampleProvider; channelCount = sampleProvider.WaveFormat.Channels; fftBuffer = new Complex[FFT_SIZE]; currentSpectrum = new float[FFT_SIZE]; } public WaveFormat WaveFormat { get { return source.WaveFormat; } } public float[] GetCurrentSpectrum() { if (updatedSpectrum) { lock (fftBuffer) { for (int binID = 0; binID < currentSpectrum.Length; binID++) { currentSpectrum[binID] = fftBuffer[binID].X; } } } return currentSpectrum; } public int Read(float[] buffer, int offset, int count) { int sampleCount = source.Read(buffer, offset, count); if (performFFT) { int fftOffset = 0; for (int s = 0; s < sampleCount; s += channelCount) { if (s >= FFT_SIZE) { lock (fftBuffer) { FastFourierTransform.FFT(true, m, fftBuffer); } updatedSpectrum = true; fftOffset -= FFT_SIZE; } float greatestVal = 0; for (int c = 0; c < channelCount; c++) { greatestVal = MathHelper.Max(buffer[s + offset + c], greatestVal); } fftBuffer[s + fftOffset].X = (float)(buffer[s + offset] * FastFourierTransform.HammingWindow(s, FFT_SIZE)); fftBuffer[s + fftOffset].Y = 0; } } return sampleCount; } } }