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); } }
//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(); }
private void SingleBlockNotificationStreamOnSingleBlockRead(object sender, SingleBlockReadEventArgs e) { lock (_lockObject) { _left.Add(e.Left); _right.Add(e.Right); _fftProvider.Add(e.Left, e.Right); } }
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; } }
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; }
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); } } }
/* * Add a single block to the FFT data. */ public void Add(float left, float right) { fftProvider.Add(left, right); }
private void SingleBlockRead(object sender, SingleBlockReadEventArgs e) => fftProvider.Add(e.Left, e.Right);
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); }
public void SingleBlockRead(Object sender, SingleBlockReadEventArgs args) { fft.Add(args.Left, args.Right); }
/// <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); }
public override void Add(float[] samples, int count) { m_Fft.Add(samples, count); }