public override int Read(float[] buffer, int offset, int count) { var playbackState = this.playbackToken.State; if (playbackState == PlaybackState.StopRequested || this.isAudioFileReaderDisposed || this.audioData.FilePath == null || this.reader == null) { DisposeReader(); this.playbackToken.State = PlaybackState.Stopped; return(0); } float volume = this.audioData.Volume * this.volume * this.masterVolumeProvider.MasterVolume; int read = this.stream.Read(buffer, offset, count); if (read == 0) { if (playbackState == PlaybackState.PlayingInLoop) { this.reader.Position = 0; this.playbackToken.IncrementLoopCount(); } else { DisposeReader(); this.playbackToken.State = PlaybackState.Stopped; } } else if (AudioPlayer.EqualsVolume(volume, 0.0f)) { Array.Clear(buffer, offset, read); } else if (!AudioPlayer.EqualsVolume(volume, 1.0f)) { if (!this.useParallel) { for (long i = 0; i < read; i++) { buffer[offset + i] *= volume; } } else { Parallel.For(0, read, (i) => { buffer[offset + i] *= volume; }); } } // If loop mode is enabled, remaining area of buffer is zero filled. // This is a reasonable way, but there may be a very small difference according to source audio data. if (playbackState == PlaybackState.PlayingInLoop && read < count) { Array.Clear(buffer, (offset + read), (count - read)); read = count; } return(read); }
public override int Read(float[] buffer, int offset, int count) { var playbackState = this.playbackToken.State; if (playbackState == PlaybackState.StopRequested) { this.playbackToken.State = PlaybackState.Stopped; return(0); } var source = this.audioData.Data; if (source == null) { return(0); } float volume = this.audioData.Volume * this.volume * this.masterVolumeProvider.MasterVolume; long availableSamples = source.Length - position; long samplesToCopy = Math.Min(availableSamples, count); if (AudioPlayer.EqualsVolume(volume, 0.0f)) { Array.Clear(buffer, offset, (int)samplesToCopy); } else if (AudioPlayer.EqualsVolume(volume, 1.0f)) { Array.Copy(source, position, buffer, offset, samplesToCopy); } else { if (!this.useParallel) { for (long i = 0; i < samplesToCopy; i++) { buffer[offset + i] = source[position + i] * volume; } } else { Parallel.For(0, samplesToCopy, (i) => { buffer[offset + i] = source[position + i] * volume; }); } } position += samplesToCopy; // If loop mode is enabled, remaining area of buffer is zero filled. // This is a reasonable way, but there may be a very small difference according to source audio data. if (playbackState == PlaybackState.PlayingInLoop) { if (position >= source.Length) { position = 0; this.playbackToken.IncrementLoopCount(); } int toBeFilled = (int)(count - samplesToCopy); if (toBeFilled > 0) { Array.Clear(buffer, (int)(offset + samplesToCopy), toBeFilled); } samplesToCopy = count; } else if (samplesToCopy < count) { this.playbackToken.State = PlaybackState.Stopped; } return((int)samplesToCopy); }