private async void ListenToServer() { try { socket = new Socket(SocketType.Stream, ProtocolType.Tcp); var ep = new IPEndPoint(Prefs.ServerIP, port); //port of game broadcasts await socket.ConnectAsync(ep); socket.Send(BitConverter.GetBytes(Prefs.Token)); while (true) { byte[] buffer = new byte[4]; socket.Receive(buffer); //receive data size int size = BitConverter.ToInt32(buffer, 0); //get size of data buffer = new byte[size]; socket.Receive(buffer); //receive actual data var data = JObject.Parse(Encoding.UTF8.GetString(buffer)); if ((string)data["type"] == "heartbeat") { continue; //ignore heartbeats } OnBroadcast?.Invoke(data); } } catch (Exception e) { Debug.WriteLine(e.Message); } }
/// <summary> /// Handles iOS audio buffer queue completed message. /// </summary> /// <param name='sender'>Sender object</param> /// <param name='e'> Input completed parameters.</param> void QueueInputCompleted(object sender, InputCompletedEventArgs e) { try { // we'll only broadcast if we're actively monitoring audio packets if (!Active) { return; } //copy data from the audio queue to a byte buffer var buffer = (AudioQueueBuffer)System.Runtime.InteropServices.Marshal.PtrToStructure(e.IntPtrBuffer, typeof(AudioQueueBuffer)); var audioBytes = new byte [buffer.AudioDataByteSize]; System.Runtime.InteropServices.Marshal.Copy(buffer.AudioData, audioBytes, 0, (int)buffer.AudioDataByteSize); //broadcast the audio data to any listeners OnBroadcast?.Invoke(this, audioBytes); //check for null/active again, because the auto stop logic may stop the audio queue from within this handler! if (Active) { var status = audioQueue.EnqueueBuffer(e.IntPtrBuffer, bufferSize, e.PacketDescriptions); if (status != AudioQueueStatus.Ok) { System.Diagnostics.Debug.WriteLine("AudioStream.QueueInputCompleted() :: audioQueue.EnqueueBuffer returned non-Ok status :: {0}", status); OnException?.Invoke(this, new Exception($"audioQueue.EnqueueBuffer returned non-Ok status :: {status}")); } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("AudioStream.QueueInputCompleted() :: Error: {0}", ex); } }
unsafe void Graph_QuantumStarted(AudioGraph sender, object args) { // we'll only broadcast if we're actively monitoring audio packets if (!Active) { return; } try { // get an audio frame from the output node AudioFrame frame = outputNode.GetFrame(); if (frame.Duration?.Milliseconds == 0) // discard any empty frames { return; } using (var buffer = frame.LockBuffer(AudioBufferAccessMode.Read)) using (IMemoryBufferReference reference = buffer.CreateReference()) { // Get the buffer from the AudioFrame ((IMemoryBufferByteAccess)reference).GetBuffer(out byte *dataInBytes, out uint capacityInBytes); // convert the bytes into float float *dataInFloat = (float *)dataInBytes; if (audioBytes == null) { audioBytes = new byte [buffer.Length * broadcastSize / 2]; // buffer length * # of frames we want to accrue / 2 (because we're transforming float audio to Int 16) } for (int i = 0; i < capacityInBytes / sizeof(float); i++) { // convert the float into a double byte for 16 bit PCM var shortVal = AudioFunctions.FloatToInt16(dataInFloat [i]); byte [] chunkBytes = BitConverter.GetBytes(shortVal); audioBytes [bufferPosition++] = chunkBytes [0]; audioBytes [bufferPosition++] = chunkBytes [1]; } // we want to wait until we accrue <broadcastSize> # of frames and then broadcast them // in practice, this will take us from 20ms chunks to 100ms chunks and result in more accurate audio level calculations // we could maybe use the audiograph latency settings to achieve similar results but this seems to work well if (bufferPosition == audioBytes.Length || !Active) { // broadcast the audio data to any listeners OnBroadcast?.Invoke(this, audioBytes); audioBytes = null; bufferPosition = 0; } } } catch (Exception ex) { OnException?.Invoke(this, new Exception($"AudioStream.QueueInputCompleted() :: Error: {ex.Message}")); } }
protected virtual unsafe void OnLogAppend(DirectBuffer buffer) { var writerPid = buffer.ReadInt64(DataHeaderFlyweight.RESERVED_VALUE_OFFSET); var messageBuffer = new DirectBuffer(buffer.Length - DataHeaderFlyweight.HEADER_LENGTH, buffer.Data + DataHeaderFlyweight.HEADER_LENGTH); var header = *(CommandHeader *)(messageBuffer.Data); var uuid = header.SeriesId; IAcceptCommand series; if ( writerPid != Pid // ignore our own messages && _openSeries.TryGetValue(uuid, out series) // ignore messages for closed series ) { if (header.CommandType == CommandType.Broadcast) { OnBroadcast?.Invoke(messageBuffer); } else { series.ApplyCommand(messageBuffer); } } }
/// <summary> /// Broadcasts a message /// </summary> /// <param name="message"></param> /// <returns></returns> public async Task <RconResponse> BroadcastAsync(string message) { var response = await ExecuteAsync($"say {message}"); OnBroadcast?.Invoke(this, response); return(response); }
/// <summary> /// Record from the microphone and broadcast the buffer. /// </summary> async Task Record() { byte [] data = new byte [bufferSize]; int readFailureCount = 0; int readResult = 0; Debug.WriteLine("AudioStream.Record(): Starting background loop to read audio stream"); while (Active) { try { // not sure if this is even a good idea, but we'll try to allow a single bad read, and past that shut it down if (readFailureCount > 1) { Debug.WriteLine("AudioStream.Record(): Multiple read failures detected, stopping stream"); await Stop(); break; } readResult = audioSource.Read(data, 0, bufferSize); // this can block if there are no bytes to read // readResult should == the # bytes read, except a few special cases if (readResult > 0) { readFailureCount = 0; OnBroadcast?.Invoke(this, data); } else { switch (readResult) { case (int)TrackStatus.ErrorInvalidOperation: case (int)TrackStatus.ErrorBadValue: case (int)TrackStatus.ErrorDeadObject: Debug.WriteLine("AudioStream.Record(): readResult returned error code: {0}", readResult); await Stop(); break; //case (int)TrackStatus.Error: default: readFailureCount++; Debug.WriteLine("AudioStream.Record(): readResult returned error code: {0}", readResult); break; } } } catch (Exception ex) { readFailureCount++; Debug.WriteLine("Error in Android AudioStream.Record(): {0}", ex.Message); OnException?.Invoke(this, ex); } } }
/// <summary> /// Record from the microphone and broadcast the buffer. /// </summary> /// <returns>Task.</returns> private async Task Record() { var buffer = new byte[_bufferSize]; var readCount = await _audioSource.ReadAsync(buffer, 0, _bufferSize); OnBroadcast.Invoke <byte[]>(this, buffer); }
/// <summary> /// Record from the microphone and broadcast the buffer. /// </summary> async Task Record() { try { int readFailureCount = 0; using (var readStream = stream.CloneStream()) using (var reader = new DataReader(readStream)) { reader.InputStreamOptions = InputStreamOptions.Partial; //reader.UnicodeEncoding = UnicodeEncoding.Utf8; while (Active) { try { //not sure if this is even a good idea (likely no), but we'll try to allow a single bad read, and past that shut it down if (readFailureCount > 1) { System.Diagnostics.Debug.WriteLine("AudioStream.Record(): Multiple read failures detected, stopping stream"); await Stop(); break; } var loadResult = await reader.LoadAsync(bufferSize); //readResult should contain the # bytes read if (loadResult > 0) { byte[] bytes = new byte[loadResult]; reader.ReadBytes(bytes); //System.Diagnostics.Debug.WriteLine("AudioStream.Record(): Read {0} bytes, broadcasting {1} bytes", loadResult, bytes.Length); OnBroadcast?.Invoke(this, bytes); } else { //System.Diagnostics.Debug.WriteLine("AudioStream.Record(): Non positive readResult returned: {0}", loadResult); } } catch (Exception ex) { readFailureCount++; System.Diagnostics.Debug.WriteLine("Error in Android AudioStream.Record(): {0}", ex.Message); OnException?.Invoke(this, ex); } } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Error in Android AudioStream.Record(): {0}", ex.Message); OnException?.Invoke(this, ex); } }
/// <summary> /// Microphones the buffer ready. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> private void MicrophoneBufferReady(object sender, EventArgs e) { var buffer = new byte[_microphone.GetSampleSizeInBytes(_microphone.BufferDuration)]; int read; do { read = _microphone.GetData(buffer, 0, buffer.Length); OnBroadcast.Invoke <byte[]>(this, buffer); }while (read > 0); }
private void setupWebsocket() { wsReconnecter = new System.Timers.Timer(reconnDebounceInterval); wsReconnecter.AutoReset = false; wsReconnecter.Enabled = false; wsReconnecter.Elapsed += (sender, e) => { ws.Connect(); }; ws = new WebSocket(server.wsEndpoint + "?access_token=" + server.token); ws.OnOpen += (sender, e) => { wsReconnecter.Stop(); ws.Send(JsonConvert.SerializeObject(new { eventName = "join-stream", args = new { streamid = server.streamId, role = "sender" } })); }; ws.OnClose += (sender, e) => { wsReconnecter.Start(); server.wsSessionId = null; this.OnError?.Invoke(this, new SpeckleEventArgs("Disconnected from server.")); }; ws.OnMessage += (sender, e) => { if (e.Data == "ping") { ws.Send("alive"); return; } dynamic message = JsonConvert.DeserializeObject(e.Data); if (message.eventName == "ws-session-id") { server.wsSessionId = message.sessionId; return; } if (message.eventName == "volatile-message") { OnMessage?.Invoke(this, new SpeckleEventArgs("volatile-message", message)); return; } if (message.eventName == "volatile-broadcast") { OnBroadcast?.Invoke(this, new SpeckleEventArgs("volatile-broadcast", message)); } }; ws.Connect(); }
/// <summary> /// Flushes any audio bytes in memory but not yet broadcast out to any listeners. /// </summary> public void Flush() { // not sure this is _really_ needed, but just in case, if we have bytes buffered in audioBytes, flush them out here // do we have leftover bytes to broadcast as we're stopping? if (audioBytes != null) { Debug.WriteLine("Broadcasting remaining {0} audioBytes", audioBytes.Length); // broadcast the audio data to any listeners OnBroadcast?.Invoke(this, audioBytes); audioBytes = null; } }
/// <summary> /// Handles iOS audio buffer queue completed message. /// </summary> /// <param name='sender'>Sender object</param> /// <param name='e'> Input completed parameters.</param> void QueueInputCompleted(object sender, InputCompletedEventArgs e) { try { // we'll only broadcast if we're actively monitoring audio packets if (!Active) { return; } if (e.Buffer.AudioDataByteSize > 0) { var audioBytes = new byte [e.Buffer.AudioDataByteSize]; Marshal.Copy(e.Buffer.AudioData, audioBytes, 0, (int)e.Buffer.AudioDataByteSize); // broadcast the audio data to any listeners OnBroadcast?.Invoke(this, audioBytes); // check if active again, because the auto stop logic may stop the audio queue from within this handler! if (Active) { BufferOperation(() => audioQueue.EnqueueBuffer(e.IntPtrBuffer, null), null, status => { Debug.WriteLine("AudioStream.QueueInputCompleted() :: audioQueue.EnqueueBuffer returned non-Ok status :: {0}", status); OnException?.Invoke(this, new Exception($"audioQueue.EnqueueBuffer returned non-Ok status :: {status}")); }); } } } catch (Exception ex) { Debug.WriteLine("AudioStream.QueueInputCompleted() :: Error: {0}", ex.Message); OnException?.Invoke(this, new Exception($"AudioStream.QueueInputCompleted() :: Error: {ex.Message}")); } }
private void setupWebsocket() { wsReconnecter = new System.Timers.Timer(reconnDebounceInterval); wsReconnecter.AutoReset = false; wsReconnecter.Enabled = false; wsReconnecter.Elapsed += (sender, e) => { ws.Connect(); }; ws = new WebSocket(server.wsEndpoint + "?access_token=" + server.token); ws.OnOpen += (sender, e) => { wsReconnecter.Stop(); ws.Send(JsonConvert.SerializeObject(new { eventName = "join-stream", args = new { streamid = server.streamId, role = "receiver" } })); }; ws.OnClose += (sender, e) => { wsReconnecter.Start(); server.wsSessionId = null; }; ws.OnMessage += (sender, e) => { if (e.Data == "ping") { ws.Send("alive"); return; } dynamic message = JsonConvert.DeserializeObject <ExpandoObject>(e.Data); if (message.eventName == "ws-session-id") { server.wsSessionId = message.sessionId; return; } if (message.eventName == "volatile-broadcast") { OnBroadcast?.Invoke(this, new SpeckleEventArgs("volatile-broadcast", message)); return; } if (message.eventName == "volatile-message") { OnMessage?.Invoke(this, new SpeckleEventArgs("volatile-message", message)); return; } if (message.eventName == "live-update") { OnDataMessage?.Invoke(this, new SpeckleEventArgs("Received update notification.")); getObjects(message.args as ExpandoObject, (castObjects) => { dynamic eventData = new ExpandoObject(); eventData.objects = castObjects; eventData.layers = SpeckleLayer.fromExpandoList(message.args.layers); eventData.name = message.args.name; OnData?.Invoke(this, new SpeckleEventArgs("live-update", eventData)); }); return; } if (message.eventName == "metadata-update") { dynamic eventData = new ExpandoObject(); eventData.name = message.args.name; eventData.layers = SpeckleLayer.fromExpandoList(message.args.layers); OnMetadata?.Invoke(this, new SpeckleEventArgs("metadata-update", eventData)); return; } if (message.eventName == "history-update") { // TODO OnHistory?.Invoke(this, new SpeckleEventArgs("history-update")); return; } }; ws.Connect(); }
protected void Broadcast(string message) { OnBroadcast?.Invoke(message); }