12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- using NAudio.Wave;
- using System;
- using System.Collections.Generic;
- namespace SongVocalSectionAnalyser.AudioAnalysis
- {
- public class SongDataWaveProvider : IWaveProvider
- {
- private readonly IReadOnlyList<short> _samples;
- private readonly int _endSample;
- public event Action<int> Playing;
- public SongDataWaveProvider(SongData data, TimeSpan? begin = null, TimeSpan? end = null)
- {
- WaveFormat = new WaveFormat(data.SampleRate, 16, 1);
- _samples = data.Samples;
- var maxTime = (float)_samples.Count / data.SampleRate;
- if (begin.HasValue)
- {
- if (begin.Value.TotalSeconds > maxTime) throw new ArgumentOutOfRangeException(nameof(begin));
- _currentSample = (int)(begin.Value.TotalSeconds * data.SampleRate);
- }
- else
- {
- _currentSample = 0;
- }
- _endSample = end.HasValue && end.Value.TotalSeconds < maxTime
- ? (int)Math.Ceiling(end.Value.TotalSeconds * data.SampleRate)
- : _samples.Count;
- }
- private int _currentSample;
- private bool _hiByte;
- public int Read(byte[] buffer, int offset, int count)
- {
- if (_currentSample == _endSample)
- {
- OnPlaying();
- return 0;
- }
- OnPlaying();
- var read = 0;
- for (var i = 0; i < count; i++)
- {
- if (_currentSample == _endSample) break;
- buffer[i] = _hiByte
- ? (byte)(_samples[_currentSample] >> 8)
- : (byte)(_samples[_currentSample]);
- if (_hiByte)
- {
- OnPlaying();
- ++_currentSample;
- }
- _hiByte = !_hiByte;
- ++read;
- }
- return read;
- }
- public WaveFormat WaveFormat { get; }
- protected virtual void OnPlaying()
- {
- Playing?.Invoke(_currentSample);
- }
- }
- }
|