0

Appears that java's sound API's work well for single streams, and even for setting the input from the microphone, but not for setting the master volume level in Vista/Windows 7.

refs:

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 only works on XP for the master volume

Anybody have something that'll work for all of them (without compatibility mode or controlling the mouse to increase volume level [robot-like]).

Community
  • 1
  • 1
rogerdpack
  • 62,887
  • 36
  • 269
  • 388

2 Answers2

1

Have done my share of JNI and steer clear where I can. As long as you have to go native to accomplish something, and assuming the task is simple and performance isn't a major issue, I've found it a lot easier to launch a separate process than deal with JNI or any of its cousins. Here is some C++ code adapted from this article that will set the master volume based on a single command line parameter:

#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;
}

Hope this helps.

Ken
  • 172
  • 7
0

seeing as there appears to be no native solution, my current method is to use jna to send keyboard strokes for "keyboard volume up and down":

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

You might be able to create a dll then hook into it that is "vista volume aware" and could actually control it right, and call methods on that, using jna.

ffi/jna/jnr/jacob (to access IAudioEndpointVolume etc.) might work. (appears jna doesn't really support COM?) ffi looks scary too, in that regard.

Could possibly use a java COM bridge to do the same. So next thought is to try either bridj or jacob

Community
  • 1
  • 1
rogerdpack
  • 62,887
  • 36
  • 269
  • 388