예제 #1
0
        /// <summary>
        ///   Create log-spectrogram (spaced according to manager's parameters)
        /// </summary>
        /// <param name = "proxy">Proxy used in generating the spectrogram</param>
        /// <param name = "filename">Filename to be processed</param>
        /// <param name = "milliseconds">Milliseconds to be analyzed</param>
        /// <param name = "startmilliseconds">Starting point</param>
        /// <returns>Logarithmically spaced bins within the power spectrum</returns>
        public float[][] CreateLogSpectrogram(IWaveformPlayer proxy, string filename, int milliseconds, int startmilliseconds)
        {
            //read 5512 Hz, Mono, PCM, with a specific proxy
            float[] samples = BassProxy.ReadMonoFromFile(filename, SampleRate, milliseconds, startmilliseconds);
            //NormalizeInPlace(samples);
            int overlap        = Overlap;
            int fftWindowsSize = WdftSize;

            double[] windowArray = FFTWindow.GetWindowFunction(FFTWindowType.HANNING, fftWindowsSize);

            int width = (samples.Length - fftWindowsSize) / overlap;           /*width of the image*/

            float[][] frames        = new float[width][];
            float[]   complexSignal = new float[2 * fftWindowsSize];         /*even - Re, odd - Img*/
            for (int i = 0; i < width; i++)
            {
                //take 371 ms each 11.6 ms (2048 samples each 64 samples)
                for (int j = 0; j < fftWindowsSize /*2048*/; j++)
                {
                    // Weight by Hann Window
                    complexSignal[2 * j] = (float)(windowArray[j] * samples[i * overlap + j]);
                    //complexSignal[2*j] = (float) (_windowArray[j]*samples[i*overlap + j]); /*Weight by Hann Window*/
                    complexSignal[2 * j + 1] = 0;
                }
                //FFT transform for gathering the spectrum
                Fourier.FFT(complexSignal, fftWindowsSize, FourierDirection.Forward);
                frames[i] = ExtractLogBins(complexSignal);
            }
            return(frames);
        }
예제 #2
0
        private static void SimpleFFT()
        {
            ComplexF[] values         = new ComplexF[1024];
            ComplexF[] expectedValues = new ComplexF[1024];

            Random rnd = new Random();

            for (int i = 0; i < 1024; i++)
            {
                values[i] = new ComplexF(20, 0);
            }

            Array.Copy(values, expectedValues, expectedValues.Length);

            Fourier.FFT(values, FourierDirection.Forward);
            for (int i = 0; i < values.Length; i++)
            {
                Console.WriteLine(values[i]);
            }

            Fourier.FFT(values, FourierDirection.Backward);
            for (int i = 0; i < values.Length; i++)
            {
                Console.WriteLine("{0} {1} {2}",
                                  values[i] / values.Length
                                  , expectedValues[i],
                                  values[i] / expectedValues[i]);
            }
        }
예제 #3
0
 /// <summary>
 /// Compute a 1D fast Fourier transform of a dataset of complex numbers.
 /// </summary>
 /// <param name="data"></param>
 /// <param name="direction"></param>
 public static void      FFT(ComplexF[] data, FourierDirection direction)
 {
     if (data == null)
     {
         throw new ArgumentNullException("data");
     }
     Fourier.FFT(data, data.Length, direction);
 }
예제 #4
0
        public override void FFT(bool forward)
        {
            data.CopyTo(copy, 0);

            Fourier.FFT(copy, copy.Length, forward ?
                        FourierDirection.Forward :
                        FourierDirection.Backward);
        }
예제 #5
0
        public static FilterProfile Profile(ISoundObj impulse, SmoothingType type, double resolution)
        {
            uint nSR  = impulse.SampleRate;
            uint nSR2 = nSR / 2;

            ushort nChannels = impulse.NumChannels;

            for (ushort c = 0; c < nChannels; c++)
            {
                // Read channel into a buffer
                SingleChannel channel = impulse.Channel(c);
                SoundBuffer   buff    = new SoundBuffer(channel);
                buff.ReadAll();

                // And then double in length to prevent wraparound
                buff.PadTo(buff.Count * 2);
                // Pad to next higher power of two
                buff.PadToPowerOfTwo();
                // Read out into array of complex
                Complex[][] data  = buff.ToComplexArray();
                Complex[]   cdata = data[0];

                // Then we're done with the buffer for this channel
                buff = null;
                GC.Collect();

                // FFT in place
                Fourier.FFT(cdata.Length, cdata);

                int n = cdata.Length / 2;

                // Now we have an array of complex, from 0Hz to Nyquist and back again.
                // We really only care about the first half of the cdata buffer, but
                // treat it as circular anyway (i.e. wrap around for negative values).
                //
                // We're only working with magnitudes from here on,
                // so we can save some space by computing mags right away and storing them in the
                // real part of the complex array; then we can use the imaginary portion for the
                // smoothed data.
                for (int j = 0; j < cdata.Length; j++)
                {
                    cdata[j].Re = cdata[j].Magnitude;
                    cdata[j].Im = 0;
                }

                // Take a rectangular window of width (resolution)*(octave or ERB band)
                // Add up all magnitudes falling within this window
                //
                // Move the window forward by one thingummajig
                //double wMid = 0;    // center of the window
                //double wLen = 0;
            }
            return(new FilterProfile()); // temp
        }
예제 #6
0
        static private void Create_spectr()
        {
            lock (lockerDF)
            {
                data_furePic.Clear();
                data_own_func.Clear();
                float step = (float)1 / size / stept;
                for (int i = 0; i < data_fure.Count; i++)
                {
                    Complex[] buf = new Complex[size];
                    for (int j = 0; j < size; j++)
                    {
                        buf[j] = data_fure[i][j];
                    }



                    buf = Fourier.FFT(buf);


                    for (int j = 0; j < size; j++)
                    {
                        data_fure[i][j] = buf[j];
                    }

                    List <PointF> buf_vector = new List <PointF>();
                    for (int j = 0; j < size; j++)
                    {
                        PointF point = new PointF {
                            X = j * step, Y = (float)data_fure[i][j].Abs
                        };
                        buf_vector.Add(point);
                    }
                    data_furePic.Add(buf_vector);
                }


                for (int i = 0; i < size; i++) //-2 ибо не считаю спектры с концов, там всякий шум копится
                {
                    List <PointF> buf_list = new List <PointF>();
                    for (int j = 0; j < data_furePic.Count; j++)
                    {
                        PointF buf = new PointF {
                            X = (float)xx[j], Y = (float)data_fure[j][i].Re
                        };
                        buf_list.Add(buf);
                    }
                    data_own_func.Add(buf_list);
                }
                isSpectrDone = true;
            }

            return;
        }
예제 #7
0
    public static double[] padded_FFT(Complex[] complexSignal)
    {
        int N = complexSignal.Length;

        Fourier.FFT(complexSignal, N, FourierDirection.Forward);

        // get the result
        double[] fft_real = new double[N];
        for (int j = 0; j < N; j++)
        {
            fft_real[j] = complexSignal[j].Re;
        }
        return(fft_real);
    }
예제 #8
0
        public override double[] Spectrum(double[] input, bool scale)
        {
            var data = ToComplex(input);

            Fourier.FFT(data, data.Length, FourierDirection.Forward);

            var spectrum = ComputeSpectrum(data);

            Fourier.FFT(data, data.Length, FourierDirection.Backward);

            ToDouble(data, input);

            return(spectrum);
        }
예제 #9
0
    public static double[] padded_IFFT(double[] signal)
    {
        int N = signal.Length;

        Complex[] complexSignal = FFTUtils.DoubleToComplex(signal);
        Fourier.FFT(complexSignal, N, FourierDirection.Backward);

        // get the result
        double[] fft_real = new double[N];
        for (int j = 0; j < N; j++)
        {
            fft_real[j] = complexSignal[j].Re;
        }
        return(fft_real);
    }
예제 #10
0
        /// <summary>
        /// Applies a High Pass Filter to a Signal
        /// </summary>
        /// <param name="s">The Signal to filter</param>
        /// <returns>The Filtered Signal</returns>
        public static Signal High(Signal s)
        {
            Signal fft       = Fourier.FFT(s);
            int    indexPass = (7 * 2) - 1;
            Signal result    = new Signal(s.Length);

            for (int i = 0; i < result.Length; i++)
            {
                result[i] = 0;
            }
            for (int i = 15; i < result.Length - indexPass; i += 2)
            {
                result[i] = fft[i];
            }
            return(Fourier.InverseFFT(result));
        }
예제 #11
0
        public void AppendSample(byte[] data, uint time)
        {
            Complex[] fft = new Complex[N];
            for (int i = 0; i < N; i++)
            {
                int    byteOffset = 2 * i;
                double val        = hammingWindowCoeffs[i] * (short)(data[byteOffset] | data[byteOffset + 1] << 8);

                fft[i] = new Complex(val, 0);
            }
            Fourier.FFT(N, fft);

            var magnitudes  = new double[6];
            var frequencies = new uint[6];

            for (uint freq = MinFrequency; freq < MaxFrequency - 1; freq++)
            {
                // Get the magnitude:
                double mag = fft[freq].Magnitude;

                // Find out which range we are in:
                int range = getRange(freq);

                // Save the highest magnitude and corresponding frequency:
                if (mag > magnitudes[range])
                {
                    magnitudes[range] = mag;

                    frequencies[range] = freq;
                }
            }

            var threshold = 0.9 * (magnitudes[0] + magnitudes[1] + magnitudes[2] +
                                   magnitudes[3] + magnitudes[4] + magnitudes[5]) / 6;

            for (int i = 0; i < 6; i++)
            {
                if (magnitudes[i] > threshold)
                {
                    spectrum.Add(new SpectrumPoint()
                    {
                        Freq = frequencies[i], Time = time
                    });
                }
            }
        }
예제 #12
0
        private static void LinqVersion()
        {
            byte[] outputBuffer = new byte[1024 * 4];

            var filter =
                LoadBlocks(INPUT_FILENAME, outputBuffer.Length)
                .Select(cb => Fourier.FFT(cb, FourierDirection.Forward))
                .Select(cb => LowPassFilter(cb))
                .Select(cb => Fourier.FFT(cb, FourierDirection.Backward));

            using (Stream output = File.Create(LINQ_OUTPUT_FILENAME))
            {
                foreach (ComplexF[] complexBuffer in filter)
                {
                    WriteComplexBuffer(output, complexBuffer);
                }
            }
        }
예제 #13
0
        public float[] FFTForward(float[] signal, int startIndex, int length)
        {
            float[] complexSignal = new float[2 * length]; /*even - Re, odd - Img, thats how Exocortex works*/

            // take 371 ms each 11.6 ms (2048 samples each 64 samples)
            for (int i = 0; i < length /*2048*/; i++)
            {
                complexSignal[2 * i]       = signal[startIndex + i];
                complexSignal[(2 * i) + 1] = 0;
            }

            lock (lockObject)
            {
                Fourier.FFT(complexSignal, length, FourierDirection.Forward);
            }

            return(complexSignal);
        }
예제 #14
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[][] CreateSpectrogramExocortex(float[] samples, int fftWindowsSize, int fftOverlap)
        {
            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 X time slots (numberOfSegments) and do analysis on each slot
            int numberOfSegments = (numberOfSamples - fftWindowsSize) / fftOverlap;
            var frames           = new double[numberOfSegments][];

            // even - Re, odd - Img
            var complexSignal = new float[2 * 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] = (float)(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
                Fourier.FFT(complexSignal, fftWindowsSize, FourierDirection.Forward);

                // 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];

                    band[j] = (double)Math.Sqrt(re * re + img * img);
                }
                frames[i] = band;
            }

            return(frames);
        }
예제 #15
0
        /// <summary>
        ///   Create spectrogram of the input file
        /// </summary>
        /// <param name = "proxy">Proxy used to read from file</param>
        /// <param name = "filename">Filename</param>
        /// <param name = "milliseconds">Milliseconds to process</param>
        /// <param name = "startmilliseconds">Starting point of the processing</param>
        /// <returns>Spectrogram</returns>
        public float[][] CreateSpectrogram(IWaveformPlayer proxy, string filename, int milliseconds, int startmilliseconds, bool doNormalise)
        {
            //read 5512 Hz, Mono, PCM, with a specific proxy
            float[] samples = BassProxy.ReadMonoFromFile(filename, SampleRate, milliseconds, startmilliseconds);
            if (doNormalise)
            {
                NormalizeInPlace(samples);
            }
            int overlap        = Overlap;
            int fftWindowsSize = WdftSize;             // aka N = FFT Length

            double[] windowArray = FFTWindow.GetWindowFunction(FFTWindowType.HANNING, fftWindowsSize);

            int width = (samples.Length - fftWindowsSize) / overlap;           /*width of the image*/

            float[][] frames        = new float[width][];
            float[]   complexSignal = new float[2 * fftWindowsSize];         /*even - Re, odd - Img*/
            for (int i = 0; i < width; i++)
            {
                //take 371 ms each 11.6 ms (2048 samples each 64 samples)
                // apply Hanning Window
                for (int j = 0; j < fftWindowsSize /*2048*/; j++)
                {
                    // Weight by Hann Window
                    complexSignal[2 * j] = (float)(windowArray[j] * samples[i * overlap + j]);
                    //complexSignal[2*j] = (float) ((4.0/(fftWindowsSize - 1)) * windowArray[j]*samples[i*overlap + j]); /*Weight by Hann Window*/
                    complexSignal[2 * j + 1] = 0;                    // need to clear out as fft modifies buffer
                }
                //FFT transform for gathering the spectrum
                Fourier.FFT(complexSignal, fftWindowsSize, FourierDirection.Forward);
                float[] band = new float[fftWindowsSize / 2 + 1];
                for (int j = 0; j < fftWindowsSize / 2 + 1; j++)
                {
                    double re  = complexSignal[2 * j];
                    double img = complexSignal[2 * j + 1];
                    //double img = 0.0; // TODO: Zero out the imaginary component (phase) ? / need to clear out as fft modifies buffer
                    band[j] = (float)Math.Sqrt(re * re + img * img);
                }
                frames[i] = band;
            }

            return(frames);
        }
예제 #16
0
        /// <summary>
        /// Applies a Notch Filter to a Signal
        /// </summary>
        /// <param name="s">The Signal to filter</param>
        /// <returns>The Filtered Signal</returns>
        public static Signal Notch(Signal s)
        {
            Signal fft    = Fourier.FFT(s);
            Signal result = new Signal(s.Length);

            for (int i = 0; i < result.Length; i++)
            {
                result[i] = fft[i];
            }
            for (int i = 9; i < 16; i++)
            {
                result[i] = 0;
            }
            for (int i = 497; i < 504; i++)
            {
                result[i] = 0;
            }
            return(Fourier.InverseFFT(result));
        }
예제 #17
0
        public void GetPower()
        {
            int count = WINDOW_SIZE / FLOAT_SIZE;

            complex = new Complex[count];
            real    = new double[count];
            imag    = new double[count];

            for (int i = 0; i < WINDOW_SIZE; i += 4)
            {
                //audioStream.Read(buffer, 0, FLOAT_SIZE);
                complex[i] = (Complex)BitConverter.ToSingle(window, i);
            }

            Fourier.FFT(complex, count, FourierDirection.Forward);
            real = complex.Select(c => Math.Pow(c.Re, 2)).ToArray();
            imag = complex.Select(c => Math.Pow(c.Im, 2)).ToArray();

            audioStream.Position -= (WINDOW_SIZE - WINDOW_SHIFT_SIZE);
            audioStream.Read(window, 0, WINDOW_SIZE);
        }
예제 #18
0
        private static void SequentialVersion()
        {
            using (Stream output = File.Create(OUTPUT_FILENAME))
            {
                byte[] outputBuffer = new byte[1024 * 4];

                // Stage 1
                foreach (ComplexF[] complexBuffer in LoadBlocks(INPUT_FILENAME, outputBuffer.Length))
                {
                    // Stage 2
                    ComplexF[] result = Fourier.FFT(complexBuffer, FourierDirection.Forward);

                    // Stage 3
                    result = LowPassFilter(result);

                    // Stage 4
                    result = Fourier.FFT(result, FourierDirection.Backward);

                    // Stage 5
                    WriteComplexBuffer(output, result);
                }
            }
        }
예제 #19
0
    public static double[] padded_IFFT(Complex[] complexSignal)
    {
        int N = MathUtils.NextPowerOfTwo(complexSignal.Length);

        if (N <= 4096)
        {
            complexSignal = zeros(complexSignal, N);
            Fourier.FFT(complexSignal, N, FourierDirection.Backward);
        }
        else
        {
            N = 4096;
            Array.Resize(ref complexSignal, N);
            Fourier.FFT(complexSignal, N, FourierDirection.Backward);
        }

        // get the result
        double[] fft_real = new double[N];
        for (int j = 0; j < N; j++)
        {
            fft_real[j] = complexSignal[j].Re;
        }
        return(fft_real);
    }
예제 #20
0
        private static void CalculateTremor()
        {
            GetAccelAmplitudes();
            Fourier.FFT(accelAmplitudes, FourierDirection.Forward);
            float[] fftAmplitudes = GetFFTAmplitudes(accelAmplitudes);
            float[] binFrequencies = new float[(int)(fftAmplitudes.Length)];
            float   halfSampleFreq = Sample_Frequency / 2;
            float   freq = 0, maxAmp = Threshold_Amplitude;

            for (int binIndex = 0; binIndex < binFrequencies.Length; binIndex++)
            {
                freq = binIndex * halfSampleFreq / fftAmplitudes.Length; // From: (bin_id * freq/2) / N
                binFrequencies[binIndex] = freq;

                if (fftAmplitudes[binIndex] > maxAmp && freq > Threshold_Frequency)
                {
                    maxAmp    = fftAmplitudes[binIndex];
                    Amplitude = maxAmp;
                    Frequency = freq;
                }
            }

            DataLogging.LogProcessedData(binFrequencies, fftAmplitudes);
        }
예제 #21
0
파일: GraphCommand.cs 프로젝트: Iyui/Gmage
        public Bitmap Draw()
        {
            var _bitmap = bitmap.Clone() as Bitmap;

            return(Fourier.FFT(_bitmap));
        }
예제 #22
0
        private static double WeightedVolume2(SoundBuffer src, double dbSPL, double dbSPLBase)
        {
            double v  = 0;
            uint   sr = src.SampleRate;

            // Read buffer into array of complex
            Complex[][] data = src.ToComplexArray();

            // We only have a single channel
            Complex[] cdata = data[0];

            // FFT in place
            Fourier.FFT(cdata.Length, cdata);

            // Calculate magnitude, weighted by 80-phon loudness, for each loudness band.
            // These are the ISO measured points:
            FilterProfile lfg;

            if (dbSPLBase == 0)
            {
                lfg = SPL(dbSPL);
            }
            else
            {
                lfg = DifferentialSPL(dbSPL, dbSPLBase);
            }
//          lfg.Add(new FreqGain(sr / 2, lfg[lfg.Count - 1].Gain));

            // Cover the ISO measured range (only...)
            int nStart = (int)(lfg[0].Freq * (long)cdata.Length / sr);
            int nEnd   = (int)(lfg[lfg.Count - 1].Freq * (long)cdata.Length / sr);

            // Just use linear interpolation (on a dB scale; linear freq scale) of gain between each measured point
            int nfg = 0;

            int    startp = nStart;
            int    endp   = (int)(lfg[nfg + 1].Freq * (long)cdata.Length / sr); // endpoint of this band
            double dB1    = lfg[nfg].Gain;                                      // SPL of the ISO223 curve at this freq
            double dB2    = lfg[nfg + 1].Gain;                                  // ...and the next point

            double vThisBand = 0;
            int    nThisBand = 0;

            for (int j = nStart; j < nEnd; j++)
            {
                if (j > endp)
                {
                    if (nThisBand > 0)
                    {
                        v += Math.Sqrt(vThisBand / nThisBand);                // RMS
                    }
                    while (j >= endp)
                    {
                        nfg++;
                        startp = j;
                        endp   = (int)(lfg[nfg + 1].Freq * (long)cdata.Length / sr);
                        dB1    = lfg[nfg].Gain;
                        dB2    = lfg[nfg + 1].Gain;
                    }
                    vThisBand = 0;
                    nThisBand = 0;
                }
                Complex c      = cdata[j];
                double  dbHere = dB1 + ((dB2 - dB1) * (double)(j - startp) / (double)(endp - startp));
                vThisBand += (c.Re * c.Re) / MathUtil.gain(dbHere);
                nThisBand++;
            }
            if (nThisBand > 0)
            {
                v += Math.Sqrt(vThisBand / nThisBand);
            }

            return(v);
        }
예제 #23
0
        private bool ComputePartitionedImpulseFFT()
        {
            if (_impulse == null)
            {
                return(false);
            }
            ushort nChannels;

            if (_input == null)
            {
                nChannels = _impulse.NumChannels;
            }
            else
            {
                nChannels = _input.NumChannels;
            }
            ushort p;
            int    N  = _impulseLength;
            int    Nh = N << 1;
            int    K  = (int)(N / _partitions);
            int    L  = MathUtil.NextPowerOfTwo(K << 1);
            int    P  = (int)Math.Ceiling((double)N / (double)K);

            // Initialize the arrays of impulse-FFTs
            _PartitionedImpulseFFT = new Complex[nChannels][][];
            Complex[][] tmp = new Complex[nChannels][];
            for (ushort c = 0; c < nChannels; c++)
            {
                tmp[c] = new Complex[Nh];
                _PartitionedImpulseFFT[c] = new Complex[P][];
                for (p = 0; p < P; p++)
                {
                    _PartitionedImpulseFFT[c][p] = new Complex[L];
                }
            }

            // Read all samples from the impulse, & fft in blocks of size K (padded to L, L~=2K)
            int i = 0;
            int n = 0;

            p = 0;
            foreach (ISample sample in _impulse)
            {
                // Reading a segment of the impulse (into src[])
                n++;
                if (n > _impulseLength)
                {
                    break;
                }                                  // source gave us more data than we'd expected
                for (ushort c = 0; c < _impulse.NumChannels; c++)
                {
                    tmp[c][i + K] = new Complex(sample[c], 0); // TBD
                }
                i++;
                if (i >= K)
                {
                    // Do the fft of this segment of the impulse, into fftImpulse[]
                    for (ushort c = 0; c < nChannels; c++)
                    {
                        if (c >= _impulse.NumChannels)
                        {
                            // Handle the case where impulse has only one channel, but input (hence nChannels) is wider;
                            // we already computed the fft in _PartitionedImpulseFFT[0][p], so just duplicate it.
                            // In fact we can just ref the whole buffer -- no need even to make a deep copy
                            _PartitionedImpulseFFT[c][p] = _PartitionedImpulseFFT[0][p];
                        }
                        else
                        {
                            Array.Copy(tmp[c], _PartitionedImpulseFFT[c][p], L);
                            Fourier.FFT(L, _PartitionedImpulseFFT[c][p]);
                        }
                    }
                    i = 0; p++;
                }
            }
            _impulseLengthOrig = n - 1;
            if (p < P)
            {
                // Fill any extra space with nulls
                for (int ii = i; ii < K; ii++)
                {
                    for (ushort c = 0; c < _impulse.NumChannels; c++)
                    {
                        tmp[c][ii + K] = new Complex(0, 0); // TBD
                    }
                }
                // FFT the last segment
                for (ushort c = 0; c < nChannels; c++)
                {
                    if (c >= _impulse.NumChannels)
                    {
                        // Handle the case where impulse has only one channel, but input (hence nChannels) is wider;
                        // we already computed the fft in _PartitionedImpulseFFT[0][p], so just duplicate it.
                        // In fact we can just ref the whole buffer -- no need even to make a deep copy
                        _PartitionedImpulseFFT[c][p] = _PartitionedImpulseFFT[0][p];
                    }
                    else
                    {
                        Array.Copy(tmp[c], _PartitionedImpulseFFT[c][p], L);
                        Fourier.FFT(L, _PartitionedImpulseFFT[c][p]);
                    }
                }
            }
            return(true);
        }
예제 #24
0
        private bool ComputeNormalImpulseFFT()
        {
            if (_impulse == null)
            {
                return(false);
            }
            ushort nChannels;

            if (_input == null)
            {
                nChannels = _impulse.NumChannels;
            }
            else
            {
                nChannels = _input.NumChannels;
            }
            int N  = _impulseLength;
            int Nh = N << 1;

            // Initialize the array of impulse-FFTs
            _NormalImpulseFFT = new Complex[nChannels][];
            for (ushort c = 0; c < nChannels; c++)
            {
                _NormalImpulseFFT[c] = new Complex[Nh];
            }

            // Read all samples from the impulse
            // into the second half of the src buffer (the first half is all zeros)
            int i = 0;

            foreach (ISample sample in _impulse)
            {
                for (ushort c = 0; c < _impulse.NumChannels; c++)
                {
                    _NormalImpulseFFT[c][i + N] = new Complex(sample[c], 0);
                }
                i++;
                if (i >= _impulseLength)
                {
                    break;
                }                                   // source gave us more data than we'd expected
            }
            _impulseLengthOrig = i - 1;

            // Do the fft of impulse, in-place
            for (ushort c = 0; c < nChannels; c++)
            {
                if (c >= _impulse.NumChannels)
                {
                    // Handle the case where impulse has only one channel, but input (hence nChannels) is wider;
                    // we already computed the fft in _NormalImpulseFFT[0], so just duplicate it.
                    // In fact we can just ref the whole buffer -- no need even to make a deep copy
                    _NormalImpulseFFT[c] = _NormalImpulseFFT[0];
                }
                else
                {
                    Fourier.FFT(Nh, _NormalImpulseFFT[c]);
                }
            }
            return(true);
        }
예제 #25
0
        /// <summary>
        /// 读取样本
        /// </summary>
        /// <param name="transmit"></param>
        private void ReadSample(bool transmit)
        {
            // 提取数据, sampleIndex特定位置
            clip.GetData(sampleBuffer, sampleIndex);

            // 抓住一个新的样品缓冲区
            float[] targetSampleBuffer = VoiceChatFloatPool.Instance.Get();

            // 将我们的真实样本重新取样到缓冲区中
            Resample(sampleBuffer, targetSampleBuffer);

            // Forward index
            sampleIndex += recordSampleSize;

            // 最高自动检测频率
            float freq  = float.MinValue;
            int   index = -1;

            // 自动检测语音,但如果我们要按键传输,就不需要检测了
            if (autoDetectSpeaking && !transmit)
            {
                // 清除FFT缓冲区
                for (int i = 0; i < fftBuffer.Length; ++i)
                {
                    fftBuffer[i] = 0;
                }

                //  复制到FFT缓冲区
                Array.Copy(targetSampleBuffer, 0, fftBuffer, 0, targetSampleBuffer.Length);

                // 应用FFT
                Fourier.FFT(fftBuffer, fftBuffer.Length / 2, FourierDirection.Forward);

                // 获取最高频率
                for (int i = 0; i < fftBuffer.Length; ++i)
                {
                    if (fftBuffer[i] > freq)
                    {
                        freq  = fftBuffer[i];
                        index = i;
                    }
                }
            }

            // 如果我们有一个事件,并且
            if (NewSample != null && (transmit || forceTransmit > 0 || index >= autoDetectIndex))
            {
                // 如果我们自动检测到声音,就强行录音一会儿
                if (index >= autoDetectIndex)
                {
                    if (forceTransmit <= 0)
                    {
                        while (previousSampleBuffer.Count > 0)
                        {
                            TransmitBuffer(previousSampleBuffer.Remove());
                        }
                    }

                    forceTransmit = forceTransmitTime;
                }

                TransmitBuffer(targetSampleBuffer);
            }
            else
            {
                if (previousSampleBuffer.Count == previousSampleBuffer.Capacity)
                {
                    VoiceChatFloatPool.Instance.Return(previousSampleBuffer.Remove());
                }

                previousSampleBuffer.Add(targetSampleBuffer);
            }
        }
예제 #26
0
 private Complex[] GetFourier(double[] Input)
 {
     Complex[] FourierMass = Fourier.FFT(Input);
     return(FourierMass);
 }
예제 #27
0
    /// <summary>
    /// Compute a 1D real-symmetric fast fourier transform.
    /// </summary>
    /// <param name="data"></param>
    /// <param name="length"></param>
    /// <param name="direction"></param>
    public static void      RFFT(float[] data, int length, FourierDirection direction)
    {
        if (data == null)
        {
            throw new ArgumentNullException("data");
        }
        if (data.Length < length)
        {
            throw new ArgumentOutOfRangeException("length", length, "must be at least as large as 'data.Length' parameter");
        }
        if (Fourier.IsPowerOf2(length) == false)
        {
            throw new ArgumentOutOfRangeException("length", length, "must be a power of 2");
        }

        float c1 = 0.5f, c2;
        float theta = (float)Math.PI / (length / 2);

        if (direction == FourierDirection.Forward)
        {
            c2 = -0.5f;
            FFT(data, length / 2, direction);
        }
        else
        {
            c2    = 0.5f;
            theta = -theta;
        }

        float wtemp = (float)Math.Sin(0.5 * theta);
        float wpr   = -2 * wtemp * wtemp;
        float wpi   = (float)Math.Sin(theta);
        float wr    = 1 + wpr;
        float wi    = wpi;

        // do / undo packing
        for (int i = 1; i < length / 4; i++)
        {
            int   a   = 2 * i;
            int   b   = length - 2 * i;
            float h1r = c1 * (data[a] + data[b]);
            float h1i = c1 * (data[a + 1] - data[b + 1]);
            float h2r = -c2 * (data[a + 1] + data[b + 1]);
            float h2i = c2 * (data[a] - data[b]);
            data[a]     = h1r + wr * h2r - wi * h2i;
            data[a + 1] = h1i + wr * h2i + wi * h2r;
            data[b]     = h1r - wr * h2r + wi * h2i;
            data[b + 1] = -h1i + wr * h2i + wi * h2r;
            wr          = (wtemp = wr) * wpr - wi * wpi + wr;
            wi          = wi * wpr + wtemp * wpi + wi;
        }

        if (direction == FourierDirection.Forward)
        {
            float hir = data[0];
            data[0] = hir + data[1];
            data[1] = hir - data[1];
        }
        else
        {
            float hir = data[0];
            data[0] = c1 * (hir + data[1]);
            data[1] = c1 * (hir - data[1]);
            Fourier.FFT(data, length / 2, direction);
        }
    }
예제 #28
0
        static void Main()
        {
            //var A1 = new double[Nx];
            //var A2 = new double[Nx];
            //for (int i = 0; i < Nx; i++)
            //{
            //    A1[i] = i;
            //    A2[i] = A1[i];
            //}
            //A2[Nx - 1] = 253;
            //double res = NormsComparison(A2, A1);
            int jj = 0;

            SetPumping(r);
            SetLosses(sigma);
            SetSpaceFrequency();
            SetInitials();
            SetExtraConstants();
            for (int i = 0; i < Nx; i++)
            {
                Console.WriteLine(E[i].Abs * E[i].Abs);
            }
            sumtimer.Start();
            for (int q = 0; q < Nt; q++)
            {
                ffttimer.Start();
                Ef = Fourier.FFT(E);
                Pf = Fourier.FFT(P);
                ffttimer.Stop();

                for (int i = 0; i < Nx; i++)
                {
                    Dfl[i] = exp1 * D[i];
                    Pfl[i] = exp2 * P[i];
                    Pf[i]  = Pf[i] * exp4[i];
                    Efl[i] = exp2 * Pf[i] + exp3[i] * (Ef[i] - Pf[i]);
                }
                ffttimer.Start();
                Efl = Fourier.IFFT(Efl);
                ffttimer.Stop();

                // Start iteration process
                Set(E, Ec);
                Set(P, Pc);
                Set(D, Dc);
                Set(E, Ej);
                ffttimer.Start();
                Ef = Fourier.FFT(Efl);
                ffttimer.Stop();

                for (int i = 0; i < Nx; i++)
                {
                    exp5[i] = D[i] * E[i];
                    exp6[i] = 2 * R[i] - 0.5 * (Ec[i].Re * Pc[i].Re + Pc[i].Im * Ec[i].Im);
                }
                //jj = 0;
                for (int j = 0; j < Nmax; j++)
                {
                    //jj++;
                    for (int i = 0; i < Nx; i++)
                    {
                        Pj[i] = Pfl[i] + (exp5[i] + Dc[i] * Ec[i]) / 2 * dt;
                        Dj[i] = Dfl[i] + gamma * dt * (exp6[i] - 0.5 * (Ec[i].Re * Pc[i].Re + Pc[i].Im * Ec[i].Im)) / 2;
                    }
                    ffttimer.Start();
                    Pf = Fourier.FFT(Pj);
                    ffttimer.Stop();

                    for (int i = 0; i < Nx; i++)
                    {
                        Pf[i] = Pf[i] * exp4[i];
                        Dj[i] = Dj[i] * exp1;
                        Pj[i] = Pj[i] * exp2;
                        Ej[i] = exp2 * Pf[i] + exp3[i] * (Ef[i] - Pf[i]);
                    }
                    ffttimer.Start();
                    Ej = Fourier.IFFT(Ej);
                    ffttimer.Stop();

                    normtimer.Start();
                    double normE = NormsComparison(Ej, Ec);
                    double normP = NormsComparison(Pj, Pc);
                    double normD = NormsComparison(Dj, Dc);
                    if (normE < eps && normP < eps && normD < eps)
                    {
                        Ec = Ej;
                        Pc = Pj;
                        Dc = Dj;
                        normtimer.Stop();
                        if (jj != j)
                        {
                            Console.WriteLine(j);
                            jj = j;
                        }
                        break;
                    }
                    else
                    {
                        Set(Ej, Ec);
                        Set(Pj, Pc);
                        Set(Dj, Dc);
                    }
                    normtimer.Stop();
                }
                //Console.WriteLine(jj);
                E = Ec;
                P = Pc;
                D = Dc;
            }
            sumtimer.Stop();

            Console.WriteLine("Sum time: " + sumtimer.ElapsedMilliseconds / Nt);
            Console.WriteLine("FFT time: " + ffttimer.ElapsedMilliseconds / Nt);
            Console.WriteLine("Norm time: " + normtimer.ElapsedMilliseconds / Nt);
            for (int i = 0; i < Nx; i++)
            {
                Console.WriteLine(E[i].Abs * E[i].Abs);
            }
            Console.ReadKey();
        }
예제 #29
0
파일: Data.cs 프로젝트: andgra/reverse_ray
        public static Trace[] Deconvolve(Trace[] data, double decA = Double.NegativeInfinity, bool onlyRe = false)
        {
            var tracesDataDeconv = new Trace[numberOfSonograms * numberOfTraces];

            if (Double.IsNegativeInfinity(decA))
            {
                decA = curDecA;
            }

            var impulseSpec = new Exocortex.DSP.Complex[4096];

            for (int i = 0; i < signal.Length; i++)
            {
                impulseSpec[i].Re = signal[i];
            }
            Exocortex.DSP.Fourier.FFT(impulseSpec, 4096, Exocortex.DSP.FourierDirection.Forward);

            var impMulti = new Exocortex.DSP.Complex[4096];

            if (decA >= 0)
            {
                var impulseSpecInv = new Exocortex.DSP.Complex[4096];
                for (int i = 0; i < impulseSpec.Length; i++)
                {
                    impulseSpecInv[i].Re = impulseSpec[i].Re;
                    impulseSpecInv[i].Im = -impulseSpec[i].Im;
                }

                for (int i = 0; i < impulseSpec.Length; i++)
                {
                    impMulti[i] = impulseSpecInv[i] / (Math.Pow(impulseSpec[i].Re, 2) + Math.Pow(impulseSpec[i].Im, 2) + Math.Pow(decA, 2));
                }
            }
            else
            {
                for (int i = 0; i < impulseSpec.Length; i++)
                {
                    impMulti[i] = impulseSpec[i];
                }
            }

            Parallel.For(0, data.Length, tn =>
            {
                var t          = data[tn];
                var tempColumn = new Exocortex.DSP.Complex[4096];
                for (int i = 0; i < Math.Min(4096, maxtime); i++)
                {
                    tempColumn[i].Re = t.data[i];
                }
                Fourier.FFT(tempColumn, 4096, FourierDirection.Forward);
                for (int i = 0; i < 4096; i++)
                {
                    tempColumn[i] = tempColumn[i] * impMulti[i];
                }
                Fourier.FFT(tempColumn, 4096, FourierDirection.Backward);

                Trace tConv = new Trace(t);

                for (int i = 0; i < Math.Min(4096, maxtime); i++)//обрезаем то, что вылезло за границы
                {
                    tConv.data[i] = (onlyRe ? (float)tempColumn[i].Re : (float)Math.Sqrt(tempColumn[i].Re * tempColumn[i].Re + tempColumn[i].Im * tempColumn[i].Im)) / 4096;
                }
                tracesDataDeconv[tn] = tConv;
            });

            return(tracesDataDeconv);
        }
예제 #30
0
        public void Calculate()
        {
            try
            {
                sumtimer.Reset();
                ffttimer.Reset();
                normtimer.Reset();
                if (OnCalculationStart != null)
                {
                    OnCalculationStart(this, new EventArgs());
                }
                sumtimer.Start();
                SetParameters();
                for (int q = 0; q < Nt; q++)
                {
                    if (CalculationCancelled)
                    {
                        break;
                    }
                    ffttimer.Start();
                    Ef = Fourier.FFT(E);
                    Pf = Fourier.FFT(P);
                    ffttimer.Stop();

                    for (int i = 0; i < Nx; i++)
                    {
                        Dfl[i] = exp1 * D[i];
                        Pfl[i] = exp2 * P[i];
                        Pf[i]  = Pf[i] * exp4[i];
                        Efl[i] = exp2 * Pf[i] + exp3[i] * (Ef[i] - Pf[i]);
                    }
                    ffttimer.Start();
                    Efl = Fourier.IFFT(Efl);
                    ffttimer.Stop();

                    // Start iteration process
                    Set(E, Ec);
                    Set(P, Pc);
                    Set(D, Dc);
                    Set(E, Ej);
                    ffttimer.Start();
                    Ef = Fourier.FFT(Efl);
                    ffttimer.Stop();

                    for (int i = 0; i < Nx; i++)
                    {
                        exp5[i] = D[i] * E[i];
                        exp6[i] = 2 * R[i] - 0.5 * (Ec[i].Re * Pc[i].Re + Pc[i].Im * Ec[i].Im);
                    }
                    //jj = 0;
                    for (int j = 0; j < Nmax; j++)
                    {
                        //jj++;
                        for (int i = 0; i < Nx; i++)
                        {
                            Pj[i] = Pfl[i] + (exp5[i] + Dc[i] * Ec[i]) / 2 * dt;
                            Dj[i] = Dfl[i] + gamma * dt * (exp6[i] - 0.5 * (Ec[i].Re * Pc[i].Re + Pc[i].Im * Ec[i].Im)) / 2;
                        }
                        ffttimer.Start();
                        Pf = Fourier.FFT(Pj);
                        ffttimer.Stop();

                        for (int i = 0; i < Nx; i++)
                        {
                            Pf[i] = Pf[i] * exp4[i];
                            Dj[i] = Dj[i] * exp1;
                            Pj[i] = Pj[i] * exp2;
                            Ej[i] = exp2 * Pf[i] + exp3[i] * (Ef[i] - Pf[i]);
                        }
                        ffttimer.Start();
                        Ej = Fourier.IFFT(Ej);
                        ffttimer.Stop();

                        normtimer.Start();
                        //double normE = NormsComparison(Ej, Ec);
                        //double normP = NormsComparison(Pj, Pc);
                        //double normD = NormsComparison(Dj, Dc);
                        if (NormsComparison(Ej, Ec) < eps && NormsComparison(Pj, Pc) < eps && NormsComparison(Dj, Dc) < eps)
                        {
                            Ec = Ej;
                            Pc = Pj;
                            Dc = Dj;
                            normtimer.Stop();
                            if (jj != j)
                            {
                                Console.WriteLine(j);
                                jj = j;
                            }
                            break;
                        }
                        else
                        {
                            Set(Ej, Ec);
                            Set(Pj, Pc);
                            Set(Dj, Dc);
                        }
                        normtimer.Stop();
                    }
                    //Console.WriteLine(jj);
                    E = Ec;
                    P = Pc;
                    D = Dc;
                }
            }
            catch (Exception ex)
            {
                if (OnCalculationError != null)
                {
                    OnCalculationError(this, new EventArgs());
                }
            }
            sumtimer.Stop();
            if (OnCalculationFinish != null)
            {
                OnCalculationFinish(this, new EventArgs());
            }
            CalculationCancelled = false;
        }