Beispiel #1
0
 static void Diff(SubSequence <double> x, double[] result)
 {
     for (var i = x.Length - 2; i > -1; i--)
     {
         result[i] = x[i + 1] - x[i];
     }
 }
Beispiel #2
0
        static void Histc(SubSequence <double> x, SubSequence <double> edges, int[] index)
        {
            var count = 1;
            var i     = 0;

            for (; i < edges.Length; i++)
            {
                index[i] = 1;
                if (edges[i] >= x[0])
                {
                    break;
                }
            }
            for (; i < edges.Length; i++)
            {
                if (edges[i] < x[count])
                {
                    index[i] = count;
                }
                else
                {
                    index[i--] = count++;
                }
                if (count == x.Length)
                {
                    break;
                }
            }
            for (count--, i++; i < edges.Length; i++)
            {
                index[i] = count;
            }
        }
Beispiel #3
0
        public static void FFTShift(SubSequence <double> x, double[] result)
        {
            var halfPoint = x.Length / 2;

            for (var i = 0; i < halfPoint; i++)
            {
                result[i]             = x[i + halfPoint];
                result[i + halfPoint] = x[i];
            }
        }
Beispiel #4
0
        public static void Interp1Q(double x, double shift, SubSequence <double> y, SubSequence <double> xi, double[] yi)
        {
            var deltaY = new double[y.Length];

            Diff(y, deltaY);
            deltaY[y.Length - 1] = 0.0;

            for (var i = 0; i < xi.Length; i++)
            {
                var xiBase     = (int)((xi[i] - x) / shift);
                var xiFraction = (xi[i] - x) / shift - xiBase;
                yi[i] = y[xiBase] + deltaY[xiBase] * xiFraction;
            }
        }
Beispiel #5
0
        public static void Interp1(SubSequence <double> x, double[] y, SubSequence <double> xi, double[] yi)
        {
            var h = new double[x.Length - 1];

            for (var i = 0; i < h.Length; i++)
            {
                h[i] = x[i + 1] - x[i];
            }
            var k = new int[xi.Length];

            Histc(x, xi, k);

            for (var i = 0; i < xi.Length; i++)
            {
                var s = (xi[i] - x[k[i] - 1]) / h[k[i] - 1];
                yi[i] = y[k[i] - 1] + s * (y[k[i]] - y[k[i] - 1]);
            }
        }
Beispiel #6
0
 public SubSequence(SubSequence <T> array)
     : this(array, 0, array.Length)
 {
 }
Beispiel #7
0
 public SubSequence(SubSequence <T> array, int offset)
     : this(array, offset, Math.Max(array.Length - offset, 0))
 {
 }
Beispiel #8
0
 public SubSequence(SubSequence <T> a, int offset, int length)
 {
     Array  = a.Array;
     Offset = a.Offset + offset;
     Length = length;
 }
Beispiel #9
0
 public static SubSequence <T> SubSequence <T>(this SubSequence <T> array, int offset)
 {
     return(new SubSequence <T>(array, offset));
 }
Beispiel #10
0
        //-----------------------------------------------------------------------------
        // GetCoarseAperiodicity() calculates the aperiodicity in multiples of 3 kHz.
        // The upper limit is given based on the sampling frequency.
        //-----------------------------------------------------------------------------
        private void GetCoarseAperiodicity(double[] staticGroupDelay, int fs, int fftSize, int numberOfAperiodicities, double[] window, ForwardRealFFT forwardRealFFT, SubSequence <double> coarseAperiodicity)
        {
            var boundary         = MatlabFunctions.MatlabRound(fftSize * 8.0 / window.Length);
            var halfWindowLength = window.Length / 2;

            Array.Clear(forwardRealFFT.Waveform, 0, fftSize);

            var powerSpectrum = new double[fftSize / 2 + 1];

            for (var i = 0; i < numberOfAperiodicities; i++)
            {
                var center = (int)(FrequencyInterval * (i + 1) * fftSize / fs);
                for (int j = 0, limit = halfWindowLength * 2; j <= limit; j++)
                {
                    forwardRealFFT.Waveform[j] = staticGroupDelay[center - halfWindowLength + j] * window[j];
                }
                FFT.Execute(forwardRealFFT.ForwardFFT);

                var spectrum = forwardRealFFT.Spectrum;
                for (int j = 0, limit = fftSize / 2; j <= limit; j++)
                {
                    powerSpectrum[j] = spectrum[j].Real * spectrum[j].Real + spectrum[j].Imaginary * spectrum[j].Imaginary;
                }

                Array.Sort(powerSpectrum);
                for (int j = 1, limit = fftSize / 2; j <= limit; j++)
                {
                    powerSpectrum[j] += powerSpectrum[j - 1];
                }

                coarseAperiodicity[i] = 10.0 * Math.Log10(powerSpectrum[fftSize / 2 - boundary - 1] / powerSpectrum[fftSize / 2]);
            }
        }
Beispiel #11
0
        //-----------------------------------------------------------------------------
        // D4CGeneralBody() calculates a spectral envelope at a temporal
        // position. This function is only used in D4C().
        // Caution:
        //   forward_fft is allocated in advance to speed up the processing.
        //-----------------------------------------------------------------------------
        void D4CGeneralBody(double[] x, int fs, double currentF0, int fftSize, double currentPosition, int numberOfAperiodicities, double[] window, ForwardRealFFT forwardRealFFT, SubSequence <double> coarseAperiodicity)
        {
            var staticCentroid        = new double[fftSize / 2 + 1];
            var smoothedPowerSpectrum = new double[fftSize / 2 + 1];
            var staticGroupDelay      = new double[fftSize / 2 + 1];

            GetStaticCentroid(x, fs, currentF0, fftSize, currentPosition, forwardRealFFT, staticCentroid);
            GetSmoothedPowerSpectrum(x, fs, currentF0, fftSize, currentPosition, forwardRealFFT, smoothedPowerSpectrum);
            GetStaticGroupDelay(staticCentroid, smoothedPowerSpectrum, fs, currentF0, fftSize, staticGroupDelay);

            GetCoarseAperiodicity(staticGroupDelay, fs, fftSize, numberOfAperiodicities, window, forwardRealFFT, coarseAperiodicity);

            // Revision of the result based on the F0
            for (var i = 0; i < numberOfAperiodicities; i++)
            {
                coarseAperiodicity[i] = Math.Min(0.0, coarseAperiodicity[i] + (currentF0 - 100) / 50.0);
            }
        }