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);
            }
        }
Beispiel #6
0
        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);
        }