[NotNull] private static DecoderPipeline GetOrCreateDecoderPipeline(FrameFormat format, [NotNull] IVolumeProvider volume) { if (volume == null) { throw new ArgumentNullException("volume"); } ConcurrentPool <DecoderPipeline> pool; if (!FreePipelines.TryGetValue(format, out pool)) { pool = new ConcurrentPool <DecoderPipeline>(3, () => { var decoder = DecoderFactory.Create(format); return(new DecoderPipeline(decoder, format.FrameSize, p => { p.Reset(); Recycle(format, p); })); }); FreePipelines[format] = pool; } var pipeline = pool.Get(); pipeline.Reset(); pipeline.VolumeProvider = volume; return(pipeline); }
[NotNull] public static IVoiceDecoder Create(FrameFormat format) { try { switch (format.Codec) { case Codec.Identity: return(new IdentityDecoder(format.WaveFormat)); //ncrunch: no coverage start (Justification: Don't want to pull opus binaries into test context) case Codec.Opus: return(new OpusDecoder(format.WaveFormat, VoiceSettings.Instance.ForwardErrorCorrection)); //ncrunch: no coverage end default: throw new ArgumentOutOfRangeException("format", "Unknown codec."); } } catch (Exception ex) { Log.Error("Encountered unexpected error creating decoder. Audio playback will be disabled.\n{0}", ex); return(new SilenceDecoder(format)); } }
private static void Recycle(FrameFormat format, [CanBeNull] DecoderPipeline pipeline) { if (pipeline == null) { return; } GetPool(format).Put(pipeline); }
private static void Recycle(FrameFormat format, DecoderPipeline pipeline) { ConcurrentPool <DecoderPipeline> pool; if (!FreePipelines.TryGetValue(format, out pool)) { Log.Warn(Log.PossibleBugMessage("Tried to recycle a pipeline but the pool for this pipeline format does not exist", "A6212BCF-9318-4224-B69F-BA4B5A651785")); } else { pool.Put(pipeline); } }
[NotNull] public static IVoiceDecoder Create(FrameFormat format) { switch (format.Codec) { case Codec.Identity: return(new IdentityDecoder(format.WaveFormat)); case Codec.Opus: return(new OpusDecoder(format.WaveFormat)); default: throw new ArgumentOutOfRangeException("format", "Codec not supported"); } }
/// <summary> /// Starts a new speech session and adds it to the queue for playback /// </summary> /// <param name="format">The frame format.</param> /// <param name="now">Current time, or null for DateTime.UtcNow</param> /// <param name="jitter">Jitter estimator, or null for this stream to estimate it's own jitter</param> public void StartSession(FrameFormat format, DateTime?now = null, [CanBeNull] IJitterEstimator jitter = null) { if (PlayerName == null) { throw Log.CreatePossibleBugException("Attempted to `StartSession` but `PlayerName` is null", "0C0F3731-8D6B-43F6-87C1-33CEC7A26804"); } _active = GetOrCreateDecoderPipeline(format, _volumeProvider); var session = SpeechSession.Create(new SessionContext(PlayerName, unchecked (_currentId++)), jitter ?? this, _active, _active, now ?? DateTime.UtcNow); _awaitingActivation.Enqueue(session); Log.Debug("Created new speech session with buffer time of {0}ms", session.Delay.TotalMilliseconds); }
[NotNull] internal static DecoderPipeline GetDecoderPipeline(FrameFormat format, [NotNull] IVolumeProvider volume) { if (volume == null) { throw new ArgumentNullException("volume"); } var pool = GetPool(format); var pipeline = pool.Get(); pipeline.Reset(); pipeline.VolumeProvider = volume; return(pipeline); }
[NotNull] public static IVoiceDecoder Create(FrameFormat format) { switch (format.Codec) { case Codec.Identity: return(new IdentityDecoder(format.WaveFormat)); //ncrunch: no coverage start (Justification: Don't want to pull opus binaries into test context) case Codec.Opus: return(new OpusDecoder(format.WaveFormat, VoiceSettings.Instance.ForwardErrorCorrection)); //ncrunch: no coverage end default: throw new ArgumentOutOfRangeException("format", "Codec not supported"); } }
[NotNull] private static ConcurrentPool <DecoderPipeline> GetPool(FrameFormat format) { ConcurrentPool <DecoderPipeline> pool; if (!Pools.TryGetValue(format, out pool)) { pool = new ConcurrentPool <DecoderPipeline>(3, () => { var decoder = DecoderFactory.Create(format); var uuid = _nextPipelineId.ToString(); return(new DecoderPipeline(decoder, format.FrameSize, p => { p.Reset(); Recycle(format, p); }, uuid)); }); Pools[format] = pool; _nextPipelineId++; } return(pool); }