/*
         * Calcule la transformée de fourrier du signal audio
         * C'est un calcul nécessaire pour pouvoir calculer les critères fréquenciels
         */
        public void calculerFFT()
        {
            int tailleFenetre = (int)(_Fe * _fenetre);
            int N             = _signal.Length / tailleFenetre;

            _fft = new double[N][];

            for (int i = 0; i < N; i++)
            {
                _fft[i] = Traitements.FFT(_signal, i * tailleFenetre, tailleFenetre);
            }
        }
        public double[] Centroid()
        {
            int tailleFenetre = (int)(_Fe * _fenetre);
            int N             = _signal.Length / tailleFenetre;

            double[] res = new double[N];

            for (int i = 0; i < N; i++)
            {
                res[i] = Traitements.Centroid(_fft[i], (int)_Fe);
            }

            return(res);
        }
        /*
         * Calcule le Zero Crossing Rate pour chaque fenetre
         */
        public double[] ZCR()
        {
            int tailleFenetre = (int)(_Fe * _fenetre);
            int N             = _signal.Length / tailleFenetre;

            double[] res = new double[N];

            for (int i = 0; i < N; i++)
            {
                res[i] = Traitements.ZRC(_signal, i * tailleFenetre, tailleFenetre);
            }

            return(res);
        }
        public double[] Rollof(double gama)
        {
            int tailleFenetre = (int)(_Fe * _fenetre);
            int N             = _signal.Length / tailleFenetre;

            double[] res = new double[N];

            for (int i = 0; i < N; i++)
            {
                res[i] = Traitements.RollOff(_fft[i], gama, (int)_Fe);
            }

            return(res);
        }
        /*
         * Calcule le Root Mean Square du signal audio
         * Les données sont normalisée entre 0 et 1
         */
        public double[] RMS()
        {
            int tailleFenetre = (int)(_Fe * _fenetre);
            int N             = _signal.Length / tailleFenetre;

            double[] res = new double[N];

            for (int i = 0; i < N; i++)
            {
                res[i] = Traitements.RMS(_signal, i * tailleFenetre, tailleFenetre);
            }

            Stats.normalise(ref res);

            return(res);
        }
        /*
         * Calcule "l'écart type de fréquence" pour une transformée de fourrier donnée
         * Il est possible de donner la Centroid si elle a déjà été calculée
         */
        public static double Spread(double[] fft, int Fe, double centroid = double.NegativeInfinity)
        {
            if (centroid == double.NegativeInfinity)
            {
                centroid = Traitements.Centroid(fft, Fe);
            }

            double somme         = 0.0;
            double sommePonderee = 0.0;

            for (int i = 0; i < fft.Length; i++)
            {
                double m = (double)Fe / (2 * fft.Length) * i;
                somme         += fft[i];
                sommePonderee += fft[i] * (m - centroid) * (m - centroid);
            }

            return(somme == 0 ? 0 : Math.Sqrt(sommePonderee / somme));
        }
        public double[] Spread(double[] centroid = null)
        {
            int tailleFenetre = (int)(_Fe * _fenetre);
            int N             = _signal.Length / tailleFenetre;

            double[] res = new double[N];

            for (int i = 0; i < N; i++)
            {
                if (centroid != null)
                {
                    res[i] = Traitements.Spread(_fft[i], (int)_Fe, centroid[i]);
                }
                else
                {
                    res[i] = Traitements.Spread(_fft[i], (int)_Fe);
                }
            }

            return(res);
        }