Exemplo n.º 1
0
        private void AudioEndpointVolume_OnVolumeNotification(NAudio.CoreAudioApi.AudioVolumeNotificationData data)
        {
            _Master.Volume = data.MasterVolume;
            int ChannelCount = data.ChannelVolume.Count();

            for (int iChannel = 0; iChannel < ChannelCount; ++iChannel)
            {
                NAudio.CoreAudioApi.AudioEndpointVolumeChannel Channel = Device.AudioEndpointVolume.Channels[iChannel];
                _Channels[iChannel].Volume = Math.Round(Channel.VolumeLevelScalar * 100.0);
            }
            OnPropertyChanged("Master");
            OnPropertyChanged("Channels");
        }
Exemplo n.º 2
0
        static int correcting;      // = 0;
        async void VolumeChangedHandler(NAudio.CoreAudioApi.AudioVolumeNotificationData data)
        {
            var    oldVol = Volume;
            double newVol = data.MasterVolume * 100;

            if (Math.Abs(newVol - Target) <= SmallVolumeHysterisis)
            {
                if (Taskmaster.ShowInaction)
                {
                    Log.Verbose("<Microphone> Volume change too small ({VolumeChange:N1}%) to act on.", Math.Abs(newVol - Target));
                }
                return;
            }

            if (Taskmaster.Trace)
            {
                Log.Verbose("<Microphone> Volume changed from {OldVolume:N1}% to {NewVolume:N1}%", oldVol, newVol);
            }

            // This is a light HYSTERISIS limiter in case someone is sliding a volume bar around,
            // we act on it only once every [AdjustDelay] ms.
            // HOPEFULLY there are no edge cases with this triggering just before last adjustment
            // and the notification for the last adjustment coming slightly before. Seems super unlikely tho.
            // TODO: Delay this even more if volume is changed ~2 seconds before we try to do so.
            if (Math.Abs(newVol - Target) >= VolumeHysterisis)             // Volume != Target for double
            {
                if (Taskmaster.Trace)
                {
                    Log.Verbose("<Microphone> DEBUG: Volume changed = [{OldVolume:N1} -> {NewVolume:N1}], Off.Target: {VolumeOffset:N1}",
                                oldVol, newVol, Math.Abs(newVol - Target));
                }

                if (Atomic.Lock(ref correcting))
                {
                    try
                    {
                        await System.Threading.Tasks.Task.Delay(AdjustDelay);                         // actual hysterisis, this should be cancellable

                        oldVol = Control.Percent;
                        Log.Information("<Microphone> Correcting volume from {OldVolume:N1} to {NewVolume:N1}", oldVol, Target);
                        Volume        = Target;
                        Corrections  += 1;
                        micstatsdirty = true;

                        VolumeChanged?.Invoke(this, new VolumeChangedEventArgs {
                            Old = oldVol, New = Target, Corrections = Corrections
                        });
                    }
                    catch { throw; }                      // required for finally to be guaranteed
                    finally
                    {
                        Atomic.Unlock(ref correcting);
                    }
                }
                else
                {
                    if (Taskmaster.Trace)
                    {
                        Log.Verbose("<Microphone> DEBUG CorrectionAlreadyQueued");
                    }
                }
            }
            else
            {
                if (Taskmaster.Trace)
                {
                    Log.Verbose("<Microphone> DEBUG NotCorrected");
                }
            }
        }