private static T GetCoreAudioObject <T>(int pid) { IMMDevice speakers = VolumeMixer.GetOutputDevice(); IAudioSessionManager2 mgr = VolumeMixer.GetOutputDeviceSessionManager(speakers); IAudioSessionEnumerator sessionEnumerator = VolumeMixer.GetOutputDeviceSessionEnumerator(mgr); int count; sessionEnumerator.GetCount(out count); dynamic volumeControl = null; for (int i = 0; i < count; i++) { IAudioSessionControl2 ctl; sessionEnumerator.GetSession(i, out ctl); int cpid; ctl.GetProcessId(out cpid); if (cpid == pid) { volumeControl = (T)ctl; break; } Marshal.ReleaseComObject(ctl); } Marshal.ReleaseComObject(sessionEnumerator); Marshal.ReleaseComObject(mgr); Marshal.ReleaseComObject(speakers); return(volumeControl); }
public static float?GetApplicationPeak(int pid) { IAudioMeterInformation meter = VolumeMixer.GetCoreAudioObject <IAudioMeterInformation>(pid); if (meter == null) { return(null); } float peak; meter.GetPeakValue(out peak); return(peak); }
public static void SetApplicationMute(int pid, bool mute) { ISimpleAudioVolume volume = VolumeMixer.GetCoreAudioObject <ISimpleAudioVolume>(pid); if (volume == null) { return; } Guid guid = Guid.Empty; volume.SetMute(mute, ref guid); Marshal.ReleaseComObject(volume); }
public static void SetApplicationVolume(int pid, float level) { ISimpleAudioVolume volume = VolumeMixer.GetCoreAudioObject <ISimpleAudioVolume>(pid); if (volume == null) { return; } Guid guid = Guid.Empty; volume.SetMasterVolume(level / 100, ref guid); Marshal.ReleaseComObject(volume); }
public static bool?GetApplicationMute(int pid) { ISimpleAudioVolume volume = VolumeMixer.GetCoreAudioObject <ISimpleAudioVolume>(pid); if (volume == null) { return(null); } bool mute; volume.GetMute(out mute); Marshal.ReleaseComObject(volume); return(mute); }
public static float?GetApplicationVolume(int pid) { ISimpleAudioVolume volume = VolumeMixer.GetCoreAudioObject <ISimpleAudioVolume>(pid); if (volume == null) { return(null); } float level; volume.GetMasterVolume(out level); Marshal.ReleaseComObject(volume); return(level * 100); }
/** * Resets all reduced applications to the stored volume level */ public void RemoveReduction() { if (!this._ReductionApplied) { return; } this._WriteIfDebugging("Restoring volume levels"); foreach (AppVolume appVolume in this.GetStoredVolumeLevels()) { if (!this._IsWhitelisted(appVolume)) { VolumeMixer.SetApplicationVolume(appVolume.ProcessID, appVolume.Volume); } } this._ReductionApplied = false; }
/** * Stores the current volume level of all applications and reduces their volumes by the reduction percent */ public void ApplyReduction() { this._LastReductionAttemptMicroTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(); if (this._ReductionApplied) { this._WriteIfDebugging("Already reduced volume levels"); return; } this._ReductionApplied = true; this.StoreCurrentVolumeLevels(); this._WriteIfDebugging("Reducing volume levels"); foreach (AppVolume appVolume in this.GetStoredVolumeLevels()) { if (!this._IsWhitelisted(appVolume)) { double newVolume = appVolume.Volume - (appVolume.Volume * this._Reduction); this._WriteIfDebugging("Setting " + appVolume.Name + " from " + appVolume.Volume + " to " + newVolume); if (!this._Debug) { VolumeMixer.SetApplicationVolume(appVolume.ProcessID, (float)newVolume); } } } //Wait for X to reset the timers var resetTimer = new Timer(); resetTimer.Interval = 100; resetTimer.AutoReset = true; resetTimer.Elapsed += (object sender, ElapsedEventArgs e) => { if (DateTimeOffset.Now.ToUnixTimeMilliseconds() - this._LastReductionAttemptMicroTime >= 1000 * this._RestoreVolumeAfter) { this.RemoveReduction(); resetTimer.Stop(); resetTimer.Dispose(); } }; resetTimer.Start(); }
/** * Gets the volume levels for all current processes */ public static List <AppVolume> GetAppVolumes() { List <AppVolume> appVolumes = new List <AppVolume>(); foreach (Process process in Process.GetProcesses()) { float?processVolume = VolumeMixer.GetApplicationVolume(process.Id); if (processVolume != null) { appVolumes.Add(new AppVolume { ProcessID = process.Id, Path = PathFinder.GetProcessFilename(process), Name = process.ProcessName, Volume = (float)processVolume }); } } return(appVolumes); }
/** * Listens for audio coming out of known voip applications */ public void ListenForIncomingVOIP() { int msSincePidCheck = AudioReducer._PIDRecheckInterval; int msSinceCheck = 0; List <float> valuesSinceCheck = new List <float>(); Dictionary <int, string> voipPids = new Dictionary <int, string>(); Timer voipChecker = new Timer(); voipChecker.AutoReset = true; voipChecker.Interval = AudioReducer._VolumeRecheckInterval; voipChecker.Elapsed += (sender, e) => { msSinceCheck += (int)voipChecker.Interval; msSincePidCheck += (int)voipChecker.Interval; //Re-check voip apps for new/removed processes if (msSincePidCheck > AudioReducer._PIDRecheckInterval) { msSincePidCheck = 0; Process[] currentProcesses = Process.GetProcesses(); //Remove pids which are no longer valid foreach (KeyValuePair <int, string> voipPid in voipPids.ToList()) { if (!currentProcesses.Any(process => process.Id == voipPid.Key)) { voipPids.Remove(voipPid.Key); this._WriteIfDebugging("Voip app " + voipPid.Value + " (" + voipPid.Key + ") process lost"); } } //Load the pid by scanning the process list foreach (String voipAppPath in this._VoipApps) { foreach (Process process in currentProcesses) { if (!voipPids.ContainsKey(process.Id)) { String processPath = PathFinder.GetProcessFilename(process); if (this._DoesPathWildcardMatch(processPath, voipAppPath)) { voipPids[process.Id] = voipAppPath; this._WriteIfDebugging("Voip app " + voipAppPath + " found as process " + process.Id); } } } } } //Update average value lists foreach (KeyValuePair <int, string> voipPid in voipPids) { float?currentVolume = VolumeMixer.GetApplicationPeak(voipPid.Key); if (currentVolume.HasValue) { valuesSinceCheck.Add(currentVolume.Value); } } //If we've reached our check threshold check what the values have been if (msSinceCheck >= this._MinimumNoiseLength * 1000) { double average = 0; if (valuesSinceCheck.Count() > 0) { average = valuesSinceCheck.Average(); } if (average > this._MinimumAppVolume) { this._WriteIfDebugging("Heard apps at qualifying average volume: " + average); this.ApplyReductionIfNoisy(); } valuesSinceCheck.Clear(); msSinceCheck = 0; } }; voipChecker.Start(); }