Beispiel #1
0
        protected override async Task <int> DoReadAsync(byte[] outputBuffer, int offset, int count, CancellationToken cancellationToken)
        {
            while (_bytesInBuffer < count)
            {
                var byteCount = await _clip.ReadAsync(_buffer, 0, _buffer.Length, cancellationToken);

                if (byteCount == 0)
                {
                    break;
                }

                // Write to buffer stream and seek back the number of bytes we wrote
                var current = _bufferStream.Position;
                _bufferStream.Seek(0, SeekOrigin.End);
                await _bufferStream.WriteAsync(_buffer, 0, byteCount, cancellationToken);

                _bufferStream.Seek(current, SeekOrigin.Begin);
                _bytesInBuffer += byteCount;
            }

            var bytesToRead = (int)Math.Min(_bytesInBuffer, count);

            _bytesInBuffer -= bytesToRead;
            return(await _bufferStream.ReadAsync(outputBuffer, offset, bytesToRead, cancellationToken));
        }
Beispiel #2
0
        protected override async Task <int> DoReadAsync(byte[] outputBuffer, int offset, int count, CancellationToken cancellationToken)
        {
            void _complete()
            {
                _ = _currentClip.DisposeAsync();
                _playlist.Remove(_currentClip);
                _currentClip = null;
                OnClipCompleted?.Invoke(this, _currentClip);
            }

            // Check if the current song should be skipped
            if (_shouldSkip)
            {
                _shouldSkip = false;
                _complete();
            }

            // Check if any items need to start preparing
            if (_playlist.Count(p => (p.IsReady || p.IsPreparing) && p != _currentClip) == 0)
            {
                var toPrepare = _playlist.FirstOrDefault(p => !p.IsReady && !p.IsPreparing);
                if (toPrepare != null)
                {
                    _ = toPrepare.PrepareAsync();
                }
            }

            // Set the current clip to the next clip if necessary
            if (_currentClip == null)
            {
                _currentClip = _playlist.FirstOrDefault(p => p.IsReady);
            }

            if (_currentClip == null)
            {
                return(0);
            }

            var byteCount = await _currentClip.ReadAsync(outputBuffer, offset, count, cancellationToken);

            if (byteCount == 0)
            {
                _complete();
            }

            return(byteCount);
        }
Beispiel #3
0
        public static async Task <int> ReadAsync(this Clip clip, short[] outputBuffer, int offset, int count, CancellationToken cancellationToken)
        {
            var buffer    = new byte[count * 2];
            var bytesRead = await clip.ReadAsync(buffer, 0, buffer.Length, cancellationToken);

            for (int sample = 0; sample < bytesRead / 2; sample++)
            {
                int i = sample * 2;

                short b1 = (short)((buffer[i + 1] & 0xff) << 8);
                short b2 = (short)(buffer[i] & 0xff);

                outputBuffer[sample + offset] = (short)(b1 | b2);
            }

            return(bytesRead / 2);
        }
Beispiel #4
0
        protected override async Task <int> DoReadAsync(byte[] outputBuffer, int offset, int count, CancellationToken cancellationToken)
        {
            var ratio = _inputSampleRate / (double)_outputSampleRate;

            var buffer    = new byte[(int)Math.Ceiling(count * ratio)];
            var byteCount = await _clip.ReadAsync(buffer, 0, buffer.Length, cancellationToken);

            var outputByteCount = (int)(byteCount / ratio);

            for (int sample = 0; sample < outputByteCount / 2; sample++)
            {
                var i = sample * 2;
                var j = (int)(sample * ratio) * 2;
                outputBuffer[i]     = buffer[j];
                outputBuffer[i + 1] = buffer[j + 1];
            }

            return(outputByteCount);
        }
        protected override async Task DoPrepareAsync()
        {
            await _clip.PrepareAsync();

            var cts = new CancellationTokenSource();

            while (true)
            {
                var buffer    = new byte[2880];
                var byteCount = await _clip.ReadAsync(buffer, 0, buffer.Length, cts.Token);

                if (byteCount == 0)
                {
                    break;
                }

                await _stream.WriteAsync(buffer, 0, byteCount, cts.Token);
            }
        }
Beispiel #6
0
        protected override async Task <int> DoReadAsync(byte[] outputBuffer, int offset, int count, CancellationToken cancellationToken)
        {
            var byteCount = await _clip.ReadAsync(outputBuffer, offset, count, cancellationToken);

            for (int i = offset; i < offset + byteCount; i += 2)
            {
                short b1 = (short)((outputBuffer[i + 1] & 0xff) << 8);
                short b2 = (short)(outputBuffer[i] & 0xff);

                short data   = (short)(b1 | b2);
                float sample = data / (float)short.MaxValue;
                data = (short)(sample * short.MaxValue * _volume);

                outputBuffer[i]     = (byte)data;
                outputBuffer[i + 1] = (byte)(data >> 8);
            }

            return(byteCount);
        }
        protected override async Task <int> DoReadAsync(byte[] outputBuffer, int offset, int count, CancellationToken cancellationToken)
        {
            async Task <int> waitAndReturn(CancellationToken cancellationToken)
            {
                await cancellationToken.WhenCancelled();

                throw new OperationCanceledException();
            }

            while (!cancellationToken.IsCancellationRequested && _bytesInBuffer < count)
            {
                var workaround = await Task.WhenAny(
                    _clip.ReadAsync(_buffer, 0, _buffer.Length, cancellationToken),
                    waitAndReturn(cancellationToken)
                    );

                var byteCount = await workaround;
                if (byteCount == 0)
                {
                    break;
                }

                // Write to buffer stream and seek back the number of bytes we wrote
                var current = _bufferStream.Position;
                _bufferStream.Seek(0, SeekOrigin.End);
                await _bufferStream.WriteAsync(_buffer, 0, byteCount, cancellationToken);

                _bufferStream.Seek(current, SeekOrigin.Begin);
                _bytesInBuffer += byteCount;
            }

            cancellationToken.ThrowIfCancellationRequested();

            var bytesToRead = (int)Math.Min(_bytesInBuffer, count);

            _bytesInBuffer -= bytesToRead;
            return(await _bufferStream.ReadAsync(outputBuffer, offset, bytesToRead, cancellationToken));
        }