/// <summary> /// Start service loop. /// </summary> private async Task StartAsyncSend() { Running = true; while (Running) { if (OutStream == null || !OutStream.CanWrite) { Thread.Sleep(100); continue; } try { if (AudioQueue.Count > 0) { byte[] mixed = new byte[AudioHelpers.BUFFER_SIZE * AudioHelpers.CHANNEL_COUNT]; for (int i = 0; i < AudioHelpers.FRAME_SAMPLES; ++i) { int sample = 0; foreach (var audioPair in AudioQueue) { var session = audioPair.Value; if (session.State == ReproductionState.Paused) { continue; } if (session.State == ReproductionState.Stopped) { session.CloseReproduction(); } if (session.State == ReproductionState.Closed || session.EndOfStream) { AudioQueue.TryRemove(audioPair.Key, out var e); continue; } double volume = Math.Max(Math.Min((session.Source?.Volume ?? DefaultAudioSource.Instance.Volume) / 100, 1), 0); double gain = (session.Source?.Gain ?? DefaultAudioSource.Instance.Gain) + 1; byte[] buffer = new byte[AudioHelpers.SAMPLE_SIZE]; if (session.Read(buffer, 0, AudioHelpers.SAMPLE_SIZE) > 0) { sample += (Int32)(AudioHelpers.GetInt16(buffer, 0, true) * volume * gain); } } short sampleValue = (short)Math.Min(Math.Max(short.MinValue, sample), short.MaxValue); AudioHelpers.GetBytes(sampleValue, mixed, i * AudioHelpers.SAMPLE_SIZE, true); } // Send the buffer to Discord await OutStream.WriteAsync(mixed, 0, AudioHelpers.FRAME_SAMPLES *AudioHelpers.CHANNEL_COUNT); } else { // Flush stream await OutStream.FlushAsync(); Thread.Sleep(100); } } catch (Exception e) { } } await Task.CompletedTask; }
public Task FlushAsync(CancellationToken cancellationToken) { return(OutStream.FlushAsync(cancellationToken)); }