在Java(+ - JNA)中有没有办法在XP + Vista + Windows 7中可靠地设置主系统卷?

时间:2010-07-14 19:07:02

标签: java audio

看来java的声音API适用于单个流,甚至用于设置麦克风的输入,但不适用于在Vista / Windows 7中设置主音量级别。

参考文献:

Java Sound API to access the system/master volume control in Vista and Win 7

How to adjust speaker volume from Java program?

Changing master volume level  仅适用于主卷的XP

任何人都有适合所有人的东西(没有兼容模式或控制鼠标以增加音量[机器人般])。

2 个答案:

答案 0 :(得分:1)

完成了我对JNI的分享,并尽可能明确指出。只要您必须本地完成某些事情,并且假设任务很简单并且性能不是主要问题,我发现启动一个单独的流程比处理JNI或其任何表兄弟要容易得多。以下是一些改编自this文章的C ++代码,它将根据单个命令行参数设置主卷:

#include <WinSDKVer.h>
#define _WIN32_WINNT _WIN32_WINNT_VISTA
#include <SDKDDKVer.h>

#define WIN32_LEAN_AND_MEAN
// Windows Header Files:
#include <windows.h>
#include <tchar.h>

#include <mmdeviceapi.h>
#include <endpointvolume.h> 

int APIENTRY _tWinMain(HINSTANCE hInstance,
                 HINSTANCE hPrevInstance,
                 LPTSTR    lpCmdLine,
                 int       nCmdShow)
{
double newVolume = _ttof(lpCmdLine);

CoInitialize(NULL);

IMMDeviceEnumerator* deviceEnumerator = NULL;
if(CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (LPVOID *)&deviceEnumerator) == S_OK) {
    IMMDevice* defaultDevice = NULL;
    if(deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevice) == S_OK) {
        IAudioEndpointVolume* endpointVolume = NULL;
        if(defaultDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&endpointVolume) == S_OK) {
            endpointVolume->SetMasterVolumeLevelScalar((float)newVolume, NULL);
            endpointVolume->Release();
        }
        defaultDevice->Release();
    }
    deviceEnumerator->Release();
}

CoUninitialize();

return 0;
}

希望这有帮助。

答案 1 :(得分:0)

看到似乎没有本机解决方案,我目前的方法是使用jna发送“键盘音量上下”的键盘敲击:

https://superuser.com/questions/82229/how-to-control-master-volume-in-windows-7/86227#86227

你或许可以创建一个dll,然后挂入“vista volume aware”并实际控制它,并使用jna调用方法。

ffi / jna / jnr / jacob(访问IAudioEndpointVolume等)可能会有效。 (看来jna并不真的支持COM?)在这方面,ffi看起来也很可怕。

可能使用java COM bridge来做同样的事情。所以下一个想法是尝试bridj或jacob