我正在开发一个屏幕录制软件,它具有音量控制。我下面粘贴的代码是我如何控制音量的方法。
static class NativeMethods
{
[DllImport("winmm.dll")]
public static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume);
[DllImport("winmm.dll", EntryPoint = "waveOutSetVolume")]
public static extern int WaveOutSetVolume(IntPtr hwo, uint dwVolume);
[DllImport("winmm.dll", SetLastError = true)]
public static extern bool PlaySound(string pszSound, IntPtr hmod, uint fdwSound);
}
//Event for handling volume control
private void VolumeSlider(object sender, RoutedPropertyChangedEventArgs<double> e)
{
// Calculate the volume that's being set
int NewVolume = ((ushort.MaxValue / 10) * (int)slider.Value);
// Set the same volume for both the left and the right channels
uint NewVolumeAllChannels = (((uint)NewVolume & 0x0000ffff) | ((uint)NewVolume << 16));
// Set the volume
NativeMethods.WaveOutSetVolume(IntPtr.Zero, NewVolumeAllChannels);
}
通过在Windows上查看Volume Mixer,我可以看到它设置了应用程序的音量而不是设备的音量。这很棒,因为仅更改应用程序的音量会更改其录制的视频的音量。
现在,我想知道是否可以像Windows Volume Mixer中那样为应用程序的卷创建VU Meter。我尝试使用NAudio达到此效果,但不确定如何或是否可以实现。我对其他API持开放态度。
编辑:我不是在问如何改变音量...我只需要一个功能VU Meter像在搅拌机上的。
最佳答案
不想让这个问题没有答案,以防有人偶然发现。基本上@RickLiddle评论有答案。我将根据回答给出修改后的代码,并尝试进行解释。试图学习这一点,我对NAudio&CSCore非常熟悉,因此,如果您需要进一步的帮助,请不要犹豫。
class PeakClass
{
static int CurrentProcessID = 0000;
private static void Main(string[] args)
{
//Basically gets your default audio device and session attached to it
using (var sessionManager = GetDefaultAudioSessionManager2(DataFlow.Render))
{
using (var sessionEnumerator = sessionManager.GetSessionEnumerator())
{
//This will go through a list of all processes uses the device
//the code got two line above.
foreach (var session in sessionEnumerator)
{
//This block of code will get the peak value(value needed for VU Meter)
//For whatever process you need it for (I believe you can also check by name
//but I found that less reliable)
using (var session2 = session.QueryInterface<AudioSessionControl2>())
{
if(session2.ProcessID == CurrentProcessID)
{
using (var audioMeterInformation = session.QueryInterface<AudioMeterInformation>())
{
Console.WriteLine(audioMeterInformation.GetPeakValue());
}
}
}
//Uncomment this block of code if you need the peak values
//of all the processes
//
//using (var audioMeterInformation = session.QueryInterface<AudioMeterInformation>())
//{
// Console.WriteLine(audioMeterInformation.GetPeakValue());
//}
}
}
}
}
private static AudioSessionManager2 GetDefaultAudioSessionManager2(DataFlow dataFlow)
{
using (var enumerator = new MMDeviceEnumerator())
{
using (var device = enumerator.GetDefaultAudioEndpoint(dataFlow, Role.Multimedia))
{
Console.WriteLine("DefaultDevice: " + device.FriendlyName);
var sessionManager = AudioSessionManager2.FromMMDevice(device);
return sessionManager;
}
}
}
}