如何将系统音量级别作为从 0 到 100 的标量?
How to get system volume level as a scalar from 0 to 100?
我目前正在开发 "Volume mixer" 来控制我电脑上每个程序的音量 (Windows 10)。
如何将每个 program/audio 会话的音量水平作为从 0 到 100 的标量?
如您所见,在下面的代码中,我找到了 GetPeakValue
函数,但它 returns 的值类似于 0.0812654 或 0.021352。
我确定这些值是从 1.0 到 0.0 的标量中每个音频会话的音量。但我想要的是音量限制,例如您可以在 windows 混音器中设置,而不是当前级别。因此,如果我将程序音量级别设置为 50%,我想要一个类似 0.5 的值。
在第二个函数 (getVolume
) 中,您会看到我已经获得了 0-100 标量中的主音量,但是端点设备已经具有标量级别的函数。因此,我至少需要相同的函数或计算才能为每个音频会话获得这样的标量。
void getSessions() {
CoInitialize(NULL);
IMMDeviceEnumerator *pDeviceEnumerator = NULL;
IMMDevice *pDevice = NULL;
IAudioSessionManager2 *pAudioSessionManager2 = NULL;
IAudioSessionEnumerator *pAudioSessionEnumerator = NULL;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDeviceEnumerator);
pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
pDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void **) &pAudioSessionManager2);
pAudioSessionManager2->GetSessionEnumerator(&pAudioSessionEnumerator);
int nSessionCount;
pAudioSessionEnumerator->GetCount(&nSessionCount);
std::cout << "Session Count: " << nSessionCount << std::endl;
while (true) {
for (int nSessionIndex = 0; nSessionIndex < nSessionCount; nSessionIndex++) {
IAudioSessionControl *pSessionControl = NULL;
if (FAILED(pAudioSessionEnumerator->GetSession(nSessionIndex, &pSessionControl)))
continue;
IAudioMeterInformation *pAudioMeterInformation = NULL;
pSessionControl->QueryInterface(&pAudioMeterInformation);
float fPeak = NULL;
pAudioMeterInformation->GetPeakValue(&fPeak);
std::cout << "fPeak Value: " << fPeak << std::endl;
}
std::cout << "\n\n";
Sleep(1000);
}
CoUninitialize();
}
double getVolume() {
float currentVolume = 0;
CoInitialize(NULL);
IMMDeviceEnumerator *deviceEnumerator = NULL;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
IMMDevice *defaultDevice = NULL;
deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
deviceEnumerator->Release();
deviceEnumerator = NULL;
IAudioEndpointVolume *endpointVolume = NULL;
defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
defaultDevice->Release();
defaultDevice = NULL;
float fLevel;
endpointVolume->GetMasterVolumeLevel(&fLevel);
qDebug() << "FLevel: ";
qDebug() << fLevel;
endpointVolume->GetMasterVolumeLevelScalar(¤tVolume);
endpointVolume->Release();
CoUninitialize();
return (double)(currentVolume * 100);
}
好的,我找到了解决问题的方法!
我必须在 SessionControl 上调用 QueryInterface 才能访问 ISimpleAudioVolume,您可以在其中使用函数 GetMasterVolume 和 SetMasterVolume。它是一个 0-1 标量,但您可以将它乘以 100 以获得 0-100 标量。如果系统的主音量为 50%,如果程序音量也为 50%,则输出为 1,因此输出基于系统的主音量!
感谢您的每一条评论和帮助!
这里是工作代码:
void getSessions() {
CoInitialize(NULL);
IMMDeviceEnumerator *pDeviceEnumerator;
IMMDevice *pDevice;
IAudioSessionManager2 *pAudioSessionManager2;
IAudioSessionEnumerator *pAudioSessionEnumerator;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDeviceEnumerator);
pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
pDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void **) &pAudioSessionManager2);
pAudioSessionManager2->GetSessionEnumerator(&pAudioSessionEnumerator);
int nSessionCount;
pAudioSessionEnumerator->GetCount(&nSessionCount);
while (true) {
for (int nSessionIndex = 0; nSessionIndex < nSessionCount; nSessionIndex++) {
IAudioSessionControl *pSessionControl;
if (FAILED(pAudioSessionEnumerator->GetSession(nSessionIndex, &pSessionControl)))
continue;
ISimpleAudioVolume *pSimpleAudioVolume;
pSessionControl->QueryInterface(&pSimpleAudioVolume);
float fLevel;
pSimpleAudioVolume->GetMasterVolume(&fLevel);
std::cout << "fLevel Value: " << fLevel << std::endl;
}
Sleep(1000);
}
CoUninitialize();
}
我目前正在开发 "Volume mixer" 来控制我电脑上每个程序的音量 (Windows 10)。
如何将每个 program/audio 会话的音量水平作为从 0 到 100 的标量?
如您所见,在下面的代码中,我找到了 GetPeakValue
函数,但它 returns 的值类似于 0.0812654 或 0.021352。
我确定这些值是从 1.0 到 0.0 的标量中每个音频会话的音量。但我想要的是音量限制,例如您可以在 windows 混音器中设置,而不是当前级别。因此,如果我将程序音量级别设置为 50%,我想要一个类似 0.5 的值。
在第二个函数 (getVolume
) 中,您会看到我已经获得了 0-100 标量中的主音量,但是端点设备已经具有标量级别的函数。因此,我至少需要相同的函数或计算才能为每个音频会话获得这样的标量。
void getSessions() {
CoInitialize(NULL);
IMMDeviceEnumerator *pDeviceEnumerator = NULL;
IMMDevice *pDevice = NULL;
IAudioSessionManager2 *pAudioSessionManager2 = NULL;
IAudioSessionEnumerator *pAudioSessionEnumerator = NULL;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDeviceEnumerator);
pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
pDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void **) &pAudioSessionManager2);
pAudioSessionManager2->GetSessionEnumerator(&pAudioSessionEnumerator);
int nSessionCount;
pAudioSessionEnumerator->GetCount(&nSessionCount);
std::cout << "Session Count: " << nSessionCount << std::endl;
while (true) {
for (int nSessionIndex = 0; nSessionIndex < nSessionCount; nSessionIndex++) {
IAudioSessionControl *pSessionControl = NULL;
if (FAILED(pAudioSessionEnumerator->GetSession(nSessionIndex, &pSessionControl)))
continue;
IAudioMeterInformation *pAudioMeterInformation = NULL;
pSessionControl->QueryInterface(&pAudioMeterInformation);
float fPeak = NULL;
pAudioMeterInformation->GetPeakValue(&fPeak);
std::cout << "fPeak Value: " << fPeak << std::endl;
}
std::cout << "\n\n";
Sleep(1000);
}
CoUninitialize();
}
double getVolume() {
float currentVolume = 0;
CoInitialize(NULL);
IMMDeviceEnumerator *deviceEnumerator = NULL;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator);
IMMDevice *defaultDevice = NULL;
deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice);
deviceEnumerator->Release();
deviceEnumerator = NULL;
IAudioEndpointVolume *endpointVolume = NULL;
defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume);
defaultDevice->Release();
defaultDevice = NULL;
float fLevel;
endpointVolume->GetMasterVolumeLevel(&fLevel);
qDebug() << "FLevel: ";
qDebug() << fLevel;
endpointVolume->GetMasterVolumeLevelScalar(¤tVolume);
endpointVolume->Release();
CoUninitialize();
return (double)(currentVolume * 100);
}
好的,我找到了解决问题的方法!
我必须在 SessionControl 上调用 QueryInterface 才能访问 ISimpleAudioVolume,您可以在其中使用函数 GetMasterVolume 和 SetMasterVolume。它是一个 0-1 标量,但您可以将它乘以 100 以获得 0-100 标量。如果系统的主音量为 50%,如果程序音量也为 50%,则输出为 1,因此输出基于系统的主音量!
感谢您的每一条评论和帮助!
这里是工作代码:
void getSessions() {
CoInitialize(NULL);
IMMDeviceEnumerator *pDeviceEnumerator;
IMMDevice *pDevice;
IAudioSessionManager2 *pAudioSessionManager2;
IAudioSessionEnumerator *pAudioSessionEnumerator;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&pDeviceEnumerator);
pDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
pDevice->Activate(__uuidof(IAudioSessionManager2), CLSCTX_ALL, NULL, (void **) &pAudioSessionManager2);
pAudioSessionManager2->GetSessionEnumerator(&pAudioSessionEnumerator);
int nSessionCount;
pAudioSessionEnumerator->GetCount(&nSessionCount);
while (true) {
for (int nSessionIndex = 0; nSessionIndex < nSessionCount; nSessionIndex++) {
IAudioSessionControl *pSessionControl;
if (FAILED(pAudioSessionEnumerator->GetSession(nSessionIndex, &pSessionControl)))
continue;
ISimpleAudioVolume *pSimpleAudioVolume;
pSessionControl->QueryInterface(&pSimpleAudioVolume);
float fLevel;
pSimpleAudioVolume->GetMasterVolume(&fLevel);
std::cout << "fLevel Value: " << fLevel << std::endl;
}
Sleep(1000);
}
CoUninitialize();
}