/// <summary>
        /// Start the speaker configuration step.
        /// A test tone will be played on all speakers and the volume recorded.
        /// </summary>
        public void Start()
        {
            MMDevice outputAudioDevice = workerThread.GetOutputAudioDevice();
            MMDevice inputAudioDevice  = workerThread.GetInputAudioDevice();

            isCanceled = false;
            volumes    = new Dictionary <int, float[]>();
            originalChannelVolume.Clear();
            speakerStep = 1;

            // get the current channel volumes to reset it when the configuration is done
            for (int i = 0; i < outputAudioDevice.AudioEndpointVolume.Channels.Count; i++)
            {
                originalChannelVolume.Add(i, outputAudioDevice.AudioEndpointVolume.Channels[i].VolumeLevelScalar);
            }

            testTone = new TestTone(outputAudioDevice, inputAudioDevice);

            // if this is the first time this step gets executed, record the volume level and calculate a target to scale it to
            if (volumeScalingFactor == 0)
            {
                manager.SetInstructions("Calibrating max volume");
                testTone.Play(TestToneLength, delegate(object sender, StoppedEventArgs e)
                {
                    float maxVolume     = testTone.GetAverageCaptureVolume();
                    volumeScalingFactor = TestToneScalingTarget / maxVolume;
                    manager.SetAudioInputDeviceVolume(maxVolume * volumeScalingFactor);

                    MuteAllChannels();
                    manager.SetInstructions("Calibrating speakers channel " + (speakerStep / 2) + " - Step 1");
                    outputAudioDevice.AudioEndpointVolume.Channels[0].VolumeLevelScalar = originalChannelVolume[0];
                    testTone.Play(TestToneLength, new EventHandler <StoppedEventArgs>(TestToneStopped));
                });
            }
            else
            {
                // start with first channel
                MuteAllChannels();
                manager.SetInstructions("Calibrating speakers channel " + (speakerStep / 2) + " - Step 1");
                outputAudioDevice.AudioEndpointVolume.Channels[0].VolumeLevelScalar = originalChannelVolume[0];
                testTone.Play(TestToneLength, new EventHandler <StoppedEventArgs>(TestToneStopped));
            }
        }
 /// <summary>
 /// Updates the enabled state of the start button.
 /// Requires all devices to be selected and a unique name for an enabled button.
 /// </summary>
 private void UpdateStartButton()
 {
     if (workerThread.GetCameras().Keys.Count >= 2 && workerThread.GetOutputAudioDevice() != null && workerThread.GetInputAudioDevice() != null && roomNameTextBox.Text.Trim().Length > 0 && !Configuration.GetInstance().Rooms.ContainsKey(roomNameTextBox.Text))
     {
         startCalibrationButton.IsEnabled = true;
     }
     else
     {
         startCalibrationButton.IsEnabled = false;
     }
 }