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);
    }
示例#2
0
    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);
    }
示例#3
0
        /// <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));
            }
        }
示例#4
0
        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);
        }
示例#5
0
        /// <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);
        }
示例#6
0
        /// <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);
        }
示例#7
0
        /// <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);
    }
示例#9
0
    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;
        }
    }
示例#10
0
    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();
    }
示例#11
0
    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);
    }
示例#12
0
        public void FFT(bool forward)
        {
            data.CopyTo(copy, 0);

            fft.FFT(copy, forward);
        }