示例#1
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));
            }
        }
    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);
    }
示例#3
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);
        }
示例#4
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);
        }
示例#5
0
            public FFTThread(int w)
            {
                m_window = new FFTWindow(FFTWindowType.HANNING, w);
                m_w      = w;
                m_rin    = new double[m_w];
                m_rout   = new double[m_w];
                m_iout   = new double[m_w];
                //m_fft = new FFTReal(m_w);

                m_fft = new LomontFFT();
            }
示例#6
0
    void Awake()
    {
        if (AudioAnalyzer._instance != null)
        {
            Destroy(this);
        }
        _fft      = new LomontFFT();
        _instance = this;

        InitializeAnalyzer();
    }
示例#7
0
        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> * Create an FFT transformer for a given sample size. This preallocates
        /// * resources appropriate to that block size. A specified window
        /// * function will be applied to all input data.
        /// *  </summary>
        /// * <param name="size"> The number of samples in a block that we will
        /// *                      be asked to transform. Must be a power of 2. </param>
        /// * <param name="window"> Window function to apply to all input data.
        /// *                      Its block size must be the same as the size
        /// *                      parameter. </param>
        /// * <exception cref="IllegalArgumentException"> Invalid parameter. </exception>
        ///
        public FFTTransformer(int size, Window window)
        {
            if (!IsPowerOf2(size))
            {
                throw new System.ArgumentException("size for FFT must" + " be a power of 2 (was " + size + ")");
            }

            windowFunc  = window;
            transformer = new LomontFFT();
            blockSize   = size;

            // Allocate working data arrays.
            xre = new double[blockSize];
        }
 public NoteFinderFilter(int fftSize, double sampleRate, double cornerFrequency = 440.0)
 {
     _fftSize        = fftSize;
     _sampleRate     = sampleRate;
     _fftBufferTmp   = new double[_fftSize * 2];
     _hanWindow      = new HanWindow(_fftSize);
     _soFilter       = new SecondOrderLowPassFilter(_sampleRate, cornerFrequency);
     _frequencyNotes = new FrequencyNotes(_fftSize, _sampleRate);
     _fft            = new LomontFFT
     {
         A = 1,
         B = -1
     };
 }
示例#10
0
        public FFT(FFTWindowType windowType, int winSize)
        {
            this.winSize = winSize;
            this.fftSize = 2 * winSize;

            fftwData = fftwf_malloc(fftSize * sizeof(float));
            fftwPlan = fftwf_plan_r2r_1d(fftSize, fftwData, fftwData, FFTW_R2HC,
                                         FFTW_ESTIMATE | FFTW_DESTROY_INPUT);

            fft  = new float[fftSize];
            data = new float[fftSize];

            lomonFFT = new LomontFFT();
            win      = new FFTWindow(windowType, winSize);
        }
示例#11
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);
        }
示例#12
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);
    }
示例#14
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();
    }
示例#15
0
        /// <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);
        }
示例#16
0
 public AudioService()
 {
     lomonFFT = new Lomont.LomontFFT();
 }
示例#17
0
    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));
            }
        }
    }
示例#18
0
    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);
        }
    }