//Create samples to scale based on the current timeline ticks period. //Runs in background to keep the ui free. private void bw_createScaleSamples(object sender, DoWorkEventArgs args) { _creatingSamples = true; BackgroundWorker worker = sender as BackgroundWorker; if (audio == null) { _creatingSamples = false; return; } if (!audio.MediaLoaded) { audio.LoadMedia(TimeSpan.MinValue); } samplesPerPixel = (double)pixelsToTime(1).Ticks / TimeSpan.TicksPerMillisecond * audio.Frequency / 1000; int step = audio.BytesPerSample; samples.Clear(); double samplesRead = 0; while (samplesRead < audio.NumberSamples) { if ((worker.CancellationPending)) { args.Cancel = true; break; } int low = 0; int high = 0; //Might need a better way to dither the partial samples out. Casting to int rounds it out while //the counter tries to maintian some sanity. A few random samples might be off at some zoom levels, //but we are doing a fair amount of averaging to begin with. The farther in the zoom the more chances //a artifact might be visible. byte[] waveData = audio.GetSamples((int)samplesRead, (int)samplesPerPixel); samplesRead += samplesPerPixel; if (waveData == null) { break; } for (int n = 0; n < waveData.Length; n += step) { //Allow for 16 or 32 bit data. Should be 16 most of the time. int sample = step == 2 ? BitConverter.ToInt16(waveData, n) : BitConverter.ToInt32(waveData, n); if (sample < low) { low = sample; } if (sample > high) { high = sample; } } samples.Add(new SampleAggregator.Sample { High = ClampValue(high), Low = ClampValue(low) }); } _creatingSamples = false; }
private void waveformGenerateWorker_DoWork() { #if (MARKERS) var span = Markers.EnterSpan("waveformGen"); #endif using (Mp3FileReader waveformMp3Stream = new Mp3FileReader(song.FileName)) using (WaveChannel32 waveformInputStream = new WaveChannel32(waveformMp3Stream)) { waveformInputStream.Sample += waveStream_Sample; int frameCount = (int)((float)waveformInputStream.Length / frameLength); byte[] readBuffer = new byte[frameLength]; waveformAggregator = new SampleAggregator(frameLength); int currentPointIndex = 0; float[] waveformArray = new float[frameCount * 2]; float waveformLeftMax = 0; float waveformRightMax = 0; while (currentPointIndex < frameCount * 2) { waveformInputStream.Read(readBuffer, 0, readBuffer.Length); var leftMaxVolume = waveformAggregator.LeftMaxVolume; var rightMaxVolume = waveformAggregator.RightMaxVolume; waveformArray[currentPointIndex++] = leftMaxVolume; waveformArray[currentPointIndex++] = rightMaxVolume; if (leftMaxVolume > waveformLeftMax) { waveformLeftMax = leftMaxVolume; } if (rightMaxVolume > waveformRightMax) { waveformRightMax = rightMaxVolume; } waveformAggregator.Clear(); tkn.ThrowIfCancellationRequested(); } byte[] waveformBytes = new byte[waveformArray.Length]; float factor = 31f / Math.Max(Math.Abs(waveformLeftMax), Math.Abs(waveformRightMax)); for (int ndx = 0; ndx < waveformArray.Length; ndx++) { waveformBytes[ndx] = (byte)Math.Abs(Math.Abs(waveformArray[ndx]) * factor); } song.WaveformData = waveformBytes; } #if (MARKERS) span.Leave(); #endif }
private void inputStream_Sample(object sender, SampleEventArgs e) { sampleAggregator.Add(e.Left, e.Right); long repeatStartPosition = (long)((SelectionBegin.TotalSeconds / ActiveStream.TotalTime.TotalSeconds) * ActiveStream.Length); long repeatStopPosition = (long)((SelectionEnd.TotalSeconds / ActiveStream.TotalTime.TotalSeconds) * ActiveStream.Length); if (((SelectionEnd - SelectionBegin) >= TimeSpan.FromMilliseconds(repeatThreshold)) && ActiveStream.Position >= repeatStopPosition) { sampleAggregator.Clear(); ActiveStream.Position = repeatStartPosition; } }
private void waveformGenerateWorker_DoWork(object sender, DoWorkEventArgs e) { WaveformGenerationParams waveformParams = e.Argument as WaveformGenerationParams; Mp3FileReader waveformMp3Stream = new Mp3FileReader(waveformParams.Path); WaveChannel32 waveformInputStream = new WaveChannel32(waveformMp3Stream); waveformInputStream.Sample += waveStream_Sample; int frameCount = (int)((double)waveformInputStream.Length / (double)frameLength); byte[] readBuffer = new byte[frameLength]; waveformAggregator = new SampleAggregator(frameLength); int currentPointIndex = 0; float[] waveformArray = new float[frameCount * 2]; float waveformLeftMax = 0; float waveformRightMax = 0; int readCount = 0; while (currentPointIndex < frameCount * 2) { waveformInputStream.Read(readBuffer, 0, readBuffer.Length); waveformArray[currentPointIndex++] = waveformAggregator.LeftMaxVolume; waveformArray[currentPointIndex++] = waveformAggregator.RightMaxVolume; if (waveformAggregator.LeftMaxVolume > waveformLeftMax) { waveformLeftMax = waveformAggregator.LeftMaxVolume; } if (waveformAggregator.RightMaxVolume > waveformRightMax) { waveformRightMax = waveformAggregator.RightMaxVolume; } waveformAggregator.Clear(); if (waveformGenerateWorker.CancellationPending) { e.Cancel = true; break; } readCount++; } byte[] waveformBytes = new byte[waveformArray.Length]; float factor = 31f / Math.Max(Math.Abs(waveformLeftMax), Math.Abs(waveformRightMax)); for (int ndx = 0; ndx < waveformArray.Length; ndx++) { waveformBytes[ndx] = (byte)Math.Abs(Math.Abs(waveformArray[ndx]) * factor); } //UI.Invoke(new Action(() => { WaveformData = waveformBytes; })); waveformData = waveformBytes; waveformInputStream.Close(); waveformInputStream.Dispose(); waveformInputStream = null; waveformMp3Stream.Close(); waveformMp3Stream.Dispose(); waveformMp3Stream = null; }