First commit
This commit is contained in:
commit
cd2cc84f53
|
@ -0,0 +1,2 @@
|
|||
x64/
|
||||
.vs/
|
|
@ -0,0 +1,72 @@
|
|||
#include "AudioSessionEvents.h"
|
||||
|
||||
HRESULT QueryInterface(IAudioSessionEvents* this)
|
||||
{
|
||||
printf("IAudioSessionEvents->lpVtbl->QueryInterface()\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE Release(IAudioSessionEvents * this)
|
||||
{
|
||||
printf("IAudioSesssionEvents->lpVtbl-Release()\n");
|
||||
return S_OK;
|
||||
/*
|
||||
ULONG ulRef = InterlockedDecrement(&this->m_cRefAll);
|
||||
if (0 == ulRef)
|
||||
{
|
||||
free(this);
|
||||
//TODO "delete" is from C++, what is it's equivalent in C?
|
||||
//delete this;
|
||||
}
|
||||
return ulRef;
|
||||
*/
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef(IAudioSessionEvents * this)
|
||||
{
|
||||
printf("IAudioSessionEvents->lpVtbl->AddRef()\n");
|
||||
return S_OK;
|
||||
//return InterlockedIncrement(&this->m_cRefAll);
|
||||
}
|
||||
|
||||
HRESULT OnChannelVolumeChanged(IAudioSessionEvents* this, DWORD ChannelCount, float* NewChannelVolumeArray, DWORD ChangedChannel, LPCGUID EventContext)
|
||||
{
|
||||
printf("IAudioSessionEvents->lpVtbl->OnChannelVolumeChanged()\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT OnDisplayNameChanged(IAudioSessionEvents* this, LPCWSTR NewDisplayName, LPCGUID EventContext)
|
||||
{
|
||||
printf("IAudioSessionEvents->lpVtbl->OnDisplayNameChanged()\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT OnGroupingParamChanged(IAudioSessionEvents* this, LPCGUID NewGroupingParam, LPCGUID EventContext)
|
||||
{
|
||||
printf("IAudioSessionEvents->lpVtbl->OnGroupingParamChanged()\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT OnIconPathChanged(IAudioSessionEvents* this, LPCWSTR NewIconPath, LPCGUID EventContext)
|
||||
{
|
||||
printf("IAudioSessionEvents->lpVtbl->OnIconPathChanged()\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT OnSessionDisconnected(IAudioSessionEvents* this, AudioSessionDisconnectReason DisconnectReason)
|
||||
{
|
||||
printf("IAudioSessionEvents->lpVtbl->OnSessionDisconnected()\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT OnSimpleVolumeChanged(IAudioSessionEvents* this, float NewVolume, BOOL NewMute, LPCGUID EventContext)
|
||||
{
|
||||
printf("IAudioSessionEvents->lpVtbl->OnSimpleVolumeChanged()\n");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT OnStateChanged(IAudioSessionEvents* this, AudioSessionState NewState)
|
||||
{
|
||||
printf("IAudioSessionEvents->lpVtbl->OnStateChanged()\n");
|
||||
return S_OK;
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
#ifndef _AUDIOSESSIONECENTS_H_
|
||||
#define _AUDIOSESSIONECENTS_H_
|
||||
|
||||
#include <combaseapi.h>
|
||||
#include <audiopolicy.h>
|
||||
#include <cstdbool>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifndef __IAudioSessionEvents_FWD_DEFINED__
|
||||
#define __IAudioSessionEvents_FWD_DEFINED__
|
||||
typedef interface IAudioSessionEvents IAudioSessionEvents;
|
||||
|
||||
#endif /* __IAudioSessionEvents_FWD_DEFINED__ */
|
||||
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(IAudioSessionNotification*, REFIID, void**);
|
||||
ULONG STDMETHODCALLTYPE AddRef(IAudioSessionEvents*);
|
||||
ULONG STDMETHODCALLTYPE Release(IAudioSessionEvents*);
|
||||
HRESULT OnChannelVolumeChanged(IAudioSessionEvents*, DWORD, float*, DWORD, LPCGUID);
|
||||
HRESULT OnDisplayNameChanged(IAudioSessionEvents*, LPCWSTR, LPCGUID);
|
||||
HRESULT OnGroupingParamChanged(IAudioSessionEvents*, LPCGUID, LPCGUID);
|
||||
HRESULT OnIconPathChanged(IAudioSessionEvents*, LPCWSTR, LPCGUID);
|
||||
HRESULT OnSessionDisconnected(IAudioSessionEvents*, AudioSessionDisconnectReason);
|
||||
HRESULT OnSimpleVolumeChanged(IAudioSessionEvents*, float, BOOL, LPCGUID);
|
||||
HRESULT OnStateChanged(IAudioSessionEvents*, AudioSessionState);
|
||||
|
||||
typedef struct IAudioSessionEventsVtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
|
||||
HRESULT(STDMETHODCALLTYPE* QueryInterface)(
|
||||
IAudioSessionEvents* This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
_COM_Outptr_ void** ppvObject);
|
||||
|
||||
DECLSPEC_XFGVIRT(IUnknown, AddRef)
|
||||
ULONG(STDMETHODCALLTYPE* AddRef)(
|
||||
IAudioSessionEvents* This);
|
||||
|
||||
DECLSPEC_XFGVIRT(IUnknown, Release)
|
||||
ULONG(STDMETHODCALLTYPE* Release)(
|
||||
IAudioSessionEvents* This);
|
||||
|
||||
DECLSPEC_XFGVIRT(IAudioSessionEvents, OnChannelVolumeChange)
|
||||
HRESULT(STDMETHODCALLTYPE* OnChannelVolumeChange)(
|
||||
IAudioSessionEvents* This,
|
||||
/* [annotation][in] */
|
||||
_In_ DWORD ChannelCount,
|
||||
/* [annotation][in] */
|
||||
_In_ float* NewChannelVolumeArray,
|
||||
/* [annotation][in] */
|
||||
_In_ DWORD ChangedChannel,
|
||||
/* [annotation][in] */
|
||||
_In_ LPCGUID EventContext );
|
||||
|
||||
DECLSPEC_XFGVIRT(IAudioSessionEvents, OnDisplayNameChanged)
|
||||
HRESULT(STDMETHODCALLTYPE* OnDisplayNameChanged)(
|
||||
IAudioSessionEvents* This,
|
||||
/* [annotation][in] */
|
||||
_In_ LPCWSTR NewDisplayName,
|
||||
/* [annotation][in] */
|
||||
_In_ LPCGUID EventContext);
|
||||
|
||||
DECLSPEC_XFGVIRT(IAudioSessionEvents, OnGroupingParamChanged)
|
||||
HRESULT(STDMETHODCALLTYPE* OnGroupingParamChanged)(
|
||||
IAudioSessionEvents* This,
|
||||
/* [annotation][in] */
|
||||
_In_ LPCGUID NewGroupingParam,
|
||||
/* [annotation][in] */
|
||||
_In_ LPCGUID EventContext);
|
||||
|
||||
DECLSPEC_XFGVIRT(IAudioSessionEvents, OnIconPathChanged)
|
||||
HRESULT(STDMETHODCALLTYPE* OnIconPathChanged)(
|
||||
IAudioSessionEvents* This,
|
||||
/* [annotation][in] */
|
||||
_In_ LPCWSTR NewIconPath,
|
||||
/* [annotation][in] */
|
||||
_In_ LPCGUID EventContext);
|
||||
|
||||
DECLSPEC_XFGVIRT(IAudioSessionEvents, OnSessionDisconnected)
|
||||
HRESULT(STDMETHODCALLTYPE* OnSessionDisconnected)(
|
||||
IAudioSessionEvents* This,
|
||||
/* [annotation][in] */
|
||||
_In_ AudioSessionDisconnectReason DisconnectReason );
|
||||
|
||||
DECLSPEC_XFGVIRT(IAudioSessionEvents, OnSimpleVolumeChanged)
|
||||
HRESULT(STDMETHODCALLTYPE* OnSimpleVolumeChanged)(
|
||||
IAudioSessionEvents* This,
|
||||
/* [annotation][in] */
|
||||
_In_ float NewVolume,
|
||||
/* [annotation][in] */
|
||||
_In_ BOOL NewMute,
|
||||
/* [annotation][in] */
|
||||
_In_ LPCGUID EventContext );
|
||||
|
||||
DECLSPEC_XFGVIRT(IAudioSessionEvents, OnStateChanged)
|
||||
HRESULT(STDMETHODCALLTYPE* OnStateChanged)(
|
||||
IAudioSessionEvents* This,
|
||||
/* [annotation][in] */
|
||||
_In_ AudioSessionState NewState );
|
||||
|
||||
END_INTERFACE
|
||||
} IAudioSessionEventsVtbl;
|
||||
|
||||
interface IAudioSessionEvents
|
||||
{
|
||||
CONST_VTBL struct IAudioSessionEventsVtbl* lpVtbl;
|
||||
LONG m_cRefAll;
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef _CLSIDS_AND_IIDS_H_
|
||||
#define _CLSIDS_AND_IIDS_H_
|
||||
|
||||
// For whatever reason IID's and CLSID's are not easily accessible with C, C++ can use __uuidof() or something.
|
||||
// I am unclear on wht the proper fix is supposed to be but this works to fix the LNK2001 error for underfined externals
|
||||
//#include <initguid.h>
|
||||
|
||||
//BCDE0395-E52F-467C-8E3D-C4579291692E
|
||||
const CLSID CLSID_MMDeviceEnumerator = { 0xBCDE0395, 0xE52F, 0x467C, { 0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E } };
|
||||
//const IID IID_IMMDeviceEnumerator= {0xA95664D, 0x9614, 0x4F35, 0xA746, 0xDE8DB63617E6};
|
||||
//A95664D2-9614-4F35-A746-DE8DB63617E6
|
||||
const IID IID_IMMDeviceEnumerator = { 0xA95664D2, 0x9614, 0x4F35, { 0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6 } };
|
||||
//BFA971F1-4D5E-40BB-935E-967039BFBEE4
|
||||
const IID IID_IAudioSessionManager = { 0xBFA971F1, 0x4D5E, 0x40BB, { 0x93, 0x5E, 0x96, 0x70, 0x39, 0xBF, 0xBE, 0xE4 } };
|
||||
//1CB9AD4C-DBFA-4c32-B178-C2F568A703B2
|
||||
const IID IID_IAudioClient = { 0x1CB9AD4C, 0xDBFA, 0x4C32, { 0xB1, 0x78, 0xC2, 0xF5, 0x68, 0xA7, 0x03, 0xB2 } };
|
||||
//F4B1A599-7266-4319-A8CA-E70ACB11E8CD
|
||||
const IID IID_IAudioSessionControl = { 0xF4B1A599, 0x7266, 0x4319, { 0xA8, 0xCA, 0xE7, 0x0A, 0xCB, 0x11, 0xE8, 0xCD } };
|
||||
//5CDF2C82 - 841E-4546 - 9722 - 0CF74078229A
|
||||
const IID IID_IAudioEndpointVolume = { 0x5CDF2C82, 0x841E, 0x4546, { 0x97, 0x22, 0x0C, 0xF7, 0x40, 0x78, 0x22, 0x9A } };
|
||||
//77AA99A0 - 1BD6 - 484F - 8BC7 - 2C654C9A9B6F
|
||||
const IID IID_IAudioSessionManager2 = { 0x77AA99A0, 0x1BD6, 0x484F, { 0x8B, 0xC7, 0x2C, 0x65, 0x4C, 0x9A, 0x9B, 0x6F } };
|
||||
//BFB7FF88-7239-4FC9-8FA2-07C950BE9C6D
|
||||
const IID IID_IAudioSessionControl2 = { 0xBFB7FF88, 0x7239, 0x4FC9, {0x8F, 0xA2, 0x07, 0xC9, 0x50, 0xBE, 0x9C, 0x6D } };
|
||||
//641DD20B - 4D41 - 49CC - ABA3 - 174B9477BB08
|
||||
const IID IID_IAudioSessionNotification = { 0x641DD20B, 0x4D41, 0x49CC, { 0xAB, 0xA3, 0x17, 0x4B, 0x94, 0x77, 0xBB, 0x08 } };
|
||||
#endif
|
|
@ -0,0 +1,149 @@
|
|||
#include "IAudioSessionEvents.h"
|
||||
|
||||
HRESULT InitializeAudioSessionEvents(IAudioSessionEvents** this)
|
||||
{
|
||||
// Initializes the IAudioSessionNotification struct, this involves creating it, allocating memory, setting initial vaules and assigning the functions to be used
|
||||
//Allocate memory for the vtable
|
||||
IAudioSessionEventsVtbl* vtbl = malloc(sizeof(IAudioSessionEventsVtbl));
|
||||
|
||||
if (!vtbl)
|
||||
{
|
||||
// If the vtable memory cannot be assigned
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// Asign all the functions
|
||||
vtbl->AddRef = (*IAudioSessionEventsAddRef);
|
||||
vtbl->QueryInterface = (*IAudioSessionEventsQueryInterface);
|
||||
vtbl->Release = (*IAudioSessionEventsRelease);
|
||||
vtbl->OnChannelVolumeChanged = (*IAudioSessionEventsOnChannelVolumeChanged);
|
||||
vtbl->OnDisplayNameChanged = (*IAudioSessionEventsOnDisplayNameChanged);
|
||||
vtbl->OnGroupingParamChanged = (*IAudioSessionEventsOnGroupingParamChanged);
|
||||
vtbl->OnIconPathChanged = (*IAudioSessionEventsOnIconPathChanged);
|
||||
vtbl->OnSessionDisconnected = (*IAudioSessionEventsOnSessionDisconnected);
|
||||
vtbl->OnSimpleVolumeChanged = (*IAudioSessionEventsOnSimpleVolumeChanged);
|
||||
vtbl->OnStateChanged = (*IAudioSessionEventsOnStateChanged);
|
||||
|
||||
//Assign memory for the notifications struct. Cast the pointer returned from malloc to the correct type ??
|
||||
myIAudioSessionEvents* AudioSessionEvents;
|
||||
AudioSessionEvents = (myIAudioSessionEvents*) malloc(sizeof(myIAudioSessionEvents));
|
||||
if (!AudioSessionEvents)
|
||||
{
|
||||
// If the struct memory cannot be assigned free the memory previously assigned to the vtable and return
|
||||
free(vtbl);
|
||||
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// Add the virtual table to the strut
|
||||
AudioSessionEvents->lpVtbl = vtbl;
|
||||
AudioSessionEvents->cRef = 0;
|
||||
|
||||
// Update the pointer address passed into the function
|
||||
*this = (*IAudioSessionEvents) AudioSessionEvents;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE IAudioSessionEventsQueryInterface(IAudioSessionEvents* this, REFIID riid, void** ppvoid)
|
||||
{
|
||||
if (!this)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Validate other parameters.
|
||||
if (!ppvoid)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Set the output pointer to NULL.
|
||||
*ppvoid = NULL;
|
||||
// Check the interface identifier. memcmp() returns 0 if they are equal.
|
||||
if (memcmp(riid, &IID_IUnknown, sizeof(IID)) && memcmp(riid, &IID_IAudioSessionNotification, sizeof(IID)))
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
// The interface is supported. Increment the reference count and return.
|
||||
this->lpVtbl->AddRef(this);
|
||||
*ppvoid = this;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE IAudioSessionEventsAddRef(IAudioSessionEvents* this)
|
||||
{
|
||||
// Cast the standard interface to my interface to allow access to cRef
|
||||
myIAudioSessionEvents* castInterface = (myIAudioSessionEvents*)this;
|
||||
|
||||
return InterlockedIncrement(&castInterface->cRef);
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE IAudioSessionEventsRelease(IAudioSessionEvents* this)
|
||||
{
|
||||
// Cast the standard interface to my interface to allow access to cRef
|
||||
myIAudioSessionEvents* castInterface = (myIAudioSessionEvents*)this;
|
||||
|
||||
ULONG cRef = InterlockedDecrement(&castInterface->cRef);
|
||||
|
||||
if (cRef == 0)
|
||||
{
|
||||
free(castInterface->lpVtbl);
|
||||
free(castInterface);
|
||||
//printf("\nAudio session notification memory freed");
|
||||
}
|
||||
|
||||
//printf("\nNotification release, ref count : %ld\n", cRef);
|
||||
return cRef;
|
||||
|
||||
}
|
||||
|
||||
HRESULT IAudioSessionEventsOnChannelVolumeChanged(IAudioSessionEvents* this, DWORD ChannelCount, float* NewChannelVolumeArray, DWORD ChangedChannel, LPCGUID EventContext)
|
||||
{
|
||||
printf("\nChannel &ld volume changed to %f.3", ChangedChannel, NewChannelVolumeArray + ChangedChannel);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT IAudioSessionEventsOnDisplayNameChanged(IAudioSessionEvents* this, LPCWSTR NewDisplayName, LPCGUID EventContext)
|
||||
{
|
||||
printf("\nNew session display name: %ws", NewDisplayName);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT IAudioSessionEventsOnGroupingParamChanged(IAudioSessionEvents* this, LPCGUID NewGroupingParam, LPCGUID EventContext)
|
||||
{
|
||||
printf("\nNew grouping param");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT IAudioSessionEventsOnIconPathChanged(IAudioSessionEvents* this, LPCWSTR NewIconPath, LPCGUID EventContext)
|
||||
{
|
||||
printf("\nNew icon path");
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
||||
HRESULT IAudioSessionEventsOnSessionDisconnected(IAudioSessionEvents* this, AudioSessionDisconnectReason DisconnectReason)
|
||||
{
|
||||
printf("\nSession disconnect reason &d", (int) DisconnectReason);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT IAudioSessionEventsOnSimpleVolumeChanged(IAudioSessionEvents* this, float NewVolume, BOOL NewMute, LPCGUID EventContext)
|
||||
{
|
||||
printf("\nSession simple volume changed to %f. Session is ", NewVolume);
|
||||
if (NewMute) printf("muted");
|
||||
else printf("ummuted");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT IAudioSessionEventsOnStateChanged(IAudioSessionEvents* this, AudioSessionState NewState)
|
||||
{
|
||||
printf("\nSession state changed");
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef _IAUDIOSESSIONEVENTS_H_
|
||||
#define _IAUDIOSESSIONEVENTS_H_
|
||||
|
||||
#include <combaseapi.h>
|
||||
#include <audiopolicy.h>
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
|
||||
#ifndef __myIAudioSessionEvents_FWD_DEFINED__
|
||||
#define __myIAudioSessionEvents_FWD_DEFINED__
|
||||
typedef interface myIAudioSessionEvents myIAudioSessionEvents;
|
||||
|
||||
#endif /* __myIAudioSessionEvents_FWD_DEFINED__ */
|
||||
|
||||
HRESULT InitializeAudioSessionEvents(IAudioSessionEvents**);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE IAudioSessionEventsQueryInterface(IAudioSessionEvents*, REFIID, void**);
|
||||
ULONG STDMETHODCALLTYPE IAudioSessionEventsAddRef(IAudioSessionEvents*);
|
||||
ULONG STDMETHODCALLTYPE IAudioSessionEventsRelease(IAudioSessionEvents*);
|
||||
HRESULT IAudioSessionEventsOnChannelVolumeChanged(IAudioSessionEvents*, DWORD, float*,DWORD, LPCGUID);
|
||||
HRESULT IAudioSessionEventsOnDisplayNameChanged(IAudioSessionEvents*, LPCWSTR, LPCGUID);
|
||||
HRESULT IAudioSessionEventsOnGroupingParamChanged(IAudioSessionEvents*, LPCGUID, LPCGUID);
|
||||
HRESULT IAudioSessionEventsOnIconPathChanged(IAudioSessionEvents*, LPCWSTR, LPCGUID);
|
||||
HRESULT IAudioSessionEventsOnSessionDisconnected(IAudioSessionEvents*, AudioSessionDisconnectReason);
|
||||
HRESULT IAudioSessionEventsOnSimpleVolumeChanged(IAudioSessionEvents*, float, BOOL, LPCGUID);
|
||||
HRESULT IAudioSessionEventsOnStateChanged(IAudioSessionEvents*, AudioSessionState);
|
||||
|
||||
|
||||
|
||||
interface myIAudioSessionEvents
|
||||
{
|
||||
CONST_VTBL struct IAudioSessionEventsVtbl* lpVtbl;
|
||||
ULONG cRef;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,169 @@
|
|||
#include "IAudioSessionNotification.h"
|
||||
|
||||
HRESULT InitializeAudioSessionNotification(IAudioSessionNotification** this, IAudioSessionControl *** pppAudioSessionControlInterfaces, int* pNumberSessionControls)
|
||||
{
|
||||
// Initializes the IAudioSessionNotification struct, this involves creating it, allocating memory, setting initial vaules and assigning the functions to be used
|
||||
//Allocate memory for the vtable
|
||||
IAudioSessionNotificationVtbl* vtbl = malloc(sizeof(IAudioSessionNotificationVtbl));
|
||||
|
||||
if (!vtbl)
|
||||
{
|
||||
// If the vtable memory cannot be assigned
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// Asign all the functions
|
||||
vtbl->AddRef = (*IAudioSessionNotificationAddRef);
|
||||
vtbl->OnSessionCreated = (*IAudioSessionNotificationOnSessionCreated);
|
||||
vtbl->QueryInterface = (*IAudioSessionNotificationQueryInterface);
|
||||
vtbl->Release = (*IAudioSessionNotificationRelease);
|
||||
|
||||
//Assign memory for the notifications struct. Cast the pointer returned from malloc to the correct type
|
||||
myIAudioSessionNotification * AudioSessionNotification;
|
||||
AudioSessionNotification = (myIAudioSessionNotification*) malloc(sizeof(myIAudioSessionNotification));
|
||||
if (!AudioSessionNotification)
|
||||
{
|
||||
// If the struct memory cannot be assigned free the memory previously assigned to the vtable and return
|
||||
free(vtbl);
|
||||
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// Add the virtual table to the strut
|
||||
AudioSessionNotification->lpVtbl = vtbl;
|
||||
AudioSessionNotification->cRef = 0;
|
||||
// pppAudioSessionControlInterfaces is a pointer to an array of control interface pointers
|
||||
AudioSessionNotification->pppAudioSessionControlInterfaces = pppAudioSessionControlInterfaces;
|
||||
AudioSessionNotification->pNumberAudioSessionControls = pNumberSessionControls;
|
||||
|
||||
// Update the pointer address passed into the function
|
||||
*this = (IAudioSessionNotification*) AudioSessionNotification;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE IAudioSessionNotificationQueryInterface(IAudioSessionNotification* this, REFIID riid, void** ppvoid)
|
||||
{
|
||||
//printf("\nQuery interface audio session notification\n");
|
||||
// Validate the object pointer.
|
||||
if (!this)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Validate other parameters.
|
||||
if (!ppvoid)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
// Set the output pointer to NULL.
|
||||
*ppvoid = NULL;
|
||||
// Check the interface identifier. memcmp() returns 0 if they are equal.
|
||||
if (memcmp(riid, &IID_IUnknown, sizeof(IID)) && memcmp(riid, &IID_IAudioSessionNotification, sizeof(IID)))
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
// The interface is supported. Increment the reference count and return.
|
||||
this->lpVtbl->AddRef(this);
|
||||
*ppvoid = this;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE IAudioSessionNotificationRelease(IAudioSessionNotification* this)
|
||||
{
|
||||
// Cast the standard interface to my interface to allow access to cRef
|
||||
myIAudioSessionNotification* castInterface = (myIAudioSessionNotification*) this;
|
||||
|
||||
ULONG cRef = InterlockedDecrement(&castInterface->cRef);
|
||||
|
||||
if (cRef == 0)
|
||||
{
|
||||
free(castInterface->lpVtbl);
|
||||
free(castInterface);
|
||||
//printf("\nAudio session notification memory freed");
|
||||
}
|
||||
|
||||
//printf("\nNotification release, ref count : %ld\n", cRef);
|
||||
return cRef;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE IAudioSessionNotificationAddRef(IAudioSessionNotification* this)
|
||||
{
|
||||
// Cast the standard interface to my interface to allow access to cRef
|
||||
myIAudioSessionNotification* castInterface = (myIAudioSessionNotification*)this;
|
||||
return InterlockedIncrement(&castInterface->cRef);
|
||||
}
|
||||
|
||||
HRESULT IAudioSessionNotificationOnSessionCreated(IAudioSessionNotification* this, IAudioSessionControl* pNewSession)
|
||||
{
|
||||
printf("\nNew session created");
|
||||
|
||||
// Simpler version with fixed size array of pointers declared in the main thread and put onto the stack.
|
||||
myIAudioSessionNotification* castInterface = (myIAudioSessionNotification*)this;
|
||||
int numberInterfaces = *(castInterface->pNumberAudioSessionControls);
|
||||
IAudioSessionControl ** audioSessionControlArray = castInterface->pppAudioSessionControlInterfaces + numberInterfaces;
|
||||
*audioSessionControlArray = pNewSession;
|
||||
*(castInterface->pNumberAudioSessionControls) = numberInterfaces + 1;
|
||||
return S_OK;
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* This is using realloc and malloc to dynamically change the size of the array of pointers to interfaces.
|
||||
* It doesn't work, I don't know why at this point.
|
||||
*
|
||||
// Add the new session to the array of IAudioSessionControl interfaces
|
||||
// A pointer to pointer to the array is stored in the interface, along with a pointer to the number of current interfaces
|
||||
// Cast IAudioSessionNotification to my implementation to access those variables
|
||||
myIAudioSessionNotification* pCastInterface = (myIAudioSessionNotification*)this;
|
||||
// ppCurrentInterfacesAddress is a pointer to the array of interface pointers
|
||||
IAudioSessionControl ** ppCurrentInterfacesAddress = *(pCastInterface->pppAudioSessionControlInterfaces);
|
||||
// The number of currently stored IAudioSessionControl interfaces
|
||||
int numberOfInterfaces = *pCastInterface->pNumberAudioSessionControls;
|
||||
|
||||
if (numberOfInterfaces)
|
||||
{
|
||||
printf("");
|
||||
}
|
||||
|
||||
// This is a pointer to the first element of the array of pointers to session control objects
|
||||
IAudioSessionControl** pNewArray = NULL;
|
||||
|
||||
// Realloc memory for the new pointer
|
||||
if (numberOfInterfaces)
|
||||
{
|
||||
pNewArray = (IAudioSessionControl**)realloc(ppCurrentInterfacesAddress, sizeof(IAudioSessionControl*) * (numberOfInterfaces + 1));
|
||||
}
|
||||
|
||||
if (!pNewArray)
|
||||
{
|
||||
// Realloc has failed, have to use malloc and memcpy
|
||||
pNewArray = (IAudioSessionControl **) malloc(sizeof(IAudioSessionControl*) * (numberOfInterfaces + 1));
|
||||
|
||||
if (!pNewArray)
|
||||
{
|
||||
printf("\nNot able to allocate new memory for array of control interfaces.");
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// Copy the contents of the array (pointers to control interfaces) to the new memory location
|
||||
memcpy(pNewArray, ppCurrentInterfacesAddress, sizeof(IAudioSessionControl*) * numberOfInterfaces);
|
||||
}
|
||||
|
||||
// At this point the memory has been allocated through realloc or malloc and the last pointer needs to be added to the array at the final location
|
||||
*(pNewArray + numberOfInterfaces) = pNewSession;
|
||||
|
||||
// Send the pointer to the new array back up the chain so it is seen by the main program thread
|
||||
*(pCastInterface->pppAudioSessionControlInterfaces) = pNewArray;
|
||||
|
||||
// Increment the number of interfaces and send it back up the chain ready for the next one.
|
||||
*(pCastInterface->pNumberAudioSessionControls) = numberOfInterfaces + 1;
|
||||
|
||||
// The new IAudioSessionControl interface should now have been appended to the array
|
||||
|
||||
return S_OK;
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef _IAUDIOSESSIONNOTIFICATION_H_
|
||||
#define _IAUDIOSESSIONNOTIFICATION_H_
|
||||
|
||||
#include <combaseapi.h>
|
||||
#include <audiopolicy.h>
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
|
||||
#ifndef __myIAudioSessionNotification_FWD_DEFINED__
|
||||
#define __myIAudioSessionNotification_FWD_DEFINED__
|
||||
typedef interface myIAudioSessionNotification myIAudioSessionNotification;
|
||||
|
||||
#endif /* __myIAudioSessionNotification_FWD_DEFINED__ */
|
||||
|
||||
HRESULT STDMETHODCALLTYPE IAudioSessionNotificationQueryInterface(IAudioSessionNotification*, REFIID, void**);
|
||||
ULONG STDMETHODCALLTYPE IAudioSessionNotificationAddRef(IAudioSessionNotification*);
|
||||
ULONG STDMETHODCALLTYPE IAudioSessionNotificationRelease(IAudioSessionNotification*);
|
||||
HRESULT IAudioSessionNotificationOnSessionCreated(IAudioSessionNotification*, IAudioSessionControl*);
|
||||
|
||||
//HRESULT InitializeAudioSessionNotification(IAudioSessionNotification**, IAudioSessionControl***, int*);
|
||||
HRESULT InitializeAudioSessionNotification(IAudioSessionNotification**, IAudioSessionControl***, int*);
|
||||
|
||||
interface myIAudioSessionNotification
|
||||
{
|
||||
CONST_VTBL struct IAudioSessionNotificationVtbl* lpVtbl;
|
||||
ULONG cRef;
|
||||
const IAudioSessionControl *** pppAudioSessionControlInterfaces;
|
||||
int * pNumberAudioSessionControls;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,55 @@
|
|||
#include "IUknownInterface.h"
|
||||
|
||||
|
||||
class CSessionNotifications : public IAudioSessionNotification
|
||||
{
|
||||
private:
|
||||
LONG m_cRefAll;
|
||||
HWND m_hwndMain;
|
||||
~CSessionManager() {};
|
||||
public:
|
||||
CSessionManager(HWND hWnd) :
|
||||
m_cRefAll(1),
|
||||
m_hwndMain(hWnd)
|
||||
{}
|
||||
// IUnknown
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv)
|
||||
{
|
||||
if (IID_IUnknown == riid)
|
||||
{
|
||||
AddRef();
|
||||
*ppvInterface = (IUnknown*)this;
|
||||
}
|
||||
else if (__uuidof(IAudioSessionNotification) == riid)
|
||||
{
|
||||
AddRef();
|
||||
*ppvInterface = (IAudioSessionNotification*)this;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppvInterface = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_cRefAll);
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE Release)()
|
||||
{
|
||||
ULONG ulRef = InterlockedDecrement(&m_cRefAll);
|
||||
if (0 == ulRef)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
return ulRef;
|
||||
}
|
||||
HRESULT OnSessionCreated(IAudioSessionControl* pNewSession)
|
||||
{
|
||||
if (pNewSession)
|
||||
{
|
||||
PostMessage(m_hwndMain, WM_SESSION_CREATED, 0, 0);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
#pragma once
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.6.33801.468
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WASAPI Notification Interfaces", "WASAPI Notification Interfaces.vcxproj", "{46D8D311-8E84-468E-B7EA-7699443913BA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{46D8D311-8E84-468E-B7EA-7699443913BA}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{46D8D311-8E84-468E-B7EA-7699443913BA}.Debug|x64.Build.0 = Debug|x64
|
||||
{46D8D311-8E84-468E-B7EA-7699443913BA}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{46D8D311-8E84-468E-B7EA-7699443913BA}.Debug|x86.Build.0 = Debug|Win32
|
||||
{46D8D311-8E84-468E-B7EA-7699443913BA}.Release|x64.ActiveCfg = Release|x64
|
||||
{46D8D311-8E84-468E-B7EA-7699443913BA}.Release|x64.Build.0 = Release|x64
|
||||
{46D8D311-8E84-468E-B7EA-7699443913BA}.Release|x86.ActiveCfg = Release|Win32
|
||||
{46D8D311-8E84-468E-B7EA-7699443913BA}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F3927660-367F-4C60-8E0E-964E87EF9716}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,140 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{46d8d311-8e84-468e-b7ea-7699443913ba}</ProjectGuid>
|
||||
<RootNamespace>WASAPINotificationInterfaces</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="IAudioSessionNotification.c" />
|
||||
<ClCompile Include="main.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="IAudioSessionNotification.h" />
|
||||
<ClInclude Include="CLSIDs_and_IIDs.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IAudioSessionNotification.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="CLSIDs_and_IIDs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IAudioSessionNotification.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ShowAllFiles>false</ShowAllFiles>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -0,0 +1,196 @@
|
|||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
#include "CLSIDs_and_IIDs.h"
|
||||
#include <combaseapi.h>
|
||||
#include <mmdeviceapi.h>
|
||||
#include <audiopolicy.h>
|
||||
#include"IAudioSessionNotification.h"
|
||||
|
||||
void printLoadingTicker( void );
|
||||
// This expects HRESULT from the function to be called result
|
||||
//#define checkHRESULT(func) if((func) != S_OK) printf("\nError on line %d of %s. Result value is %lx.\n", __LINE__, __FILE__, result);
|
||||
#define checkHRESULT if(result != S_OK) printf("\nError on line %d of %s. Result value is %lx.\n", __LINE__ - 1, __FILE__, result);
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Compiled %s", __TIME__);
|
||||
printf("\nStarting");
|
||||
|
||||
HRESULT result = 1;
|
||||
result = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
//result = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
checkHRESULT;
|
||||
// Have a look at this at a later date
|
||||
//checkHRESULT(CoInitializeEx(NULL, COINIT_MULTITHREADED));
|
||||
|
||||
IAudioSessionControl* AudioSessionControls[10];
|
||||
// I can't seem to get this to work dynamically assigning the memory
|
||||
//IAudioSessionControl** AudioSessionControls;
|
||||
int numberSessionControls = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
IMMDeviceEnumerator* myIMMDeviceEnumerator = NULL;
|
||||
result = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &IID_IMMDeviceEnumerator, &myIMMDeviceEnumerator);
|
||||
checkHRESULT;
|
||||
|
||||
IMMDevice* myIMMDevice;
|
||||
myIMMDeviceEnumerator->lpVtbl->GetDefaultAudioEndpoint(myIMMDeviceEnumerator, eRender, eMultimedia, &myIMMDevice);
|
||||
checkHRESULT;
|
||||
|
||||
|
||||
IAudioSessionManager2* myAudioSessionManager2 = NULL;
|
||||
result = myIMMDevice->lpVtbl->Activate(myIMMDevice, &IID_IAudioSessionManager2, CLSCTX_ALL, NULL, &myAudioSessionManager2);
|
||||
checkHRESULT;
|
||||
|
||||
IAudioSessionEnumerator* myAudioSessionEnumerator;
|
||||
result = myAudioSessionManager2->lpVtbl->GetSessionEnumerator(myAudioSessionManager2, &myAudioSessionEnumerator);
|
||||
checkHRESULT;
|
||||
|
||||
int sessions;
|
||||
result = myAudioSessionEnumerator->lpVtbl->GetCount(myAudioSessionEnumerator, &sessions);
|
||||
checkHRESULT;
|
||||
|
||||
IAudioSessionNotification* myAudioSessionNotification;
|
||||
result = InitializeAudioSessionNotification(&myAudioSessionNotification, &AudioSessionControls, &numberSessionControls);
|
||||
checkHRESULT;
|
||||
|
||||
result = myAudioSessionManager2->lpVtbl->RegisterSessionNotification(myAudioSessionManager2, myAudioSessionNotification);
|
||||
checkHRESULT;
|
||||
|
||||
int i = 0;
|
||||
int newSessionCount = 0;
|
||||
while (1)
|
||||
{
|
||||
Sleep(50);
|
||||
//printLoadingTicker();
|
||||
i++;
|
||||
if (i > 20000)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (newSessionCount != numberSessionControls)
|
||||
{
|
||||
printf("\nNew Session control added");
|
||||
|
||||
newSessionCount = numberSessionControls;
|
||||
|
||||
for (int ii = 0; ii < numberSessionControls; ii++)
|
||||
{
|
||||
|
||||
IAudioSessionControl * ActiveSessionControl = *(AudioSessionControls + ii);
|
||||
LPWSTR iconPath;
|
||||
result = ActiveSessionControl->lpVtbl->GetIconPath(ActiveSessionControl, &iconPath);
|
||||
printf("\nSession iconPath = %ls", iconPath);
|
||||
|
||||
IAudioSessionControl2* myAudioSessionControl2;
|
||||
result = ActiveSessionControl->lpVtbl->QueryInterface(ActiveSessionControl, &IID_IAudioSessionControl2, &myAudioSessionControl2);
|
||||
checkHRESULT;
|
||||
DWORD processID = 0;
|
||||
result = myAudioSessionControl2->lpVtbl->GetProcessId(myAudioSessionControl2, &processID);
|
||||
checkHRESULT;
|
||||
printf("Process ID of control instance %d is %d", ii, processID);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// The session manager notification unregister function also calls release on the audio session notification interface
|
||||
result = myAudioSessionManager2->lpVtbl->UnregisterSessionNotification(myAudioSessionManager2, myAudioSessionNotification);
|
||||
checkHRESULT;
|
||||
|
||||
myAudioSessionManager2->lpVtbl->Release(myAudioSessionManager2);
|
||||
myAudioSessionEnumerator->lpVtbl->Release(myAudioSessionEnumerator);
|
||||
myIMMDevice->lpVtbl->Release(myIMMDevice);
|
||||
//printf("\rNext \n");
|
||||
}
|
||||
|
||||
printf("\nFinished");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
void printLoadingTicker(void)
|
||||
{
|
||||
static count = 0;
|
||||
|
||||
char loadChar = ' ';
|
||||
switch (count % 8)
|
||||
{
|
||||
case(0):
|
||||
loadChar = '|';
|
||||
break;
|
||||
case(1):
|
||||
loadChar = '/';
|
||||
break;
|
||||
case(2):
|
||||
loadChar = '-';
|
||||
break;
|
||||
case(3):
|
||||
loadChar = '\\';
|
||||
break;
|
||||
case(4):
|
||||
loadChar = '|';
|
||||
break;
|
||||
case(5):
|
||||
loadChar = '/';
|
||||
break;
|
||||
case(6):
|
||||
loadChar = '-';
|
||||
break;
|
||||
case(7):
|
||||
loadChar = '\\';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Checking for new sessions [%c]\r", loadChar);
|
||||
count++;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
HRESULT checkSessions(IAudioSessionManager2* myAudioSessionManager2)
|
||||
{
|
||||
static int sessionCount = 0;
|
||||
// Gets a new enumerator object with all the sessions
|
||||
IAudioSessionEnumerator* myAudioSessionEnumerator;
|
||||
HRESULT result = myAudioSessionManager2->lpVtbl->GetSessionEnumerator(myAudioSessionManager2, &myAudioSessionEnumerator);
|
||||
// Checks how many sessions there are now
|
||||
int newSessionCount = -1;
|
||||
result = myAudioSessionEnumerator->lpVtbl->GetCount(myAudioSessionEnumerator, &newSessionCount);
|
||||
|
||||
if (newSessionCount != sessionCount)
|
||||
{
|
||||
sessionCount = newSessionCount;
|
||||
result = getNewSessions(sessionCount, &myAudioSessionEnumerator);
|
||||
}
|
||||
|
||||
printLoadingTicker();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT getNewSessions(int numberOfSessions, IAudioSessionEnumerator* myAudioSessionEnumerator)
|
||||
{
|
||||
for (int i = 0; i < numberOfSessions; i++)
|
||||
{
|
||||
IAudioSessionControl* myAudioSessionControl;
|
||||
HRESULT result = myAudioSessionEnumerator->lpVtbl->GetSession(myAudioSessionEnumerator, i, &myAudioSessionControl);
|
||||
IAudioSessionControl2* myAudioSessionControl2;
|
||||
result = myAudioSessionControl->lpVtbl->QueryInterface(myAudioSessionControl, &IID_IAudioSessionControl2, CLSCTX_ALL, &myAudioSessionControl2);
|
||||
|
||||
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
*/
|
Loading…
Reference in New Issue