public void Run(object dummy) { foreach (var inputStream in InputFiles) { inputStream.Initialize(); } _running = true; _player.Start(); while (_running) { // Spin until the output buffer has some room while (_player.BufferSizeMs() > BUFFER_LENGTH_MS) { Thread.Sleep(5); } // Check for updated parameters and send them to the codec if needed _codecParamLock.WaitOne(); if (_codecParamChanged) { _currentCodec.SetBitrate(_bitrate); _currentCodec.SetComplexity(_complexity); _currentCodec.SetFrameSize(_frameSize); _currentCodec.SetPacketLoss(_packetLoss); _currentCodec.SetApplication(_application); _currentCodec.SetVBRMode(_useVBR, _useCVBR); _codecParamChanged = false; } AudioChunk inputPcm = _currentMusic.ReadChunk(); _codecParamLock.ReleaseMutex(); // Run the opus encoder and decoder byte[] compressedFrame = _currentCodec.Compress(inputPcm); if (compressedFrame != null && compressedFrame.Length > 0) { AudioChunk decompressed = _currentCodec.Decompress(compressedFrame); // Pipe the output to the audio device _player.QueueChunk(decompressed); } } }