private static void SyncLookupTableLength(int length) { //Debug.Assert(length < 1024 * 10); //Debug.Assert(length >= 0); if (length > _lookupTabletLength) { int level = (int)Math.Ceiling(Math.Log(length, 2)); Fourier.InitializeReverseBits(level); Fourier.InitializeComplexRotations(level); //_cFFTData = new Complex[ Math2.CeilingBase( length, 2 ) ]; //_cFFTDataF = new ComplexF[ Math2.CeilingBase( length, 2 ) ]; _lookupTabletLength = length; } }
static private void ReorderArray(double[] data) { //Debug.Assert(data != null); int length = data.Length / 2; //Debug.Assert(Fourier.IsPowerOf2(length) == true); //Debug.Assert(length >= cMinLength); //Debug.Assert(length <= cMaxLength); int[] reversedBits = Fourier.GetReversedBits(Fourier.Log2(length)); for (int i = 0; i < length; i++) { int swap = reversedBits[i]; if (swap > i) { Fourier.Swap(ref data[i << 1], ref data[swap << 1]); Fourier.Swap(ref data[i << 1 + 1], ref data[swap << 1 + 1]); } } }
static private int[] GetReversedBits(int numberOfBits) { //Debug.Assert(numberOfBits >= cMinBits); //Debug.Assert(numberOfBits <= cMaxBits); if (_reversedBits[numberOfBits - 1] == null) { long maxBits = Fourier.Pow2(numberOfBits); int[] reversedBits = new int[maxBits]; for (int i = 0; i < maxBits; i++) { int oldBits = i; int newBits = 0; for (int j = 0; j < numberOfBits; j++) { newBits = (newBits << 1) | (oldBits & 1); oldBits = (oldBits >> 1); } reversedBits[i] = newBits; } _reversedBits[numberOfBits - 1] = reversedBits; } return(_reversedBits[numberOfBits - 1]); }
public void scramble() { //Create necessary variables List <short> rawWavData = backend.WAVdata; //get the data dump of wav file int sampleRateWav = backend.sampleRate; //get samplerate of wav file List <float[]> dataPerNote = convertRawData(rawWavData, sampleRateWav); //convert dump into split arrays //foreach sample do: a Forward FFT, Flip the values, Backwards FFT foreach (float[] noteSamples in dataPerNote) { //Forward FFT Fourier.RFFT(noteSamples, FourierDirection.Forward); //Flip the values, (in pairs Real and Imaginary) float[] temporary = new float[noteSamples.Length]; for (int i = 0; i < noteSamples.Length; i += 2) { temporary[i] = noteSamples[noteSamples.Length - 2 - i]; temporary[i + 1] = noteSamples[noteSamples.Length - 1 - i]; } Array.Copy(temporary, noteSamples, noteSamples.Length); //Forward FFT and Compensate for distortion due to Fourier Transformation Fourier.RFFT(noteSamples, FourierDirection.Backward); for (int i = 0; i < noteSamples.Length; i++) { noteSamples[i] /= noteSamples.Length / 2; noteSamples[i] = (float)Math.Round(noteSamples[i]); } } //Pass on new Wav file Data List <short> newWavData = convertNewData(dataPerNote); //convert split arrays back to dump backend.newWavData(newWavData, rawWavData); //Send to backend }
/// <summary> /// Compute a 1D real-symmetric fast fourier transform. /// </summary> /// <param name="data"></param> /// <param name="length"></param> /// <param name="direction"></param> public static void RFFT(float[] data, int length, FourierDirection direction) { if (data == null) { throw new ArgumentNullException("data"); } if (data.Length < length) { throw new ArgumentOutOfRangeException("length", length, "must be at least as large as 'data.Length' parameter"); } if (Fourier.IsPowerOf2(length) == false) { throw new ArgumentOutOfRangeException("length", length, "must be a power of 2"); } float c1 = 0.5f, c2; float theta = (float)Math.PI / (length / 2); if (direction == FourierDirection.Forward) { c2 = -0.5f; FFT(data, length / 2, direction); } else { c2 = 0.5f; theta = -theta; } float wtemp = (float)Math.Sin(0.5 * theta); float wpr = -2 * wtemp * wtemp; float wpi = (float)Math.Sin(theta); float wr = 1 + wpr; float wi = wpi; // do / undo packing for (int i = 1; i < length / 4; i++) { int a = 2 * i; int b = length - 2 * i; float h1r = c1 * (data[a] + data[b]); float h1i = c1 * (data[a + 1] - data[b + 1]); float h2r = -c2 * (data[a + 1] + data[b + 1]); float h2i = c2 * (data[a] - data[b]); data[a] = h1r + wr * h2r - wi * h2i; data[a + 1] = h1i + wr * h2i + wi * h2r; data[b] = h1r - wr * h2r + wi * h2i; data[b + 1] = -h1i + wr * h2i + wi * h2r; wr = (wtemp = wr) * wpr - wi * wpi + wr; wi = wi * wpr + wtemp * wpi + wi; } if (direction == FourierDirection.Forward) { float hir = data[0]; data[0] = hir + data[1]; data[1] = hir - data[1]; } else { float hir = data[0]; data[0] = c1 * (hir + data[1]); data[1] = c1 * (hir - data[1]); Fourier.FFT(data, length / 2, direction); } }
public string convert(int ms, bool roundIt, bool returnUnfound, bool seperatorIsComma) { //read csv file for tones Dictionary backend.setSeperator(seperatorIsComma); Dictionary <char, double> tonesDictionary = backend.csvDictionary; //Read the wav file for usefull values and comunicate with data layer List <short> rawWavData = backend.WAVdata; int sampleRateWav = backend.sampleRate; int notes = ((rawWavData.Count * 1000) / sampleRateWav) / ms; //aantal tonen in Wav //converteer de rawData naar floats per toon List <float[]> dataPerNote = convertRawData(rawWavData, sampleRateWav, notes); //RFFT toepassen en dominante frequencie zoeken List <double> frequencyList = new List <double>(); foreach (float[] noteSamples in dataPerNote) { //fourier Fourier.RFFT(noteSamples, FourierDirection.Forward); //zoek freq double maxAmplitude = 0; int positie = 0; for (int i = 0; i < noteSamples.Length; i += 2)//max en pos bepalen { double vermogen = Math.Sqrt((Math.Pow(noteSamples[i], 2)) + Math.Pow(noteSamples[i + 1], 2)); if (vermogen > maxAmplitude) { positie = i; maxAmplitude = vermogen; } } double frequency = ((positie * sampleRateWav) / (double)noteSamples.Length) / 2;//what is the frequency //(afronden) en toevoegen if (roundIt) { frequencyList.Add((Math.Round(frequency * roundPrecision) / roundPrecision)); } else { frequencyList.Add(frequency); } } //create return String string returnable = ""; foreach (double frequency in frequencyList) { //als nog niet afgerond double _frequency = frequency; if (!roundIt) { _frequency = Math.Round(frequency, roundDecimals); } if (tonesDictionary.FirstOrDefault(x => x.Value == _frequency).Key == 0)//default waarde = ongevonden { if (!returnUnfound) { returnable += "? "; } else { returnable += String.Format("?\"{0}Hz\" ", _frequency); } } else { returnable += tonesDictionary.FirstOrDefault(x => x.Value == _frequency).Key + " "; } } return(returnable); }