приветствую, делаю девайс с аналоговыми крутилками для регулировки звука, есть 3 потенциометра. программой получаю 3 значения (с каждого из них) задумка такая: 1 - управляет общей громкостью, 2 и 3 настраиваемые, к примеру 2-й управляет громкостью скайпа, 3-й громкостью браузера.
нашел MMDevApi, и у него следующая инициализация
Код:
var //глобальные переменные
endpointVolume: IAudioEndpointVolume = nil;
procedure TForm1.FormCreate(Sender: TObject);
var
deviceEnumerator: IMMDeviceEnumerator;
defaultDevice: IMMDevice;
begin
CoCreateInstance(CLASS_IMMDeviceEnumerator, nil,
CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, deviceEnumerator);
deviceEnumerator.GetDefaultAudioEndpoint(0, 0, defaultDevice);
defaultDevice.Activate(IID_IAudioEndpointVolume,
CLSCTX_INPROC_SERVER, nil, endpointVolume);
end;
используется он вот так:
Код:
var
VolumeLevel: Single;
begin
VolumeLevel:=0.5;
endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
end;
тем самым выставляет громкость на половину
и если с 1 потенциометром и общем уровнем громкости разобрался, то как сделать два других?
UPD
погуглив еще сильнее, нашел что нужно искать какие то сессии, и в моем модуле MMDevAPI нет к примеру
Код:
IAudioSessionEnumerator = interface(IUnknown)
['{E2F5BB11-0570-40CA-ACDD-3AA01277DEE8}']
function GetCount(out SessionCount: integer): HResult; stdcall;
function GetSession(const SessionCount: integer;
out Session: IAudioSessionControl): HResult; stdcall;
end;
этот код я нашел в инете, но не было ничего про IAudioSessionControl, я нашел его описание на страницах микрософта и получилось сделать вот так
Код:
IAudioSessionControl = interface(IUnknown)
['{F4B1A599-7266-4319-A8CA-E70ACB11E8CD}']
function GetDisplayName(pRetVal: LPWSTR): HResult; stdcall;
function GetGroupingParam(pRetVal: TGUID): HResult; stdcall;
function GetIconPath(pRetVal: LPWSTR): HResult; stdcall;
function GetState(pRetVal: AudioSessionState): HResult; stdcall;
function RegisterAudioSessionNotification(NewNotifications
: IAudioSessionEvents): HResult; stdcall;
function SetDisplayName(Value:LPCWSTR;EventContext:LPCGUID): HResult; stdcall;
function SetGroupingParam(sOverride,EventContext:LPCGUID ): HResult; stdcall;
function SetIconPath(Value:LPCWSTR;EventContext:LPCGUID): HResult; stdcall;
function UnregisterAudioSessionNotification(NewNotifications:IAudioSessionEvents): HResult; stdcall;
end;
но тут делфи наподчеркивал вот это: AudioSessionState, IAudioSessionEvents, LPCGUID
не ужели их все придется добавлять по одному с того сайта микрософта? и это вообще поможет?
UPD
Кто нибудь, остановите меня и скажите что модуль MMDevApi есть полностью описанный..... пожалуйста
UPD
я все пересунул из микрософтовского описания что касается сессии колме IAudioSessionManager2 и IAudioSessionControl2, теперь делфи ругается на: AudioSessionState, AudioSessionDisconnectReason, LPCGUID.. думалка почти не работает уже... немного смутной логики позволило LPCGUID заменить на PGUID....
UPD
Я начинаю осознавать что все это зря ибо я понятия не имею как этим пользоваться...
UPD
Нашел вот такое
Код:
; Requirements:
; VA 2.1 - http://www.autohotkey.com/forum/topic23792.html
; Windows 7
; AutoHotkey_L
; Luck?
IID_IAudioSessionManager2 := "{77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F}"
IID_ISimpleAudioVolume := "{87CE5498-68D6-44E5-9215-6DA47EF883D8}"
dev := VA_GetDevice()
if !dev
throw "Can't get device"
if VA_IMMDevice_Activate(dev, IID_IAudioSessionManager2, 7, 0, mgr) != 0
throw "Can't get session manager"
ObjRelease(dev)
if VA_IAudioSessionManager2_GetSessionEnumerator(mgr, enm) != 0
throw "Can't get session enumerator"
ObjRelease(mgr)
VA_IAudioSessionEnumerator_GetCount(enm, count)
Loop % count
{
; IAudioSessionControl *session;
VA_IAudioSessionEnumerator_GetSession(enm, A_Index-1, ssn)
VA_IAudioSessionControl_GetDisplayName(ssn, name)
VA_IAudioSessionControl2_GetProcessId(ssn, pid)
sav := ComObjQuery(ssn, IID_ISimpleAudioVolume)
ObjRelease(ssn)
if !sav ; Unlikely?
throw "Can't get volume control"
VA_ISimpleAudioVolume_GetMasterVolume(sav, volume)
MsgBox %name%`nPID: %pid%`nVolume: %volume%
ObjRelease(sav)
}
ObjRelease(enm)
;
; ISimpleAudioVolume -- currently not included in VA.ahk
;
VA_ISimpleAudioVolume_SetMasterVolume(this, Level, EventContext) {
return DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "uint", this, "float", Level, "uint", VA_GUID(EventContext))
}
VA_ISimpleAudioVolume_GetMasterVolume(this, ByRef Level) {
return DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "uint", this, "float*", Level)
}
VA_ISimpleAudioVolume_SetMute(this, Mute, EventContext) {
return DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "uint", this, "int", Mute, "uint", VA_GUID(EventContext))
}
VA_ISimpleAudioVolume_GetMute(this, ByRef Mute) {
return DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "uint", this, "int*", Mute)
}
но пока не знаю как на делфи сделать
UPD
Код:
procedure TForm1.Button1Click(Sender: TObject);
var asm2:IAudioSessionManager2;
se:IAudioSessionEnumerator;
co:integer;
begin
asm2.GetSessionEnumerator(se);
se.GetCount(co);
caption:=inttostr(co);
end;
код выдает ошибку, что то я явно делаю не так
UPD
есть функция
Код:
function GetSimpleAudioVolumeFromHandle(const AudioDevice: IMMDevice; Hnd: uint; out SimpleAudio: ISimpleAudioVolume; out currguid: tguid): Boolean; stdcall;
при выполнении GetSimpleAudioVolumeFromHandle(defa ultDevice,h,endpointVolume,gi), endpointVolume получается nil, может с ней кто то что то делал?
UPD
после долгих тыканий в библиотеку понял следующее
GetSimpleAudioVolumeFromHandle([устройство вывода],[хендел окна],[выходной регулятор],[выходной гуид]);
но все равно не работает, я не понимаю почему!
UPD
ПОЛУЧИЛОСЬ!!! почти
Код:
procedure TForm1.FormCreate(Sender: TObject);
var
deviceEnumerator: IMMDeviceEnumerator;
DeviceEnumerator1: IMMDeviceEnumerator;
AudioSessionManager: IAudioSessionManager2;
Enumerator: IAudioSessionEnumerator;
defaultDevice: IMMDevice;
SkypeDevice: IMMDevice;
aic:IAudioSessionControl;
s: pwidechar;
h: hWnd;
HR:HRESULT;
cou:integer;
begin
CommPortDriver1.Connect;
h := FindWindow(nil, 'Skype');
CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER,
IID_IMMDeviceEnumerator, deviceEnumerator);
deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, defaultDevice);
defaultDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil,
IUnknown(endpointVolume));
hr:= CoCreateInstance(CLASS_IMMDeviceEnumerator,nil,CLSCTX_ALL,IID_IMMDeviceEnumerator,DeviceEnumerator1);
hr:=DeviceEnumerator1.GetDefaultAudioEndpoint( eRender, eMultimedia, &SkypeDevice);
hr:=SkypeDevice.Activate(IID_IAudioSessionManager2,CLSCTX_ALL, nil,IUnknown(AudioSessionManager));
hr:= AudioSessionManager.GetSessionEnumerator(&Enumerator);
Enumerator.GetCount(cou);
Enumerator.GetSession(cou-1,aic);
AudioSessionManager.GetSimpleAudioVolume(@guid_null,0,sa);
end;
так я могу управлять громкостью своего приложения, мне нужно @guid_null заменить на GUID скайпа или любого другого источника звука
UPD
Забил. больше у меня идей нет.