public EncoderPipeline([NotNull] WaveFormat inputFormat, [NotNull] IVoiceEncoder encoder, [NotNull] ICommsNetwork net) { if (inputFormat == null) { throw new ArgumentNullException("inputFormat"); } if (encoder == null) { throw new ArgumentNullException("encoder"); } if (net == null) { throw new ArgumentNullException("net"); } _net = net; _inputFormat = inputFormat; _encoder = new ReadonlyLockedValue <IVoiceEncoder>(encoder); //Create buffers to store the encoder input (1 frame of floats) and output (twice equivalent amount of bytes) _plainSamples = new float[encoder.FrameSize]; _encodedBytes = new byte[encoder.FrameSize * sizeof(float) * 2]; //Input buffer to store raw data from microphone _input = new BufferedSampleProvider(_inputFormat, encoder.FrameSize * 2); //Resample data from microphone rate -> encoder rate _resampler = new Resampler(_input, encoder.SampleRate); //Provides encoder sized and encoder rate frames of data _output = new SampleToFrameProvider(_resampler, (uint)encoder.FrameSize); }
public LocalVoicePlayerState(string name, [NotNull] IAmplitudeProvider micAmplitude, [NotNull] Rooms rooms, [NotNull] RoomChannels roomChannels, [NotNull] PlayerChannels playerChannels, [NotNull] ILossEstimator loss, [NotNull] ICommsNetwork network) : base(name) { _rooms = rooms; _micAmplitude = micAmplitude; _roomChannels = roomChannels; _playerChannels = playerChannels; _loss = loss; _network = network; rooms.JoinedRoom += OnLocallyEnteredRoom; rooms.LeftRoom += OnLocallyExitedRoom; roomChannels.OpenedChannel += OnChannelOpened; roomChannels.ClosedChannel += OnChannelClosed; playerChannels.OpenedChannel += OnChannelOpened; playerChannels.ClosedChannel += OnChannelClosed; }
public void Start([NotNull] ICommsNetwork network, [NotNull] IMicrophoneCapture microphone) { if (network == null) { throw new ArgumentNullException("network"); } if (microphone == null) { throw new ArgumentNullException("microphone"); } _microphone = microphone; _network = network; Net_ModeChanged(network.Mode); network.ModeChanged += Net_ModeChanged; }
public EncoderPipeline(IMicrophoneCapture mic, IVoiceEncoder encoder, ICommsNetwork net, Func <int> channelCount) { _mic = mic; _encoder = encoder; _net = net; _channelCount = channelCount; _encodedBytes = new byte[encoder.FrameSize * sizeof(float)]; _plainSamples = new float[encoder.FrameSize]; _inputFormat = mic.Format; //Create an input buffer with plenty of spare space _input = new BufferedSampleProvider(_inputFormat, Math.Max(_encoder.FrameSize * 2, mic.FrameSize * 2)); _resampler = new Resampler(_input, _encoder.SampleRate); //Whatever we did above, we need to read in frame size chunks _output = new SampleToFrameProvider(_resampler, (uint)encoder.FrameSize); }
public void Start([NotNull] ICommsNetwork network, [NotNull] IMicrophoneCapture microphone) { if (network == null) { throw new ArgumentNullException("network"); } if (microphone == null) { throw new ArgumentNullException("microphone"); } _microphone = microphone; _network = network; AudioSettingsWatcher.Instance.Start(); Net_ModeChanged(network.Mode); network.ModeChanged += Net_ModeChanged; _isMobilePlatform = IsMobilePlatform(); }
private void Start() { //Ensure that all settings are loaded before we access them (potentially from other threads) ChatRoomSettings.Preload(); DebugSettings.Preload(); VoiceSettings.Preload(); //Write multithreaded logs ASAP so the logging system knows which is the main thread Logs.WriteMultithreadedLogs(); //Sanity check (can't run without a network object) var net = gameObject.GetComponent <ICommsNetwork>(); if (net == null) { throw new Exception("Cannot find a voice network component. Please attach a voice network component appropriate to your network system to the DissonanceVoiceComms' entity."); } //Sanity check (can't run without run in background). This value doesn't work on mobile platforms so don't perform this check there if (!Application.isMobilePlatform && !Application.runInBackground) { Log.Error(Log.UserErrorMessage( "Run In Background is not set", "The 'Run In Background' toggle on the player settings has not been checked", "https://dissonance.readthedocs.io/en/latest/Basics/Getting-Started/#3-run-in-background", "98D123BB-CF4F-4B41-8555-41CD01108DA7") ); } //Load default playback prefab if one has not been set if (PlaybackPrefab == null) { Log.Info("Loading default playback prefab"); PlaybackPrefab = Resources.Load <GameObject>("PlaybackPrefab").GetComponent <VoicePlayback>(); } net.PlayerJoined += Net_PlayerJoined; net.PlayerLeft += Net_PlayerLeft; net.PlayerEnteredRoom += Net_PlayerRoomEvent; net.PlayerExitedRoom += Net_PlayerRoomEvent; net.VoicePacketReceived += Net_VoicePacketReceived; net.PlayerStartedSpeaking += Net_PlayerStartedSpeaking; net.PlayerStoppedSpeaking += Net_PlayerStoppedSpeaking; net.TextPacketReceived += _text.OnMessageReceived; //If an explicit name has not been set generate a GUID based name if (string.IsNullOrEmpty(LocalPlayerName)) { var guid = Guid.NewGuid().ToString(); LocalPlayerName = guid; } //mark this component as started, locking the LocalPlayerName, PlaybackPrefab and Microphone properties from changing _started = true; //Setup the playback pool so we can create pipelines to play audio _playbackPool.Start(PlaybackPrefab, transform); //Make sure we load up the codec settings so we can create codecs later _codecSettings.Start(); //Start the player collection (to set local name) _players.Start(LocalPlayerName, _capture, Rooms, RoomChannels, PlayerChannels); net.Initialize(LocalPlayerName, Rooms, PlayerChannels, RoomChannels); _net = net; //Begin capture manager, this will create and destroy capture pipelines as necessary (net mode changes, mic name changes, mic requires reset etc) _capture.MicrophoneName = _micName; _capture.Start(_net, GetOrAddMicrophone()); }
[UsedImplicitly] private void Start() { // Unity is unreliable about late loading DLLs so try to load dependencies as early as possible. try { TestDependencies(); } catch (Exception e) { Log.Error("Dependency Error: {0}", e.Message); } //Ensure that all settings are loaded before we access them (potentially from other threads) ChatRoomSettings.Preload(); DebugSettings.Preload(); VoiceSettings.Preload(); //Write multithreaded logs ASAP so the logging system knows which is the main thread Logs.WriteMultithreadedLogs(); //Sanity check (can't run without a network object) var net = gameObject.GetComponent <ICommsNetwork>(); if (net == null) { throw new Exception("Cannot find a voice network component. Please attach a voice network component appropriate to your network system to the DissonanceVoiceComms' entity."); } //Sanity check (can't run without run in background). This value doesn't work on mobile platforms so don't perform this check there if (!Application.isMobilePlatform && !Application.runInBackground) { Log.Error(Log.UserErrorMessage( "Run In Background is not set", "The 'Run In Background' toggle on the player settings has not been checked", "https://dissonance.readthedocs.io/en/latest/Basics/Getting-Started/#3-run-in-background", "98D123BB-CF4F-4B41-8555-41CD01108DA7") ); } //Load default playback prefab if one has not been set if (PlaybackPrefab == null) { //Check if there is a legacy playback prefab set if (_playbackPrefab != null) { PlaybackPrefab = _playbackPrefab.gameObject; } else { Log.Info("Loading default playback prefab"); PlaybackPrefab = Resources.Load <GameObject>("PlaybackPrefab"); if (PlaybackPrefab == null) { throw Log.CreateUserErrorException("Failed to load PlaybackPrefab from resources - Dissonance voice will be disabled", "Incorrect installation of Dissonance", "https://dissonance.readthedocs.io/en/latest/Basics/Getting-Started/", "F542DAE5-AB78-4ADE-8FF0-4573233505AB"); } } } net.PlayerJoined += Net_PlayerJoined; net.PlayerLeft += Net_PlayerLeft; net.PlayerEnteredRoom += Net_PlayerRoomEvent; net.PlayerExitedRoom += Net_PlayerRoomEvent; net.VoicePacketReceived += Net_VoicePacketReceived; net.PlayerStartedSpeaking += Net_PlayerStartedSpeaking; net.PlayerStoppedSpeaking += Net_PlayerStoppedSpeaking; net.TextPacketReceived += _text.OnMessageReceived; //If an explicit name has not been set generate a GUID based name if (string.IsNullOrEmpty(LocalPlayerName)) { var guid = Guid.NewGuid().ToString(); LocalPlayerName = guid; } //mark this component as started, locking the LocalPlayerName, PlaybackPrefab and Microphone properties from changing _started = true; //Setup the playback pool so we can create pipelines to play audio _playbackPool.Start(PlaybackPrefab, transform); //Make sure we load up the codec settings so we can create codecs later _codecSettingsLoader.Start(); //Start the player collection (to set local name) _players.Start(LocalPlayerName, _capture, Rooms, RoomChannels, PlayerChannels, _capture, net); net.Initialize(LocalPlayerName, Rooms, PlayerChannels, RoomChannels, _codecSettingsLoader.Config); _net = net; //Begin capture manager, this will create and destroy capture pipelines as necessary (net mode changes, mic name changes, mic requires reset etc) _capture.MicrophoneName = _micName; _capture.Start(_net, GetOrAddMicrophone()); Log.Info("Starting Dissonance Voice Comms ({0})\n- Network: [{1}]\n- Quality Settings: [{2}]\n- Codec: [{3}]", Version, _net, VoiceSettings.Instance, _codecSettingsLoader); }
public void Start([NotNull] string name, [NotNull] IAmplitudeProvider micAmplitude, [NotNull] Rooms rooms, [NotNull] RoomChannels roomChannels, [NotNull] PlayerChannels playerChannels, [NotNull] ILossEstimator loss, [NotNull] ICommsNetwork net) { if (name == null) { throw new ArgumentException("name"); } if (micAmplitude == null) { throw new ArgumentException("micProvider"); } if (rooms == null) { throw new ArgumentNullException("rooms"); } if (roomChannels == null) { throw new ArgumentException("roomChannels"); } if (playerChannels == null) { throw new ArgumentException("playerChannels"); } if (loss == null) { throw new ArgumentException("playerChannels"); } if (net == null) { throw new ArgumentException("net"); } Local = new LocalVoicePlayerState(name, micAmplitude, rooms, roomChannels, playerChannels, loss, net); Add(Local); }
private void Start() { //Ensure that all settings are loaded before we access them (potentially from other threads) DebugSettings.Preload(); VoiceSettings.Preload(); //Write multithreaded logs ASAP so the logging system knows which is the main thread Logs.WriteMultithreadedLogs(); var net = gameObject.GetComponent <ICommsNetwork>(); if (net == null) { throw new Exception("Cannot find a voice network component. Please attach a voice network component appropriate to your network system to the DissonanceVoiceComms' entity."); } if (PlaybackPrefab == null) { Log.Info("Loading default playback prefab"); PlaybackPrefab = Resources.Load <GameObject>("PlaybackPrefab").GetComponent <VoicePlayback>(); } net.PlayerJoined += Net_PlayerJoined; net.PlayerLeft += Net_PlayerLeft; net.VoicePacketReceived += Net_VoicePacketReceived; net.PlayerStartedSpeaking += Net_PlayerStartedSpeaking; net.PlayerStoppedSpeaking += Net_PlayerStoppedSpeaking; net.TextPacketReceived += _text.OnMessageReceived; if (string.IsNullOrEmpty(LocalPlayerName)) { var guid = Guid.NewGuid().ToString(); LocalPlayerName = guid; } //mark this component as started, locking the LocalPlayerName, PlaybackPrefab and Microphone properties from changing _started = true; MicCapture = MicrophoneCapture.Start(_micName); _localPlayerState = new LocalVoicePlayerState(LocalPlayerName, this); _players.Add(_localPlayerState); _playersLookup.Add(LocalPlayerName, _localPlayerState); Action <NetworkMode> networkModeChanged = mode => { if (mode.IsClientEnabled()) { var encoder = new OpusEncoder(VoiceSettings.Instance.Quality, VoiceSettings.Instance.FrameSize); _decoderFrameSize = (uint)encoder.FrameSize; _decoderSampleRate = encoder.SampleRate; _transmissionPipeline = new EncoderPipeline(MicCapture, encoder, _net, () => _playerChannels.Count + _roomChannels.Count); for (var i = 0; i < _activationListeners.Count; i++) { MicCapture.Subscribe(_activationListeners[i]); } } else { if (_transmissionPipeline != null) { _transmissionPipeline.Dispose(); _transmissionPipeline = null; } for (var i = 0; i < _activationListeners.Count; i++) { MicCapture.Unsubscribe(_activationListeners[i]); } } }; if (MicCapture != null) { net.ModeChanged += networkModeChanged; } else { Log.Warn("No microphone detected; local voice transmission will be disabled."); } net.Initialize(LocalPlayerName, Rooms, PlayerChannels, RoomChannels); _net = net; }