/// <summary> /// Combines the people tracking and speaker balancing. /// It first processes the next camera frames and receives the coordinates of the detected people. /// Afterwards, the speaker will be balanced. /// It also updates the UI Windows and triggers new result events. /// </summary> private void DoWork() { WorkerResult result = new WorkerResult(cameras.Keys.Count); Point coordinates = new Point(0, 0); bool applyCoordinates = true; // process all cameras for (int i = 0; i < cameras.Keys.Count; i++) { Image image = cameras.Keys.ElementAt(i); Camera camera = cameras[image]; // process next frame and detect people/coordinates if needed camera.Process(isBalancing || isCalibrating); result.SetFrame(i, camera.GetFrame()); Point?cameraCoordinates = camera.GetCoordinates(i % 2 == 0 ? Orientation.Horizontal : Orientation.Vertical); // if a camera is not ready or didn't detect a person, cancel coordinates calculation if (cameraCoordinates == null) { applyCoordinates = false; } else { coordinates.X = Math.Max(coordinates.X, cameraCoordinates.Value.X); coordinates.Y = Math.Max(coordinates.Y, cameraCoordinates.Value.Y); } } if (applyCoordinates) { result.SetCoordinates(coordinates); if (isBalancing) { float[] channels = new float[outputAudioDevice.AudioEndpointVolume.Channels.Count]; for (int i = 0; i < outputAudioDevice.AudioEndpointVolume.Channels.Count; i++) { channels[i] = (float)volumeInterpolation.GetVolumeForPositionAndSpeaker(coordinates.X, coordinates.Y, i); } volumeFader.Set(channels); } } // dispatch the result ready event and update the main window if (Application.Current != null) { Application.Current.Dispatcher.Invoke(() => { OnResultReady(result); if (isBalancing) { if (Application.Current.MainWindow is MainWindow) { ((MainWindow)Application.Current.MainWindow).UpdateChannelLevels(); } } }); } }
/// <summary> /// Calls the event listeners when a new result is ready. /// </summary> /// <param name="result">New result.</param> protected virtual void OnResultReady(WorkerResult result) { if (ResultReady != null) { ResultReadyEventArgs args = new ResultReadyEventArgs(); args.Result = result; ResultReady(this, args); } }