123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- #include "stdafx.h"
- #include "SpBase.h"
- #include "volumekeeper.h"
- #include <audioclient.h>
- #include <MMDeviceApi.h>
- #include <AudioEngineEndPoint.h>
- #include <DeviceTopology.h>
- #include <EndpointVolume.h>
- #include <functiondiscoverykeys.h>
- #define EXIT_ON_ERROR(x) if (FAILED(x)) {goto Exit;}
- #define RETURN_ERROR(x) FAILED(x)?false:true
- class volume_keeper_t : public IAudioEndpointVolumeCallback
- {
- private:
- char m_dev_key[MAX_PATH];
- int m_in_dev;
- ULONG m_lRef;
- public:
- IAudioEndpointVolume *m_pAudioEndpointVolume;
- GUID m_guidContext;
- float m_kept_value;
- volume_keeper_t(const char *dev_key, int in_dev, int kept_value) : m_lRef(1), m_kept_value(kept_value/100.0f), m_pAudioEndpointVolume(NULL), m_in_dev(in_dev)
- {
- strcpy(m_dev_key, dev_key);
- }
- HRESULT Init()
- {
- IMMDeviceEnumerator *pEnumerator = NULL;
- IMMDeviceCollection *pDeviceCollection = NULL;
-
- HRESULT hr;
- hr = CoCreateGuid(&m_guidContext);
- EXIT_ON_ERROR(hr);
- hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IMMDeviceEnumerator), (void**)&pEnumerator);
- EXIT_ON_ERROR(hr);
- hr = pEnumerator->EnumAudioEndpoints(m_in_dev ? eCapture : eRender, DEVICE_STATE_ACTIVE, &pDeviceCollection);
- EXIT_ON_ERROR(hr);
- UINT nCount = 0;
- hr = pDeviceCollection->GetCount(&nCount);
- EXIT_ON_ERROR(hr);
- for (UINT i = 0; i < nCount; ++i) {
- IMMDevice *pDevice = NULL;
- hr = pDeviceCollection->Item(i, &pDevice);
- if (SUCCEEDED(hr)) {
- char name[260];
- IPropertyStore *pPS = NULL;
- PROPVARIANT value;
- PropVariantInit(&value);
- pDevice->OpenPropertyStore(STGM_READ, &pPS);
- pPS->GetValue(PKEY_Device_FriendlyName, &value);
- WideCharToMultiByte(CP_ACP, 0, value.pwszVal, -1, name, sizeof(name)-1, 0, 0);
- PropVariantClear(&value);
- pPS->Release();
- if (strstr(name, m_dev_key)) {
- hr = pDevice->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (void**)&m_pAudioEndpointVolume);
- if (SUCCEEDED(hr)) {
- hr = m_pAudioEndpointVolume->RegisterControlChangeNotify(this);
- m_pAudioEndpointVolume->SetMasterVolumeLevelScalar(m_kept_value, &m_guidContext);
- }
- pDevice->Release();
- break;
- } else {
- pDevice->Release();
- }
- } else {
- break;
- }
- }
- Exit:
- if (pDeviceCollection) {
- pDeviceCollection->Release();
- }
- if (pEnumerator) {
- pEnumerator->Release();
- }
- return hr;
- }
- void Term()
- {
- if (m_pAudioEndpointVolume) {
- m_pAudioEndpointVolume->UnregisterControlChangeNotify(this);
- m_pAudioEndpointVolume->Release();
- }
- }
- void ChangeValue(int nValue)
- {
- m_kept_value=nValue/100.f;
- }
- ULONG STDMETHODCALLTYPE AddRef()
- {
- return InterlockedIncrement(&m_lRef);
- }
- ULONG STDMETHODCALLTYPE Release()
- {
- ULONG ulRef = InterlockedDecrement(&m_lRef);
- if (0 == ulRef) {
- delete this;
- }
- return ulRef;
- }
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, VOID **ppvInterface)
- {
- if (IID_IUnknown == riid) {
- AddRef();
- *ppvInterface = (IUnknown*)this;
- } else if (__uuidof(IAudioEndpointVolumeCallback) == riid) {
- AddRef();
- *ppvInterface = (IAudioEndpointVolumeCallback*)this;
- } else {
- *ppvInterface = NULL;
- return E_NOINTERFACE;
- }
- return S_OK;
- }
- // Callback method for endpoint-volume-change notifications.
- HRESULT STDMETHODCALLTYPE OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify)
- {
- if (pNotify == NULL) {
- return E_INVALIDARG;
- }
- if (pNotify->guidEventContext != m_guidContext) {
- if (pNotify->fMasterVolume != m_kept_value) {
- m_pAudioEndpointVolume->SetMasterVolumeLevelScalar(m_kept_value, &m_guidContext);
- }
- }
- return S_OK;
- }
- };
- void *volume_keeper_create(const char *dev_key_name, int in_dev, int kept_value)
- {
- if (!dev_key_name) {
- return NULL;
- }
-
- if (kept_value < 0 || kept_value > 100) {
- return NULL;
- }
- volume_keeper_t *inst = new volume_keeper_t(dev_key_name, in_dev, kept_value);
- if (SUCCEEDED(inst->Init()))
- {
- return inst;
- }
- else
- {
- inst->Release();
- }
- return NULL;
- }
- void volume_keeper_destroy(void *inst)
- {
- volume_keeper_t *keeper = (volume_keeper_t*)inst;
- keeper->Term();
- keeper->Release();
- }
- void volume_keeper_change(void *inst,int change_value)
- {
- volume_keeper_t *keeper = (volume_keeper_t*)inst;
- float fCurValue = 0.0;
- keeper->m_kept_value =(change_value/100.0f);
- if (keeper->m_kept_value>1)
- {
- keeper->m_kept_value = 1;
- }
- else if (keeper->m_kept_value<0)
- {
- keeper->m_kept_value = 0;
- }
- if (NULL != keeper->m_pAudioEndpointVolume){
- keeper->m_pAudioEndpointVolume->SetMasterVolumeLevelScalar(keeper->m_kept_value,&keeper->m_guidContext);
- }
-
- }
- bool get_audiodevice_volumn(void *inst,int*nvalue)
- {
- volume_keeper_t *keeper = (volume_keeper_t*)inst;
- float fValue = 0.0;
- if (NULL != keeper->m_pAudioEndpointVolume){
- keeper->m_pAudioEndpointVolume->GetMasterVolumeLevelScalar(&fValue);
- }
- *nvalue = fValue*100;
- return true;
- }
|