public void UpdateItems() { // Create list of connected and loaded microphones without duplicates. // A loaded microphone might have been created with hardware that is not connected now. List <string> connectedMicNames = Microphone.devices.ToList(); List <MicProfile> loadedMicProfiles = SettingsManager.Instance.Settings.MicProfiles; List <MicProfile> micProfiles = new List <MicProfile>(loadedMicProfiles); List <ConnectedClientHandler> connectedClientHandlers = ServerSideConnectRequestManager.GetConnectedClientHandlers(); // Create mic profiles for connected microphones that are not yet in the list foreach (string connectedMicName in connectedMicNames) { bool alreadyInList = micProfiles.AnyMatch(it => it.Name == connectedMicName && !it.IsInputFromConnectedClient); if (!alreadyInList) { MicProfile micProfile = new MicProfile(connectedMicName); micProfiles.Add(micProfile); } } // Create mic profiles for connected companion apps that are not yet in the list foreach (ConnectedClientHandler connectedClientHandler in connectedClientHandlers) { bool alreadyInList = micProfiles.AnyMatch(it => it.ConnectedClientId == connectedClientHandler.ClientId && it.IsInputFromConnectedClient); if (!alreadyInList) { MicProfile micProfile = new MicProfile(connectedClientHandler.ClientName, connectedClientHandler.ClientId); micProfiles.Add(micProfile); } } Items = micProfiles; }
private void UpdateConnectedClientCountText() { string connectedClientNamesCsv = ServerSideConnectRequestManager.ConnectedClientCount > 0 ? ServerSideConnectRequestManager.GetConnectedClientHandlers() .Select(it => it.ClientName) .ToCsv(", ", "", "") : ""; uiText.text = $"Connected Clients: {ServerSideConnectRequestManager.ConnectedClientCount}\n" + connectedClientNamesCsv; }
private void UpdateRecordingWithInputFromConnectedClient() { // Use the sample data that is sent by the connected client if (!ServerSideConnectRequestManager.TryGetConnectedClientHandler(MicProfile.ConnectedClientId, out ConnectedClientHandler connectedClientHandler)) { Debug.Log($"Client disconnected: {micProfile.Name}. Stopping recording."); StopRecording(); return; } int newSamplesCount = connectedClientHandler.GetNewMicSamples(MicSamples); ApplyAmplificationAndNotifyListeners(newSamplesCount); }
private static int GetSampleRateHz(MicProfile micProfile) { if (micProfile.IsInputFromConnectedClient) { return(ServerSideConnectRequestManager.TryGetConnectedClientHandler(micProfile.ConnectedClientId, out ConnectedClientHandler connectedClientHandler) ? connectedClientHandler.SampleRateHz : DefaultSampleRateHz); } else { Microphone.GetDeviceCaps(micProfile.Name, out int minFrequency, out int maxFrequency); return(maxFrequency == 0 // a value of zero indicates, that the device supports any frequency // https://docs.unity3d.com/ScriptReference/Microphone.GetDeviceCaps.html ? DefaultSampleRateHz : maxFrequency); } }
private static bool CheckMicProfileIsDisconnected(MicProfile localMicProfile) { if (localMicProfile.IsInputFromConnectedClient) { if (!ServerSideConnectRequestManager.TryGetConnectedClientHandler(localMicProfile.ConnectedClientId, out ConnectedClientHandler connectedClientHandler)) { Debug.LogWarning($"Client for mic-input not connected: '{localMicProfile.ConnectedClientId}'."); return(true); } } else { List <string> devices = new List <string>(Microphone.devices); if (!devices.Contains(localMicProfile.Name)) { Debug.LogWarning($"Did not find mic '{localMicProfile.Name}'. Available mic devices: {devices.ToCsv()}"); return(true); } } return(false); }
private void InitSingleInstance() { if (!Application.isPlaying) { return; } if (instance != null && instance != this) { // This instance is not needed. Destroy(gameObject); return; } instance = this; // Move object to top level in scene hierarchy. // Otherwise this object will be destroyed with its parent, even when DontDestroyOnLoad is used. transform.SetParent(null); DontDestroyOnLoad(gameObject); }
public ConnectedClientHandler(ServerSideConnectRequestManager serverSideConnectRequestManager, IPEndPoint clientIpEndPoint, string clientName, string clientId, int microphoneSampleRate) { this.serverSideConnectRequestManager = serverSideConnectRequestManager; ClientIpEndPoint = clientIpEndPoint; ClientName = clientName; ClientId = clientId; if (ClientId.IsNullOrEmpty()) { throw new ArgumentException("Attempt to create ConnectedClientHandler without ClientId"); } if (microphoneSampleRate <= 0) { throw new ArgumentException("Attempt to create ConnectedClientHandler without microphoneSampleRate"); } micSampleBuffer = new float[microphoneSampleRate]; receivedByteBuffer = new byte[2048]; stillAliveRequestByteArray = new byte[1]; MicTcpListener = new TcpListener(IPAddress.Any, 0); MicTcpListener.Start(); Debug.Log($"Started TcpListener on port {MicTcpListener.GetPort()} to receive mic samples at {microphoneSampleRate} Hz"); receiveDataThread = new Thread(() => { while (!isDisposed) { try { if (micTcpClient == null) { micTcpClient = MicTcpListener.AcceptTcpClient(); micTcpClientStream = micTcpClient.GetStream(); } } catch (Exception e) { Debug.LogException(e); Debug.LogError("Error when accepting TcpClient for mic input. Closing TcpListener."); this.serverSideConnectRequestManager.RemoveConnectedClientHandler(this); return; } AcceptMicrophoneData(); Thread.Sleep(10); } }); receiveDataThread.Start(); clientStillAliveCheckThread = new Thread(() => { while (!isDisposed) { if (micTcpClient != null && micTcpClientStream != null) { CheckClientStillAlive(); } Thread.Sleep(250); } }); clientStillAliveCheckThread.Start(); }