Exemple #1
0
        private Task Run()
        {
            return(Task.Run(async() =>
            {
                try
                {
                    while (!_isPreloaded && !_cancelToken.IsCancellationRequested)
                    {
                        await Task.Delay(1).ConfigureAwait(false);
                    }

                    long nextTick = Environment.TickCount;
                    ushort seq = 0;
                    uint timestamp = 0;
                    while (!_cancelToken.IsCancellationRequested)
                    {
                        long tick = Environment.TickCount;
                        long dist = nextTick - tick;
                        if (dist <= 0)
                        {
                            if (_queuedFrames.TryDequeue(out Frame frame))
                            {
                                await _client.SetSpeakingAsync(true).ConfigureAwait(false);
                                _next.WriteHeader(seq, timestamp, false);
                                await _next.WriteAsync(frame.Buffer, 0, frame.Bytes).ConfigureAwait(false);
                                _bufferPool.Enqueue(frame.Buffer);
                                _queueLock.Release();
                                nextTick += _ticksPerFrame;
                                seq++;
                                timestamp += OpusEncoder.FrameSamplesPerChannel;
                                _silenceFrames = 0;
#if DEBUG
                                var _ = _logger?.DebugAsync($"Sent {frame.Bytes} bytes ({_queuedFrames.Count} frames buffered)");
#endif
                            }
                            else
                            {
                                while ((nextTick - tick) <= 0)
                                {
                                    if (_silenceFrames++ < MaxSilenceFrames)
                                    {
                                        _next.WriteHeader(seq, timestamp, false);
                                        await _next.WriteAsync(_silenceFrame, 0, _silenceFrame.Length).ConfigureAwait(false);
                                    }
                                    else
                                    {
                                        await _client.SetSpeakingAsync(false).ConfigureAwait(false);
                                    }
                                    nextTick += _ticksPerFrame;
                                    seq++;
                                    timestamp += OpusEncoder.FrameSamplesPerChannel;
                                }
#if DEBUG
                                var _ = _logger?.DebugAsync("Buffer underrun");
#endif
                            }
                        }
                        else
                        {
                            await Task.Delay((int)(dist) /*, _cancelToken*/).ConfigureAwait(false);
                        }
                    }
                }
                catch (OperationCanceledException) { }
            }));
        }