Exemple #1
0
        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;
        }
Exemple #4
0
        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();
        }
Exemple #6
0
        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());
        }
Exemple #7
0
        [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);
        }
Exemple #9
0
        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;
        }