public async Task <ICanvasImage> RenderAsync(StorageFile selectedFile, IPeakProvider peakProvider, WaveFormRendererSettings settings) { var randomAcessStream = await selectedFile.OpenReadAsync(); using (var reader = new StreamMediaFoundationReader(randomAcessStream.AsStream())) { int bytesPerSample = (reader.WaveFormat.BitsPerSample / 8); var samples = reader.Length / (bytesPerSample); var samplesPerPixel = (int)(samples / settings.Width); var stepSize = settings.PixelsPerPeak + settings.SpacerPixels; peakProvider.Init(reader.ToSampleProvider(), samplesPerPixel * stepSize); return(Render(peakProvider, settings)); } }
[NotNull] private static MemoryStream NormalizeAudioData(byte[] data) { #if NCRUNCH return(new MemoryStream(data)); #endif //Construct reader which can read the audio (whatever format it is in) var reader = new StreamMediaFoundationReader(new MemoryStream(data)); var sampleProvider = reader.ToSampleProvider(); // find the max peak float max = 0; var buffer = new float[reader.WaveFormat.SampleRate]; int read; do { read = sampleProvider.Read(buffer, 0, buffer.Length); if (read > 0) { max = Math.Max(max, Enumerable.Range(0, read).Select(i => Math.Abs(buffer[i])).Max()); } } while (read > 0); if (Math.Abs(max) < float.Epsilon || max > 1.0f) { throw new InvalidOperationException("Audio normalization failed to find a reasonable peak volume"); } //Write (as wav) with soft clipping and peak volume normalization var output = new MemoryStream((int)(reader.Length * 4)); var input = new SoftClipSampleProvider(new VolumeSampleProvider(sampleProvider) { Volume = 1 / max - 0.05f }); reader.Position = 0; WaveFileWriter.WriteWavFileToStream(output, input.ToWaveProvider16()); return(output); }