Windows: volume control edit
bll 2016-12-15 This Tcl stub might be useful to someone.bll 2016-12-19 Updated so that it can be built as either a stand-alone program or as a .dll.load [file join [pwd] winvolume64[info sharedlibextension]] set vol [winvolume] ; # get the volume incr vol -10 set newvol [winvolume $vol] ; # set the volume, always returns the current volume.winmkvol.sh
#!/bin/bash
case $MSYSTEM in
*32)
g++ -m32 -static-libgcc -UWIN_TCL_INTERFACE -o winvolume32.exe \
-I$HOME/local-32/include winvolume.cpp \
-L$HOME/local-32/lib -lole32
g++ -m32 -shared -static-libgcc -DWIN_TCL_INTERFACE -o winvolume32.dll \
-I$HOME/local-32/include -DUSE_TCL_STUBS winvolume.cpp \
-L$HOME/local-32/lib -ltclstub86 -lole32
;;
*64)
g++ -m64 -static-libgcc -UWIN_TCL_INTERFACE -o winvolume64.exe \
-I$HOME/local-64/include winvolume.cpp \
-L$HOME/local-64/lib -lole32
g++ -m64 -shared -static-libgcc -DWIN_TCL_INTERFACE -o winvolume64.dll \
-I$HOME/local-64/include -DUSE_TCL_STUBS winvolume.cpp \
-L$HOME/local-64/lib -ltclstub86 -lole32
;;
esacwinvolume.cpp/*
* Copyright 2016 Brad Lanam Walnut Creek, CA US
* This code is in the public domain.
*
* much of the original volume code from: https://gist.github.com/rdp/8363580
*/
#ifdef WIN_TCL_INTERFACE
# include <tcl.h>
#endif
#include <string.h>
#include <windows.h>
#include <commctrl.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include <stdio.h>
#include <math.h>
#define EXIT_ON_ERROR(hr) \
if (FAILED(hr)) { printf ("error %d occurred\n", -hr); goto Exit; }
#define SAFE_RELEASE(punk) \
if ((punk) != NULL) { (punk)->Release(); (punk) = NULL; }
extern "C" {
int
process (int set, int vol)
{
IAudioEndpointVolume *g_pEndptVol = NULL;
HRESULT hr = S_OK;
IMMDeviceEnumerator *pEnumerator = NULL;
IMMDevice *pDevice = NULL;
OSVERSIONINFO VersionInfo;
float currentVal;
int rc;
ZeroMemory(&VersionInfo, sizeof(OSVERSIONINFO));
VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&VersionInfo);
if (VersionInfo.dwMajorVersion <= 5) {
return -1;
}
CoInitialize(NULL);
// Get enumerator for audio endpoint devices.
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator),
NULL, CLSCTX_INPROC_SERVER,
__uuidof(IMMDeviceEnumerator),
(void**)&pEnumerator);
EXIT_ON_ERROR(hr)
// Get default audio-rendering device.
hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pDevice);
EXIT_ON_ERROR(hr)
hr = pDevice->Activate(__uuidof(IAudioEndpointVolume),
CLSCTX_ALL, NULL, (void**)&g_pEndptVol);
EXIT_ON_ERROR(hr)
if (set) {
float got = (float) vol / 100.0; // needs to be within 1.0 to 0.0
hr = g_pEndptVol->SetMasterVolumeLevelScalar (got, NULL);
EXIT_ON_ERROR(hr)
}
hr = g_pEndptVol->GetMasterVolumeLevelScalar (¤tVal);
EXIT_ON_ERROR(hr)
vol = (int) round(100 * currentVal);
Exit:
SAFE_RELEASE(pEnumerator)
SAFE_RELEASE(pDevice)
SAFE_RELEASE(g_pEndptVol)
CoUninitialize();
return vol;
}
#ifndef WIN_TCL_INTERFACE
int
main (int argc, char *argv[])
{
int set;
int vol;
set = 0;
if (argc > 1) {
set = 1;
vol = atoi (argv[1]);
}
vol = process (set, vol);
printf ("%d\n", vol);
fflush (stdout);
return 0;
}
#endif
#ifdef WIN_TCL_INTERFACE
int winvolumeObjCmd (
ClientData cd,
Tcl_Interp* interp,
int objc,
Tcl_Obj * const objv[]
)
{
int set;
int vol;
int rc;
if (objc != 1 && objc != 2) {
Tcl_WrongNumArgs (interp, 1, objv, "?volume?");
return TCL_ERROR;
}
set = 0;
vol = -1;
if (objc == 2) {
rc = Tcl_GetIntFromObj (interp, objv[1], &vol);
if (rc != TCL_OK) {
return TCL_ERROR;
}
set = 1;
}
vol = process (set, vol);
if (vol < 0) {
return TCL_ERROR;
}
Tcl_SetObjResult (interp, Tcl_NewIntObj (vol));
return TCL_OK;
}
int
Winvolume_Init (Tcl_Interp *interp)
{
Tcl_Encoding utf;
#ifdef USE_TCL_STUBS
if (!Tcl_InitStubs(interp,"8.3",0)) {
return TCL_ERROR;
}
#else
if (!Tcl_PkgRequire(interp,"Tcl","8.3",0)) {
return TCL_ERROR;
}
#endif
Tcl_CreateObjCommand(interp,"winvolume", winvolumeObjCmd, (ClientData) NULL, NULL);
Tcl_PkgProvide(interp,"winvolume","0.1");
return TCL_OK;
}
#endif
} /* extern C */AMucha - 2017-10-12 13:35:59AMucha 2017-10-12 To control a microphone replace eRender with eCapture

