Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion UWPGlobalVolume/Volume.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Windows::Foundation::IAsyncOperation<bool>^ Volume::SetVolume(float volume)
});
}

Windows::Foundation::IAsyncOperation<float>^ Volume::GetVolume()
Windows::Foundation::IAsyncOperation<float>^ Volume::GetVolume()
{
return create_async([this]
{
Expand All @@ -39,5 +39,43 @@ Windows::Foundation::IAsyncOperation<float>^ Volume::GetVolume()
});
}

Windows::Foundation::IAsyncOperation<bool>^ Volume::SetMute(bool isMuted)
{
return create_async([this, isMuted]
{
if (m_volumeImpl == nullptr)
{
// Create a new WASAPI capture instance
m_volumeImpl = Make<VolumeImpl>();
}

return m_volumeImpl->SetMute(isMuted);
});
}

Windows::Foundation::IAsyncOperation<bool>^ Volume::GetMute()
{
return create_async([this]
{
if (m_volumeImpl == nullptr)
{
// Create a new WASAPI capture instance
m_volumeImpl = Make<VolumeImpl>();
}

return m_volumeImpl->GetMute();
});
}

void Volume::RegisterVolumeChangedNotify(VolumeChangedHandler^ volumeChangedAction)
{
if (m_volumeImpl == nullptr)
{
m_volumeImpl = Make<VolumeImpl>();
}

m_volumeImpl->VolumeChangedAction = volumeChangedAction;
}



3 changes: 3 additions & 0 deletions UWPGlobalVolume/Volume.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace UWPGlobalVolume
Volume();
Windows::Foundation::IAsyncOperation<bool>^ SetVolume(float volume);
Windows::Foundation::IAsyncOperation<float>^ GetVolume();
Windows::Foundation::IAsyncOperation<bool>^ SetMute(bool isMuted);
Windows::Foundation::IAsyncOperation<bool>^ GetMute();
void RegisterVolumeChangedNotify(VolumeChangedHandler^ volumeChangedAction);

private:
Microsoft::WRL::ComPtr<VolumeImpl> m_volumeImpl;
Expand Down
48 changes: 43 additions & 5 deletions UWPGlobalVolume/VolumeImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,25 @@ VolumeImpl::VolumeImpl()
{
m_event = CreateEvent(nullptr, false, false, nullptr);
// register for changes in Default audio device
m_token = MediaDevice::DefaultAudioRenderDeviceChanged += ref new Windows::Foundation::TypedEventHandler<Platform::Object ^, DefaultAudioRenderDeviceChangedEventArgs ^>(std::bind(&VolumeImpl::OnDefaultAudioCaptureDeviceChanged, this, _1, _2));
m_token = MediaDevice::DefaultAudioRenderDeviceChanged += ref new Windows::Foundation::TypedEventHandler<Platform::Object^, DefaultAudioRenderDeviceChangedEventArgs^>(std::bind(&VolumeImpl::OnDefaultAudioCaptureDeviceChanged, this, _1, _2));
}

VolumeImpl::~VolumeImpl()
{
UnregisterControlChangeNotify();
CloseHandle(m_event);
MediaDevice::DefaultAudioCaptureDeviceChanged -= m_token;
}

HRESULT VolumeImpl::InitializeVolumeInterface()
{
std::lock_guard<std::mutex> lock(m_mutex);

if (m_volumeInterface != nullptr)
{
return S_OK;
}

ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOp;
m_result = S_OK;
auto id = MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default);
Expand All @@ -41,7 +42,7 @@ HRESULT VolumeImpl::InitializeVolumeInterface()
return m_result;
}

void VolumeImpl::OnDefaultAudioCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs ^ args)
void VolumeImpl::OnDefaultAudioCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args)
{
// force next Set/GetVolume call to reinitialize the IAudioEndpointInterface
std::lock_guard<std::mutex> lock(m_mutex);
Expand Down Expand Up @@ -69,16 +70,46 @@ float VolumeImpl::GetVolume()
hr = m_volumeInterface->GetMasterVolumeLevelScalar(&volume);
}
return volume;
}

bool VolumeImpl::SetMute(bool isMuted)
{
HRESULT hr = InitializeVolumeInterface();
if (SUCCEEDED(hr) && m_volumeInterface != nullptr)
{
hr = m_volumeInterface->SetMute(isMuted, NULL);
}
return SUCCEEDED(hr);
}

bool VolumeImpl::GetMute()
{
BOOL isMuted = false;
HRESULT hr = InitializeVolumeInterface();
if (SUCCEEDED(hr) && m_volumeInterface != nullptr)
{
hr = m_volumeInterface->GetMute(&isMuted);
}
return isMuted;

}

void VolumeImpl::UnregisterControlChangeNotify()
{
HRESULT hr = InitializeVolumeInterface();
if (SUCCEEDED(hr) && m_volumeInterface != nullptr)
{
hr = m_volumeInterface->UnregisterControlChangeNotify(this);
}
}

//
// ActivateCompleted()
//
// Callback implementation of ActivateAudioInterfaceAsync function. This will be called on MTA thread
// when results of the activation are available.
//
HRESULT VolumeImpl::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *operation)
HRESULT VolumeImpl::ActivateCompleted(IActivateAudioInterfaceAsyncOperation* operation)
{
HRESULT hr = S_OK;
HRESULT hrActivateResult = S_OK;
Expand All @@ -102,10 +133,17 @@ HRESULT VolumeImpl::ActivateCompleted(IActivateAudioInterfaceAsyncOperation *ope
hr = E_NOINTERFACE;
goto exit;
}
m_volumeInterface->RegisterControlChangeNotify(this);

exit:
SetEvent(m_event);
m_result = hr;
// Need to return S_OK
return S_OK;
}

HRESULT VolumeImpl::OnNotify(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify)
{
this->VolumeChangedAction(pNotify->bMuted, pNotify->fMasterVolume);
return S_OK;
}
17 changes: 14 additions & 3 deletions UWPGlobalVolume/VolumeImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@

namespace UWPGlobalVolume
{
public delegate void VolumeChangedHandler(bool isMuted, float volume);

// Primary WASAPI Capture Class
class VolumeImpl :
public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::ClassicCom>, Microsoft::WRL::FtmBase, IActivateAudioInterfaceCompletionHandler >
public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::ClassicCom>, Microsoft::WRL::FtmBase, IActivateAudioInterfaceCompletionHandler, IAudioEndpointVolumeCallback >
{
public:
VolumeImpl();
~VolumeImpl();

bool SetVolume(float volume);
float GetVolume();
bool SetMute(bool isMuted);
bool GetMute();

VolumeChangedHandler^ VolumeChangedAction;

private:
std::mutex m_mutex;
Expand All @@ -26,10 +32,15 @@ namespace UWPGlobalVolume

HRESULT InitializeVolumeInterface();

void OnDefaultAudioCaptureDeviceChanged(Platform::Object^ sender, Windows::Media::Devices::DefaultAudioRenderDeviceChangedEventArgs ^ args);
void OnDefaultAudioCaptureDeviceChanged(Platform::Object^ sender, Windows::Media::Devices::DefaultAudioRenderDeviceChangedEventArgs^ args);

// IActivateAudioInterfaceCompletionHandler
STDMETHOD(ActivateCompleted)(IActivateAudioInterfaceAsyncOperation *operation);
STDMETHOD(ActivateCompleted)(IActivateAudioInterfaceAsyncOperation* operation);
Microsoft::WRL::ComPtr<IAudioEndpointVolume> m_volumeInterface;

// Inherited via IAudioEndpointVolumeCallback
STDMETHOD(OnNotify)(PAUDIO_VOLUME_NOTIFICATION_DATA pNotify);

void UnregisterControlChangeNotify();
};
}