Пример #1
0
 private void addToFFTs(object sender, SingleBlockReadEventArgs e)
 {
     if (!SeparateChannels)
     {
         fftProvider.Add(e.Left, e.Right);
         return;
     }
     else
     {
         fftProvider.Add(e.Left, e.Left);
         fftProvider2.Add(e.Right, e.Right);
     }
 }
Пример #2
0
        //most of this code is stolen from the example in the CSCore github so idk what it does 40% of the time
        public void Initialize(FFTSize _size = FFTSize._4096)
        {
            size     = _size;
            _soundIn = new WasapiLoopbackCapture();

            _soundIn.Initialize();
            var soundInSource = new SoundInSource(_soundIn);

            var source = soundInSource.ToSampleSource();

            _fft = new FftProvider(source.WaveFormat.Channels, (FftSize)size);

            var n = new SingleBlockNotificationStream(source);

            n.SingleBlockRead += (s, a) => _fft.Add(a.Left, a.Right);

            _source = n.ToWaveSource(16);
            byte[] buffer = new byte[_source.WaveFormat.BytesPerSecond];
            soundInSource.DataAvailable += (s, aEvent) =>
            {
                int read;
                while ((read = _source.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ;
                }
            };
            _soundIn.Start();
        }
Пример #3
0
 private void SingleBlockNotificationStreamOnSingleBlockRead(object sender, SingleBlockReadEventArgs e)
 {
     lock (_lockObject)
     {
         _left.Add(e.Left);
         _right.Add(e.Right);
         _fftProvider.Add(e.Left, e.Right);
     }
 }
Пример #4
0
    public void SingleBlockRead(System.Object sender, SingleBlockReadEventArgs args)
    {
        fft1.Add(args.Left, args.Right);
        fft2.Add(args.Left, args.Right);

        leftChannel[leftChannelIndex++] = args.Left;
        if (leftChannelIndex >= leftChannel.Length)
        {
            leftChannelIndex %= leftChannel.Length;
        }
    }
Пример #5
0
    private void UpdateSpectrumData(byte[] data)
    {
        for (int i = 0; i < (int)fftProvider.FftSize; i++)
        {
            float l = BitConverter.ToSingle(data, i * 8) * hamming[i];
            float r = BitConverter.ToSingle(data, i * 8 + 4) * hamming[i];
            fftProvider.Add(l, r);
        }

        lock (spectrumData)
        {
            fftProvider.GetFftData(spectrumData);
        }

        newDataRead = false;
    }
Пример #6
0
 private unsafe void ProcessFrameOutput(AudioFrame frame)
 {
     using (var buffer = frame.LockBuffer(AudioBufferAccessMode.Read))
         using (var reference = buffer.CreateReference())
         {
             // Get hold of the buffer pointer.
             byte *dataInBytes;
             uint  capacityInBytes;
             ((IMemoryBufferByteAccess)reference).GetBuffer(
                 out dataInBytes, out capacityInBytes);
             var dataInFloat = (float *)dataInBytes;
             for (var n = 0; n + 1 < _audioGraph.SamplesPerQuantum; n++)
             {
                 _fftProvider.Add(dataInFloat[n], dataInFloat[n++]);
                 //max = Math.Max(Math.Abs(dataInFloat[n]), max);
             }
         }
 }
Пример #7
0
 /*
  * Add a single block to the FFT data.
  */
 public void Add(float left, float right)
 {
     fftProvider.Add(left, right);
 }
Пример #8
0
 private void SingleBlockRead(object sender, SingleBlockReadEventArgs e)
 => fftProvider.Add(e.Left, e.Right);
Пример #9
0
        public string GetLevelsFromAudioFX(string audioType, string audioFile)
        {
            string audioFilename  = Path.Combine(Executor.Current.ExpanderSharedFiles, audioType, audioFile);
            string levelsFilename = Path.Combine(Executor.Current.ExpanderSharedFiles, audioType, audioFile + ".levels");

            if (!File.Exists(levelsFilename))
            {
                using (ISampleSource source = CodecFactory.Instance.GetCodec(audioFilename).ToSampleSource())
                {
                    var fftProvider = new FftProvider(source.WaveFormat.Channels, FftSize.Fft1024);

                    int millisecondsPerFrame = 1000 / 40;

                    long maxBufferLengthInSamples = source.GetRawElements(millisecondsPerFrame);

                    long bufferLength = Math.Min(source.Length, maxBufferLengthInSamples);

                    float[] buffer = new float[bufferLength];

                    int read             = 0;
                    int totalSamplesRead = 0;

                    var fftData = new float[1024];

                    var   list    = new List <float>();
                    float highest = 0;
                    do
                    {
                        //determine how many samples to read
                        int samplesToRead = (int)Math.Min(source.Length - totalSamplesRead, buffer.Length);

                        read = source.Read(buffer, 0, samplesToRead);
                        if (read == 0)
                        {
                            break;
                        }

                        totalSamplesRead += read;

                        //add read data to the fftProvider
                        fftProvider.Add(buffer, read);

                        fftProvider.GetFftData(fftData);

                        float highestAmplitude = 0;
                        for (int i = 0; i < fftData.Length / 2; i++)
                        {
                            if (fftData[i] > highestAmplitude)
                            {
                                highestAmplitude = fftData[i];
                            }
                        }

                        list.Add(highestAmplitude);
                        if (highestAmplitude > highest)
                        {
                            highest = highestAmplitude;
                        }
                    } while (totalSamplesRead < source.Length);

                    if (highest > 0)
                    {
                        // Adjust to equalize
                        float adjustment = 1 / highest;

                        for (int i = 0; i < list.Count; i++)
                        {
                            list[i] *= adjustment;
                        }
                    }

                    using (var fs = File.Create(levelsFilename))
                    {
                        fs.Write(list.Select(x => (byte)(x * 255)).ToArray(), 0, list.Count);
                    }
                }
            }

            return(levelsFilename);
        }
Пример #10
0
 public void SingleBlockRead(Object sender, SingleBlockReadEventArgs args)
 {
     fft.Add(args.Left, args.Right);
 }
Пример #11
0
        /// <summary>
        /// Entry point
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            // Validate cmd line args
            if (args.Length != 1)
            {
                Console.WriteLine("Provide a valid music file location (mp3, wav, or m4a)");
                return;
            }

            string filename = args[0];

            if (!File.Exists(filename))
            {
                Console.Error.WriteLine("Could not find file: '{0}'", filename);
                return;
            }

            // Read in audio file and initialize fft
            IWaveSource   waveSource;
            ISampleSource sampleSource;

            try
            {
                waveSource = CodecFactory.Instance.GetCodec(filename);
            }
            catch (NotSupportedException ex)
            {
                Console.Error.WriteLine("No supporting decoder for given file: '{0}'\n", filename);
                Console.Error.WriteLine(ex.ToString());
                return;
            }

            sampleSource = waveSource.ToSampleSource();

            FftProvider fftProvider = new FftProvider(sampleSource.WaveFormat.Channels, FftSize.Fft1024);
            List <Tuple <int, Complex[]> > fftResults = new List <Tuple <int, Complex[]> >();
            int i = 0;

            // Scrub through the audio 1024 samples at a time and perform fft on each chunk
            while (sampleSource.Position < sampleSource.Length)
            {
                float[] samples = new float[1024];
                sampleSource.Read(samples, 0, 1024);
                fftProvider.Add(samples, samples.Count());

                Complex[] result = new Complex[(int)fftProvider.FftSize];
                if (fftProvider.GetFftData(result))
                {
                    fftResults.Add(new Tuple <int, Complex[]>(i, result));
                    ++i;
                }
            }

            Console.WriteLine("FFT done");

            // Stores the fundamental frequency and amplitude at each frame (1024 samples)
            List <Tuple <double, double> > fundFreqs = new List <Tuple <double, double> >();

            i = 0;

            // For each fft output
            foreach (var pair in fftResults)
            {
                // The output of the fft has a frequency domain and amplitude range.
                // In this case, the index of the value represents frequency: index * ((sampleRate / 2) / (vals.Length / 2))
                // The value at an index is the amplitude as a complex number. To normalize, calculate: sqrt(real^2 + imaginary^2), this can then be
                // used to calculate dB level with dBspl equation (20 * log10(normal))
                Complex[] vals = pair.Item2;

                // Frequency buckets produced by fft. Size of each bucket depends on sample rate.
                // 0 to N/2 of fft output is what we want, N/2 to N is garbage (negative frequencies)
                int nyquistLength = vals.Length / 2;

                // Nyquist rate is maximum possible reproducible sample frequency of a given sample rate
                int nyquistRate = sampleSource.WaveFormat.SampleRate / 2;


                // Normalize the amplitudes
                double[] normals = new double[nyquistLength];

                for (int j = 0; j < nyquistLength; ++j)
                {
                    normals[j] = Math.Sqrt(Math.Pow(vals[j].Real, 2) + Math.Pow(vals[j].Imaginary, 2));
                }

                // Find the fundamental frequency and amplitude of that frequency
                double fundFreq  = 0;
                double amplitude = double.NegativeInfinity; // in dB spl

                int freqBucket = MaxIndex(normals);
                if (freqBucket > 0)
                {
                    fundFreq = freqBucket * (nyquistRate / nyquistLength);
                }
                if (fundFreq != 0)
                {
                    amplitude = 20 * Math.Log10(normals[freqBucket]);   // Convert to dB
                }

                fundFreqs.Add(new Tuple <double, double>(fundFreq, amplitude));
                ++i;
            }

            Console.WriteLine("Fundamental frequency analysis of each frame done");

            Console.WriteLine("Writing results to csv (timestamp,frequency,amplitude)...");

            FileStream   outFileStream = null;
            StreamWriter writer        = null;

            try
            {
                outFileStream = File.Create("out.csv");
                writer        = new StreamWriter(outFileStream);

                for (int j = 0; j < fundFreqs.Count; ++j)
                {
                    writer.WriteLine(string.Format("{0},{1},{2}", FrameIndexToTimestamp(j, sampleSource.WaveFormat.SampleRate, 1024), fundFreqs[j].Item1, fundFreqs[j].Item2));
                }

                writer.Close();
                outFileStream.Close();
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("failed to write output:");
                Console.Error.WriteLine(ex.ToString());

                if (outFileStream != null)
                {
                    outFileStream.Close();
                }
                if (writer != null)
                {
                    writer.Close();
                }
            }

            Console.WriteLine("Done");
            Console.ReadKey(true);
        }
Пример #12
0
 public override void Add(float[] samples, int count)
 {
     m_Fft.Add(samples, count);
 }