mirror of
https://github.com/unclshura/ABStemPlayer.git
synced 2026-08-07 00:43:38 +00:00
63 lines
1.6 KiB
C#
63 lines
1.6 KiB
C#
using AudioCore.Impl;
|
|
|
|
public sealed class StemDecoder : IStemDecoder
|
|
{
|
|
private readonly IAudioReader _reader;
|
|
private readonly AudioBufferPool _pool;
|
|
private readonly int _blockSize;
|
|
private long _currentSample;
|
|
|
|
public StemTrack Stem { get; }
|
|
|
|
public StemDecoder(
|
|
IAudioReader reader,
|
|
AudioBufferPool pool,
|
|
StemTrack stem,
|
|
int blockSize = 4096)
|
|
{
|
|
_reader = reader;
|
|
_pool = pool;
|
|
_blockSize = blockSize;
|
|
Stem = stem;
|
|
|
|
Stem.Channels = reader.Channels;
|
|
Stem.SampleRate = reader.SampleRate;
|
|
Stem.Duration = TimeSpan.FromSeconds((double)reader.TotalSamples / reader.SampleRate);
|
|
}
|
|
|
|
public async Task<AudioBlock?> DecodeNextBlockAsync(CancellationToken token)
|
|
{
|
|
int channels = _reader.Channels;
|
|
int floatsNeeded = _blockSize * channels;
|
|
|
|
var buf = _pool.Rent(floatsNeeded);
|
|
|
|
// Async read into Memory<float>
|
|
int readFloats = await _reader.ReadAsync(buf.Samples.AsMemory(0, floatsNeeded), token)
|
|
.ConfigureAwait(false);
|
|
|
|
if (readFloats <= 0)
|
|
{
|
|
buf.Dispose();
|
|
return null;
|
|
}
|
|
|
|
buf.Length = readFloats;
|
|
|
|
long pos = _currentSample;
|
|
_currentSample += readFloats / channels;
|
|
|
|
return new AudioBlock(buf, _reader.SampleRate, channels, pos);
|
|
}
|
|
|
|
public void Seek(long samplePosition)
|
|
{
|
|
_reader.Seek(samplePosition);
|
|
_currentSample = samplePosition;
|
|
}
|
|
|
|
public void Reset() => Seek(0);
|
|
|
|
public void Dispose() => _reader.Dispose();
|
|
}
|