/// <summary> /// Helper function to go from IWaveProvider to a SampleProvider /// Must already be PCM or IEEE float /// </summary> /// <param name="waveProvider">The WaveProvider to convert</param> /// <returns>A sample provider</returns> public static ISampleProvider ConvertWaveProviderIntoSampleProvider(IWaveProvider waveProvider) { ISampleProvider sampleProvider; if (waveProvider.WaveFormat.Encoding == WaveFormatEncoding.Pcm) { // go to float if (waveProvider.WaveFormat.BitsPerSample == 8) { sampleProvider = new Pcm8BitToSampleProvider(waveProvider); } else if (waveProvider.WaveFormat.BitsPerSample == 16) { sampleProvider = new Pcm16BitToSampleProvider(waveProvider); } else if (waveProvider.WaveFormat.BitsPerSample == 24) { sampleProvider = new Pcm24BitToSampleProvider(waveProvider); } else { throw new InvalidOperationException("Unsupported operation"); } } else if (waveProvider.WaveFormat.Encoding == WaveFormatEncoding.IeeeFloat) { sampleProvider = new WaveToSampleProvider(waveProvider); } else { throw new ArgumentException("Unsupported source encoding"); } return sampleProvider; }
public static SampleSource CreateFromWaveFile(string fileName) { using (var reader = new WaveFileReader(fileName)) { ISampleProvider sp; int sourceSamples; if (reader.WaveFormat.Encoding == WaveFormatEncoding.Pcm) { if (reader.WaveFormat.BitsPerSample == 16) { sp = new Pcm16BitToSampleProvider(reader); sourceSamples = (int)(reader.Length / 2); } else if (reader.WaveFormat.BitsPerSample == 24) { sp = new Pcm24BitToSampleProvider(reader); sourceSamples = (int)(reader.Length / 3); } else { throw new ArgumentException("Currently only 16 or 24 bit PCM samples are supported"); } } else if (reader.WaveFormat.Encoding == WaveFormatEncoding.IeeeFloat) { sp = new WaveToSampleProvider(reader); sourceSamples = (int)(reader.Length / 4); } else { throw new ArgumentException("Must be PCM or IEEE float"); } float[] sampleData = new float[sourceSamples]; int n = sp.Read(sampleData, 0, sourceSamples); if (n != sourceSamples) { throw new InvalidOperationException(String.Format("Couldn't read the whole sample, expected {0} samples, got {1}", n, sourceSamples)); } SampleSource ss = new SampleSource(sampleData, sp.WaveFormat); return ss; } }
/// <summary> /// Helper function to go from IWaveProvider to a SampleProvider /// Must already be PCM or IEEE float /// </summary> /// <param name="waveProvider">The WaveProvider to convert</param> /// <returns>A sample provider</returns> public static ISampleProvider ConvertWaveProviderIntoSampleProvider(IWaveProvider waveProvider) { ISampleProvider sampleProvider; if (waveProvider.WaveFormat.Encoding == WaveFormatEncoding.Pcm) { // go to float if (waveProvider.WaveFormat.BitsPerSample == 8) { sampleProvider = new Pcm8BitToSampleProvider(waveProvider); } else if (waveProvider.WaveFormat.BitsPerSample == 16) { sampleProvider = new Pcm16BitToSampleProvider(waveProvider); } else if (waveProvider.WaveFormat.BitsPerSample == 24) { sampleProvider = new Pcm24BitToSampleProvider(waveProvider); } else { throw new InvalidOperationException("Unsupported operation"); } } else if (waveProvider.WaveFormat.Encoding == WaveFormatEncoding.IeeeFloat) { sampleProvider = new WaveToSampleProvider(waveProvider); } else { throw new ArgumentException("Unsupported source encoding"); } return(sampleProvider); }
public static float[] BuildPeaks(UWavePart part, System.ComponentModel.BackgroundWorker worker) { const double peaksRate = 4000; System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Start(); float[] peaks; using (var stream = new AudioFileReader(part.FilePath)) { int channels = part.Channels; double peaksSamples = (int)((double)stream.Length / stream.WaveFormat.BlockAlign / stream.WaveFormat.SampleRate * peaksRate); peaks = new float[(int)(peaksSamples + 1) * channels]; double blocksPerPixel = stream.Length / stream.WaveFormat.BlockAlign / peaksSamples; var converted = new WaveToSampleProvider(stream); float[] buffer = new float[4096]; int readed; int readPos = 0; int peaksPos = 0; double bufferPos = 0; float lmax = 0, lmin = 0, rmax = 0, rmin = 0; while ((readed = converted.Read(buffer, 0, 4096)) != 0) { readPos += readed; for (int i = 0; i < readed; i += channels) { lmax = Math.Max(lmax, buffer[i]); lmin = Math.Min(lmin, buffer[i]); if (channels > 1) { rmax = Math.Max(rmax, buffer[i + 1]); rmin = Math.Min(rmin, buffer[i + 1]); } if (i > bufferPos) { lmax = -lmax; lmin = -lmin; rmax = -rmax; rmin = -rmin; // negate peaks to fipped waveform peaks[peaksPos * channels] = lmax == 0 ? lmin : lmin == 0 ? lmax : (lmin + lmax) / 2; peaks[peaksPos * channels + 1] = rmax == 0 ? rmin : rmin == 0 ? rmax : (rmin + rmax) / 2; peaksPos++; lmax = lmin = rmax = rmin = 0; bufferPos += blocksPerPixel * stream.WaveFormat.Channels; } } bufferPos -= readed; worker.ReportProgress((int)((double)readPos * sizeof(float) * 100 / stream.Length)); } } sw.Stop(); System.Diagnostics.Debug.WriteLine("Build peaks {0} ms", sw.Elapsed.TotalMilliseconds); return peaks; }
public static ISampleProvider ConvertWaveProviderIntoSampleProvider(IWaveProvider waveProvider) { ISampleProvider result; if (waveProvider.WaveFormat.Encoding == WaveFormatEncoding.Pcm) { if (waveProvider.WaveFormat.BitsPerSample == 8) { result = new Pcm8BitToSampleProvider(waveProvider); } else if (waveProvider.WaveFormat.BitsPerSample == 16) { result = new Pcm16BitToSampleProvider(waveProvider); } else if (waveProvider.WaveFormat.BitsPerSample == 24) { result = new Pcm24BitToSampleProvider(waveProvider); } else { if (waveProvider.WaveFormat.BitsPerSample != 32) { throw new InvalidOperationException("Unsupported bit depth"); } result = new Pcm32BitToSampleProvider(waveProvider); } } else { if (waveProvider.WaveFormat.Encoding != WaveFormatEncoding.IeeeFloat) { throw new ArgumentException("Unsupported source encoding"); } if (waveProvider.WaveFormat.BitsPerSample == 64) { result = new WaveToSampleProvider64(waveProvider); } else { result = new WaveToSampleProvider(waveProvider); } } return(result); }
/// <summary> /// Initialises a new instance of SampleChannel /// </summary> /// <param name="waveProvider">Source wave provider, must be PCM or IEEE</param> public SampleChannel(IWaveProvider waveProvider) { ISampleProvider sampleProvider; if (waveProvider.WaveFormat.Encoding == WaveFormatEncoding.Pcm) { // go to float if (waveProvider.WaveFormat.BitsPerSample == 8) { sampleProvider = new Pcm8BitToSampleProvider(waveProvider); } else if (waveProvider.WaveFormat.BitsPerSample == 16) { sampleProvider = new Pcm16BitToSampleProvider(waveProvider); } else if (waveProvider.WaveFormat.BitsPerSample == 24) { sampleProvider = new Pcm24BitToSampleProvider(waveProvider); } else { throw new InvalidOperationException("Unsupported operation"); } } else if (waveProvider.WaveFormat.Encoding == WaveFormatEncoding.IeeeFloat) { sampleProvider = new WaveToSampleProvider(waveProvider); } else { throw new ArgumentException("Unsupported source encoding"); } if (sampleProvider.WaveFormat.Channels == 1) { sampleProvider = new MonoToStereoSampleProvider(sampleProvider); } this.waveFormat = sampleProvider.WaveFormat; // let's put the meter before the volume (useful for drawing waveforms) this.preVolumeMeter = new MeteringSampleProvider(sampleProvider); this.volumeProvider = new VolumeSampleProvider(preVolumeMeter); }
private void _play() { /* Audio chain */ // Sampling _wavesampler = new WaveToSampleProvider(new Wave16ToFloatProvider(_wavebuffer)); // Fading component _fade = new FadeInOutSampleProvider(_wavesampler); _fade.BeginFadeIn(1500); // Notifying component var _notify = new NotifyingSampleProvider(_fade); _notify.Sample += new EventHandler<SampleEventArgs>(_notify_Sample); // Gain adjustment component _volume = new VolumeSampleProvider(_notify); _volume.Volume = this.Volume; // Output Output.Init(new SampleToWaveProvider16(_volume)); /* Playback loop */ do { if (_cancel_play.IsCancellationRequested) { Console.WriteLine("[Playback thread] Cancellation requested."); // Fade out and stop Console.WriteLine("[Playback thread] Fading out and stopping..."); _fade.BeginFadeOut(500); Thread.Sleep(500); Output.Stop(); Console.WriteLine("[Playback thread] Output stopped."); this.Status = StreamStatus.Stopped; Console.WriteLine("[Playback thread] Acknowledged as status."); //_cancel_play_token.ThrowIfCancellationRequested(); //Console.WriteLine("[Playback thread] WARNING: Cancellation token is not cleanly set!"); return; } if (Output.PlaybackState != PlaybackState.Playing && _wavebuffer.BufferedDuration.TotalMilliseconds > 2750) { // Buffer is filled enough Console.WriteLine("[Playback thread] Buffer is okay now, start playback!"); this.Status = StreamStatus.Playing; Output.Play(); } else if (Output.PlaybackState == PlaybackState.Playing && _wavebuffer.BufferedDuration.TotalMilliseconds < 2250) { // Buffer is underrunning Console.WriteLine("[Playback thread] Buffer is underrunning, pausing playback..."); this.Status = StreamStatus.Buffering; Output.Pause(); } if (_bufferThread.Exception != null) { Console.WriteLine("[Playback thread] Buffering thread is faulted, aborting playback"); throw new Exception("Buffering thread faulted, aborting playback"); } Thread.Sleep(100); } while (true); }
public static SampleSource[] CreateFromWaveFile(string fileName) { using (var reader = new WaveFileReader(fileName)) { ISampleProvider sp; int sourceSamples; if (reader.WaveFormat.Encoding == WaveFormatEncoding.Pcm) { if (reader.WaveFormat.BitsPerSample == 16) { sp = new Pcm16BitToSampleProvider(reader); sourceSamples = (int)(reader.Length / 2); } else if (reader.WaveFormat.BitsPerSample == 24) { sp = new Pcm24BitToSampleProvider(reader); sourceSamples = (int)(reader.Length / 3); } else { throw new ArgumentException("Currently only 16 or 24 bit PCM samples are supported"); } } else if (reader.WaveFormat.Encoding == WaveFormatEncoding.IeeeFloat) { sp = new WaveToSampleProvider(reader); sourceSamples = (int)(reader.Length / 4); } else { throw new ArgumentException("Must be PCM or IEEE float"); } float[] sampleData = new float[sourceSamples]; int n = sp.Read(sampleData, 0, sourceSamples); if (n != sourceSamples) { throw new InvalidOperationException(String.Format("Couldn't read the whole sample, expected {0} samples, got {1}", n, sourceSamples)); } SampleSource[] result = new SampleSource[9]; // Normal pitch int normal = 4; result[normal] = new SampleSource(sampleData, sp.WaveFormat); int pitch = 5; for (int currentPitch = 0; currentPitch < normal; currentPitch++, pitch--) { float[] changedPitchData = new float[sampleData.Length/pitch]; for (int j = 0, i = 0; i < sampleData.Length && j < changedPitchData.Length; i++) { if (i % pitch == 0) { changedPitchData[j] = sampleData[i]; j++; } } result[currentPitch] = new SampleSource(changedPitchData, sp.WaveFormat); } pitch = 2; for (int currentPitch = normal+1; currentPitch < result.Length; currentPitch++, pitch++) { float[] changedPitchData = new float[sampleData.Length * pitch]; for (int j = 0, i = 0; i < sampleData.Length && j < changedPitchData.Length; j++) { changedPitchData[j] = sampleData[i]; if (j % pitch == 0) { i++; } } result[currentPitch] = new SampleSource(changedPitchData, sp.WaveFormat); } return result; } }