示例#1
0
        /// <summary>
        /// Finds fundamental frequency: calculates spectrogram, finds peaks, analyzes
        /// and refines frequency by diff sample values.
        /// </summary>
        /// <param name="x">The sounds samples data</param>
        /// <param name="sampleRate">The sound sample rate</param>
        /// <param name="minFreq">The min useful frequency</param>
        /// <param name="maxFreq">The max useful frequency</param>
        /// <returns>Found frequency, 0 - otherwise</returns>
        internal static double FindFundamentalFrequency(double[] x, int sampleRate, double minFreq, double maxFreq)
        {
            double[] spectr = FftAlgorithm.Calculate(x);

            int usefullMinSpectr = Math.Max(0,
                                            (int)(minFreq * spectr.Length / sampleRate));
            int usefullMaxSpectr = Math.Min(spectr.Length,
                                            (int)(maxFreq * spectr.Length / sampleRate) + 1);

            // find peaks in the FFT frequency bins
            const int PeaksCount = 5;

            int[] peakIndices;
            peakIndices = FindPeaks(spectr, usefullMinSpectr, usefullMaxSpectr - usefullMinSpectr,
                                    PeaksCount);

            if (Array.IndexOf(peakIndices, usefullMinSpectr) >= 0)
            {
                // lowest usefull frequency bin shows active
                // looks like is no detectable sound, return 0
                return(0);
            }

            // select fragment to check peak values: data offset
            const int verifyFragmentOffset = 0;
            // ... and half length of data
            int verifyFragmentLength = (int)(sampleRate / minFreq);

            // trying all peaks to find one with smaller difference value
            double minPeakValue       = Double.PositiveInfinity;
            int    minPeakIndex       = 0;
            int    minOptimalInterval = 0;

            for (int i = 0; i < peakIndices.Length; i++)
            {
                int    index = peakIndices[i];
                int    binIntervalStart = spectr.Length / (index + 1), binIntervalEnd = spectr.Length / index;
                int    interval;
                double peakValue;
                // scan bins frequencies/intervals
                ScanSignalIntervals(x, verifyFragmentOffset, verifyFragmentLength,
                                    binIntervalStart, binIntervalEnd, out interval, out peakValue);

                if (peakValue < minPeakValue)
                {
                    minPeakValue       = peakValue;
                    minPeakIndex       = index;
                    minOptimalInterval = interval;
                }
            }

            return((double)sampleRate / minOptimalInterval);
        }
        // Находим фундаментальную частоту: вычисляем спектрограмму, находим пики, анализируем
        //х - звуковые сэмплы
        //sampleRate частота семплирования
        //minFreq минимальная полезная частота
        //maxFreq максимальная полезная частота
        //returns Найденная частота, 0 - в противном случае

        internal static double FindFundamentalFrequency(double[] x, int sampleRate, double minFreq, double maxFreq)
        {
            double[] spectr = FftAlgorithm.Calculate(x);

            int usefullMinSpectr = Math.Max(0,
                                            (int)(minFreq * spectr.Length / sampleRate));
            int usefullMaxSpectr = Math.Min(spectr.Length,
                                            (int)(maxFreq * spectr.Length / sampleRate) + 1);

            // находим пики частот по БПФ
            const int PeaksCount = 5;

            int[] peakIndices;
            peakIndices = FindPeaks(spectr, usefullMinSpectr, usefullMaxSpectr - usefullMinSpectr,
                                    PeaksCount);

            if (Array.IndexOf(peakIndices, usefullMinSpectr) >= 0)
            {
                //
                // если звука не будет - вернет 0
                return(0);
            }

            // выбирает фрагмент для регистрации пиковых значений: смещение данных
            const int verifyFragmentOffset = 0;
            // ... и половина длины данных
            int verifyFragmentLength = (int)(sampleRate / minFreq);

            // перебираем все пики для поиска одного с наименьшим отличием от других
            double minPeakValue       = Double.PositiveInfinity;
            int    minPeakIndex       = 0;
            int    minOptimalInterval = 0;

            for (int i = 0; i < peakIndices.Length; i++)
            {
                int    index = peakIndices[i];
                int    binIntervalStart = spectr.Length / (index + 1), binIntervalEnd = spectr.Length / index;
                int    interval;
                double peakValue;
                // сканирование частот/интервалов
                ScanSignalIntervals(x, verifyFragmentOffset, verifyFragmentLength,
                                    binIntervalStart, binIntervalEnd, out interval, out peakValue);

                if (peakValue < minPeakValue)
                {
                    minPeakValue       = peakValue;
                    minPeakIndex       = index;
                    minOptimalInterval = interval;
                }
            }

            return((double)sampleRate / minOptimalInterval);
        }
示例#3
0
            protected override void ProcessData(short[] data)
            {
                foreach (short[] portion in windowBuffer.Process(data))
                {
                    for (int i = 0; i < buffer.Length; i++)
                    {
                        buffer[i] = portion[i];
                    }

                    double[] spectr = FftAlgorithm.Calculate(buffer);

                    owner.OnSpectrographData(new SpectrographDataEventArgs(spectr));
                }
            }