using System; using System.Collections.Generic; using UnityEngine; namespace Adrenak.UniVoice { /// /// Handles a client session. /// Requires an implementation of , and each. /// Allows adding input and output filters and handles their execution. /// /// public class ClientSession : IDisposable { /// /// The instances of each peer in the session /// public Dictionary PeerOutputs { get; private set; } = new Dictionary(); /// /// The input that will be applied to the outgoing audio for all the peers. /// Note that filters are executed in the order they are present in this list /// public List InputFilters { get; set; } = new List(); /// /// The output that will be applied to the incoming audio for all the peers. /// Note that filters are executed in the order they are present in this list. /// public List OutputFilters { get; set; } = new List(); public ClientSession(IAudioClient client, IAudioInput input, IAudioOutputFactory outputFactory) { Client = client; Input = input; OutputFactory = outputFactory; } /// /// The that's used for networking /// IAudioClient client; public IAudioClient Client { get => client; set { if(client != null) client.Dispose(); client = value; Client.OnLeft += () => { foreach (var output in PeerOutputs) output.Value.Dispose(); PeerOutputs.Clear(); }; Client.OnPeerJoined += id => { try { var output = outputFactory.Create(); PeerOutputs.Add(id, output); } catch (Exception e) { Debug.LogException(e); } }; Client.OnPeerLeft += id => { if (!PeerOutputs.ContainsKey(id)) return; PeerOutputs[id].Dispose(); PeerOutputs.Remove(id); }; client.OnReceivedPeerAudioFrame += (id, audioFrame) => { if (!PeerOutputs.ContainsKey(id)) return; if (OutputFilters != null) { foreach (var filter in OutputFilters) audioFrame = filter.Run(audioFrame); } if(audioFrame.samples.Length > 0) PeerOutputs[id].Feed(audioFrame); }; } } IAudioInput input; /// /// The that's used for sourcing outgoing audio /// public IAudioInput Input { get => input; set { if(input != null) input.Dispose(); input = value; input.OnFrameReady += frame => { if (InputFilters != null) { foreach (var filter in InputFilters) frame = filter.Run(frame); } if(frame.samples.Length > 0) Client.SendAudioFrame(frame); }; } } IAudioOutputFactory outputFactory; /// /// The that creates the of peers /// public IAudioOutputFactory OutputFactory { get => outputFactory; set { outputFactory = value; foreach (var output in PeerOutputs) output.Value.Dispose(); PeerOutputs.Clear(); foreach (var id in Client.PeerIDs) { try { var output = outputFactory.Create(); PeerOutputs.Add(id, output); } catch (Exception e) { Debug.LogException(e); } } } } public void Dispose() { Client.Dispose(); Input.Dispose(); } } }