public void ReadIntoSpread(CancellationToken ct) { var channels = FAudioFile.WaveFormat.Channels; long samples = (long)Math.Round(FAudioFile.TotalTime.TotalSeconds * FAudioFile.WaveFormat.SampleRate); long startSample = 0; if (Loop) { startSample = (long)(StartTime * FAudioFile.WaveFormat.SampleRate); samples = (long)((EndTime - StartTime) * FAudioFile.WaveFormat.SampleRate); } var localSpreadCount = (int)Math.Min(SpreadCount, samples); if (ToMono) { WaveFormSpread.SliceCount = 1; WaveFormSpread[0] = new Spread <double>(localSpreadCount); } else { WaveFormSpread.SliceCount = channels; for (int i = 0; i < channels; i++) { WaveFormSpread[i] = new Spread <double>(localSpreadCount); } } int blockSize = (int)(samples / localSpreadCount); FAudioFile.Position = startSample * channels * 4; var bufferSize = blockSize * channels; var buffer = new float[bufferSize]; var maxValue = 0.0f; var outputBuffers = WaveFormSpread.Select(s => s.Stream.Buffer).ToArray(); for (int slice = 0; slice < localSpreadCount; slice++) { //read one interleaved block var samplesRead = FAudioFile.Read(buffer, 0, bufferSize); //split into channels and do the max for (int channel = 0; channel < channels; channel++) { maxValue = MinValue; for (int i = 0; i < samplesRead; i += channels) { maxValue = Math.Max(maxValue, Math.Abs(buffer[i + channel])); } if (ToMono) { outputBuffers[0][slice] = Math.Max(maxValue, outputBuffers[0][slice]); } else { outputBuffers[channel][slice] = maxValue; } ct.ThrowIfCancellationRequested(); } } }
protected override void FillBuffers(float[][] buffer, int offset, int sampleCount) { if (FAudioFile == null) { return; } var channels = FAudioFile.WaveFormat.Channels; var blockAlign = FAudioFile.OriginalFileFormat.BlockAlign; int samplesToRead; if (Speed == 1.0) { samplesToRead = sampleCount * channels; } else { var desiredSamples = sampleCount * channels * Speed; //ideal value samplesToRead = (int)Math.Truncate(desiredSamples); //can only read that much var rem = samplesToRead % blockAlign; samplesToRead -= rem; FFractionalAccum += (desiredSamples - samplesToRead); //gather error //correct error if (FFractionalAccum >= blockAlign) { samplesToRead += blockAlign; FFractionalAccum -= blockAlign; } } FFileBuffer = BufferHelpers.Ensure(FFileBuffer, samplesToRead); int samplesRead = 0; if (FPlay && samplesToRead > 0) { samplesRead = FAudioFile.Read(FFileBuffer, offset * channels, samplesToRead); if (samplesRead == 0) { if (FLoop) { FAudioFile.CurrentTime = LoopStartTime; FRunToEndBeforeLooping = false; samplesRead = FAudioFile.Read(FFileBuffer, offset * channels, samplesToRead); } else { samplesRead = FFileBuffer.ReadSilence(offset * channels, samplesToRead); } if (FLoop && FAudioFile.CurrentTime >= LoopEndTime) { FAudioFile.CurrentTime = LoopStartTime; FRunToEndBeforeLooping = false; //bytesread = FAudioFile.Read(FFileBuffer, offset*channels, samplesToRead); } } if (Speed == 1.0) { //copy to output buffers for (int i = 0; i < channels; i++) { for (int j = 0; j < sampleCount; j++) { buffer[i][j] = FFileBuffer[i + j * channels]; } } } else //resample { FResampler.ResampleDeinterleave(FFileBuffer, buffer, samplesToRead / channels, sampleCount, channels); } } else //silence { for (int i = 0; i < channels; i++) { buffer[i].ReadSilence(offset, sampleCount); } } }