Пример #1
0
    private void ProcessFullSpectrum()
    {
        //Prepare audio samples
        float[] preProcessedSamples = new float[totalSamples];

        int   numProcessed           = 0;
        float combinedChannelAverage = 0f;

        //Combine channels if the audio is stereo
        //Add to pre-processed array to be passed through the fft
        for (int i = 0; i < multiChannelSamples.Length; i++)
        {
            combinedChannelAverage += multiChannelSamples[i];

            //Store the average of the channels combined for a single time index
            if ((i + 1) % this.numberOfChannels == 0)
            {
                preProcessedSamples[numProcessed] = combinedChannelAverage / numberOfChannels;
                numProcessed++;
                combinedChannelAverage = 0f;
            }
        }

        //Execute an FFT to return the spectrum data over the time domain
        int totalIterations = preProcessedSamples.Length / spectrumSampleSize;

        //Instantiate and initialise a new FFT
        FFT fft = new FFT();

        fft.Initialize((uint)spectrumSampleSize);

        double[] sampleChunk = new double[spectrumSampleSize];
        for (int i = 0; i < totalIterations; i++)
        {
            //Get the current chunk of audio sample data
            Array.Copy(preProcessedSamples, i * spectrumSampleSize, sampleChunk, 0, spectrumSampleSize);

            //Apply an FFT Window type to the input data and calculate a scale factor
            double[] windowCoefficients  = DSP.Window.Coefficients(DSP.Window.Type.Hanning, (uint)spectrumSampleSize);
            double[] scaledSpectrumChunk = DSP.Math.Multiply(sampleChunk, windowCoefficients);
            double   scaleFactor         = DSP.Window.ScaleFactor.Signal(windowCoefficients);

            //Execute the FFT and get the scaled spectrum back
            Complex[] fftSpectrum = fft.Execute(scaledSpectrumChunk);
            //Convert the complex spectrum into a usable format of doubles
            double[] scaledFFTSpectrum = DSP.ConvertComplex.ToMagnitude(fftSpectrum);
            //Apply the window scale to the spectrum
            scaledFFTSpectrum = DSP.Math.Multiply(scaledFFTSpectrum, scaleFactor);


            //The magnitude values correspond to a single point in time
            float currentSongTime = GetTimeFromIndex(i) * spectrumSampleSize;

            //Send magnitude spectrum data to Spectral Flux Analyzer to be analyzed for peaks
            analyzer.AnalyzeSpectrum(Array.ConvertAll(scaledFFTSpectrum, x => (float)x), currentSongTime);
        }

        Debug.Log("Spectrum Analysis done");
    }
Пример #2
0
    private void AnalyzeFullSpectrum()
    {
        try
        {
            //We only retain the samples of combined channel over the time domain
            float[] processedSamples = new float[totalNumberOfSamples];

            int   numProcessed   = 0;
            float channelAverage = 0f;

            for (int i = 0; i < multiChannelSamples.Length; ++i)
            {
                channelAverage += multiChannelSamples[i];

                //Store the average of the combined channels
                if ((i + 1) % numberOfChannels == 0)
                {
                    processedSamples[numProcessed] = channelAverage / numberOfChannels;
                    ++numProcessed;
                    channelAverage = 0f;
                }
            }

            //Debug.Log("Channel combining done. Total number of samples processed: " + processedSamples.Length);

            //Execute Fast-Fourier Transform to return the spectrum data over time
            int spectrumSampleSize = 1024;
            int iterations         = processedSamples.Length / spectrumSampleSize;

            FFT fft = new FFT();
            fft.Initialize((System.UInt32)spectrumSampleSize);

            double[] sampleChunk = new double[spectrumSampleSize];
            for (int i = 0; i < iterations; ++i)
            {
                //Grab the current 1024 chunk of audio data
                System.Array.Copy(processedSamples, i * spectrumSampleSize, sampleChunk, 0, spectrumSampleSize);

                //Apply FFT
                double[] windowCoEf        = DSP.Window.Coefficients(DSP.Window.Type.Hanning, (uint)spectrumSampleSize);
                double[] scaledSampleChunk = DSP.Math.Multiply(sampleChunk, windowCoEf);
                double   scaleFactor       = DSP.Window.ScaleFactor.Signal(windowCoEf);

                //Perform FFT and convert output to magnitude
                Complex[] fftSpectrum       = fft.Execute(scaledSampleChunk);
                double[]  scaledFFTSpectrum = DSP.ConvertComplex.ToMagnitude(fftSpectrum);
                scaledFFTSpectrum = DSP.Math.Multiply(scaledFFTSpectrum, scaleFactor);

                //Convert the chunk values to a single point within audio timeline
                float currSongtime = GetSongtime(i) * spectrumSampleSize;

                //Analyze multitude data using SpectrumAnalyzer to detect peaks
                spectrumAnalyzer.AnalyzeSpectrum(System.Array.ConvertAll(scaledFFTSpectrum, x => (float)x), currSongtime);
            }

            //Debug.Log("Spectrum Analysis completed, now getting all Peak data samples.");
            for (float i = 0f; i <= clipLength; i += 0.0167f)
            {
                //Get the index from the audio time
                int index = GetIndex(i) / spectrumAnalyzer.numSamples;

                //Only run if index returned is within range of the spectrum analyzer sample-list
                if (index < spectrumAnalyzer.spectralFluxSamples.Count)
                {
                    SpectralFluxInfo info = spectrumAnalyzer.spectralFluxSamples[index];

                    //Make sure sample is a peak
                    if (info.isPeak)
                    {
                        peakInfo.Add(info);
                    }
                }
            }

            //Debug.Log("Spectrum Analysis and Peak Sampling done. Thread completed.");
            peakInfoSize = peakInfo.Count;
            isDone       = true;
        }
        catch (System.Exception ex)
        {
            //Error logging
            Debug.LogError(ex.ToString());
        }
    }