private void MixAudio() { List <float> output; List <float> pfl; int currentSamples = 0; int connectedClients = 0; // MIX CLIENTS AUDIO lock (clientsLock) { foreach (KeyValuePair <string, Client> kvp in clients) { Client c = kvp.Value; if (c.IsConnected()) { connectedClients++; output = new List <float>(); for (int i = 0; i < c.currentSamples.Length / 4; i++) { output.Add(0f); } lock (c.sourcesLock) { foreach (int loop in c.GetSources()) { Loop l = loops[loop]; lock (l.talkersLock) { foreach (string talker in l.talkers) { if (clients[talker].IsConnected() && (c.guid != talker || NminusOne == false)) { output = mixSamples(output, clients[talker]); } } } } } c.outgoingSamples = Converters.floats2bytes(output.ToArray()); } else { c.outgoingSamples = null; } currentSamples = c.currentSamples.Length; } // MIX LOOP AUDIO FOR METERING AND SERVER PFL pfl = new List <float>(); for (int i = 0; i < currentSamples / 4; i++) { pfl.Add(0f); } foreach (Loop loop in loops) { output = new List <float>(); for (int i = 0; i < currentSamples / 4; i++) { output.Add(0f); } foreach (string talker in loop.talkers) { output = mixSamples(output, clients[talker]); } loop.outgoingSamples = Converters.floats2bytes(output.ToArray()); if (loop.pfl) { pfl = mixSamples(pfl, output); } } byte[] bytes = Converters.floats2bytes(pfl.ToArray()); // If no clients are connected, ignore pfl if (connectedClients > 0) { pflBuffer.AddSamples(bytes, 0, bytes.Length); // Keep pflBuffer below 200ms if (pflBuffer.BufferedDuration.TotalMilliseconds > 200) { double bytes_to_read = (sampleRate / 1000) * channels * (pflBuffer.BufferedDuration.TotalMilliseconds - 200); byte[] void_array = new byte[(int)bytes_to_read]; pflBuffer.Read(void_array, 0, (int)bytes_to_read); //Logger.WriteLine("Trew away " + bytes_to_read.ToString() + " bytes from pflBuffer"); } } } }