Skip to content
Merged
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
105 changes: 56 additions & 49 deletions Source/Driver/ASIO2WASAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -694,20 +694,20 @@ ASIO2WASAPI::ASIO2WASAPI (LPUNKNOWN pUnk, HRESULT *phr)
: CUnknown("ASIO2WASAPI", pUnk, phr)
{
clearState();
readFromRegistry();
readFromRegistry();
}

ASIO2WASAPI::~ASIO2WASAPI ()
{
shutdown();
shutdown();
}

void ASIO2WASAPI::shutdown()
{
IMMDeviceEnumerator* pEnumerator = NULL;
HRESULT hr = S_OK;

stop();
//stop(); rdundant disposeuffers calls stop()
disposeBuffers();

HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
Expand All @@ -732,7 +732,12 @@ void ASIO2WASAPI::shutdown()
delete(pNotificationClient);
pNotificationClient = NULL;
}


if (eventDrivenEvent)
{
CloseHandle(eventDrivenEvent);
eventDrivenEvent = NULL;
}
}

void ASIO2WASAPI::initInputFields(IMMDevice* pDevice, ASIO2WASAPI* pDriver, const HWND hwndDlg)
Expand Down Expand Up @@ -1308,15 +1313,15 @@ void ASIO2WASAPI::PlayThreadProcShared(LPVOID pThis)
BYTE* pData = NULL;

hr = CoInitialize(NULL);
RETURN_ON_ERROR(hr)

// Create an event handle and register it for
// buffer-event notifications.
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
CHandleCloser cl(hEvent);

hr = pAudioClient->SetEventHandle(hEvent);
RETURN_ON_ERROR(hr)
RETURN_ON_ERROR(hr)
if (!pDriver->eventDrivenEvent)// In Cubase 5 multiple start/stop cycles can occur without releasing AudioClient. And in shared mode AudioClient->SetEventHandle fails the 2nd time. So private eventDrivenEvent added as a global event.
{
pDriver->eventDrivenEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hr = pAudioClient->SetEventHandle(pDriver->eventDrivenEvent);
RETURN_ON_ERROR(hr)
}
if (pDriver->eventDrivenEvent) ResetEvent(pDriver->eventDrivenEvent); //make sure event is not signaled AudioClient start is called

hr = pAudioClient->GetService(
IID_IAudioRenderClient,
Expand All @@ -1334,7 +1339,9 @@ void ASIO2WASAPI::PlayThreadProcShared(LPVOID pThis)
// Pre-load the first buffer with data

UINT32 bufferFrameCount;
UINT32 numFramesPadding;
hr = pAudioClient->GetBufferSize(&bufferFrameCount);
hr = pAudioClient->GetCurrentPadding(&numFramesPadding);
RETURN_ON_ERROR(hr)

UINT32 startFrames;
Expand All @@ -1343,6 +1350,8 @@ void ASIO2WASAPI::PlayThreadProcShared(LPVOID pThis)
else
startFrames = pDriver->m_bufferSize;

if (startFrames > (bufferFrameCount - numFramesPadding)) startFrames = bufferFrameCount - numFramesPadding;

hr = pRenderClient->GetBuffer(startFrames, &pData);
RETURN_ON_ERROR(hr)
//memset(pData, 0, bufferFrameCount * pDriver->m_waveFormat.Format.nBlockAlign);
Expand All @@ -1361,12 +1370,11 @@ void ASIO2WASAPI::PlayThreadProcShared(LPVOID pThis)
//char convTxt[11] = { 0 };

DWORD retval = 0;
HANDLE events[2] = { pDriver->m_hStopPlayThreadEvent, hEvent };
HANDLE events[2] = { pDriver->m_hStopPlayThreadEvent, pDriver->eventDrivenEvent };
while ((retval = WaitForMultipleObjects(2, events, FALSE, INFINITE)) == (WAIT_OBJECT_0 + 1))
{//the hEvent is signalled and m_hStopPlayThreadEvent is not
// Grab the next empty buffer from the audio device.

UINT32 numFramesPadding;
// Grab the next empty buffer from the audio device.

hr = pAudioClient->GetCurrentPadding(&numFramesPadding);
if (pDriver->m_bufferSize > (int)(bufferFrameCount - numFramesPadding))
{
Expand Down Expand Up @@ -1422,13 +1430,13 @@ void ASIO2WASAPI::PlayThreadProc(LPVOID pThis)
hr = CoInitialize(NULL);
RETURN_ON_ERROR(hr)

// Create an event handle and register it for
// buffer-event notifications.
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
CHandleCloser cl(hEvent);

hr = pAudioClient->SetEventHandle(hEvent);
RETURN_ON_ERROR(hr)
if (!pDriver->eventDrivenEvent) // In Cubase 5 multiple start/stop cycles can occur without releasing AudioClient. And in shared mode AudioClient->SetEventHandle fails the 2nd time. So private eventDrivenEvent added as a global event.
{
pDriver->eventDrivenEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hr = pAudioClient->SetEventHandle(pDriver->eventDrivenEvent);
RETURN_ON_ERROR(hr)
}
if (pDriver->eventDrivenEvent) ResetEvent(pDriver->eventDrivenEvent); //make sure event is not signaled AudioClient start is called

hr = pAudioClient->GetService(
IID_IAudioRenderClient,
Expand Down Expand Up @@ -1472,7 +1480,7 @@ void ASIO2WASAPI::PlayThreadProc(LPVOID pThis)
//char convTxt[11] = { 0 };

DWORD retval = 0;
HANDLE events[2] = {pDriver->m_hStopPlayThreadEvent, hEvent };
HANDLE events[2] = {pDriver->m_hStopPlayThreadEvent, pDriver->eventDrivenEvent };
while ((retval = WaitForMultipleObjects(2,events,FALSE, INFINITE)) == (WAIT_OBJECT_0 + 1))
{//the hEvent is signalled and m_hStopPlayThreadEvent is not
// Grab the next empty buffer from the audio device.
Expand Down Expand Up @@ -1634,6 +1642,7 @@ ASIOBool ASIO2WASAPI::init(void* sysRef)
m_hAppWindowHandle = (HWND) sysRef;
m_hControlPanelHandle = 0;
pNotificationClient = NULL;
eventDrivenEvent = NULL;

HRESULT hr=S_OK;
IMMDeviceEnumerator *pEnumerator = NULL;
Expand Down Expand Up @@ -1696,25 +1705,21 @@ ASIOBool ASIO2WASAPI::init(void* sysRef)
BOOL rc = FindStreamFormat(m_pDevice, m_nChannels, m_nSampleRate, m_nBufferSize, m_wasapiExclusiveMode, m_wasapiEnableResampling, m_wasapiLowLatencySharedMode, &m_waveFormat, &m_pAudioClient);
if (!rc)
{
if (!m_wasapiExclusiveMode && !m_wasapiEnableResampling)
IAudioClient* pAudioClient = NULL;
hr = m_pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&pAudioClient);
CReleaser r(pAudioClient);

WAVEFORMATEX* devFormat;
hr = pAudioClient->GetMixFormat(&devFormat);
if (SUCCEEDED(hr))
{
IAudioClient* pAudioClient = NULL;
hr = m_pDevice->Activate(
IID_IAudioClient, CLSCTX_ALL,
NULL, (void**)&pAudioClient);
CReleaser r(pAudioClient);

WAVEFORMATEX* devFormat;
hr = pAudioClient->GetMixFormat(&devFormat);
if (SUCCEEDED(hr))
{
m_nChannels = devFormat->nChannels;
m_nSampleRate = devFormat->nSamplesPerSec;
CoTaskMemFree(devFormat);
}
FindStreamFormat(m_pDevice, m_nChannels, m_nSampleRate, m_nBufferSize, m_wasapiExclusiveMode, m_wasapiEnableResampling, m_wasapiLowLatencySharedMode, &m_waveFormat, &m_pAudioClient);
}
else
m_nChannels = !m_wasapiExclusiveMode ? devFormat->nChannels : 2;
m_nSampleRate = devFormat->nSamplesPerSec;
CoTaskMemFree(devFormat);
rc = FindStreamFormat(m_pDevice, m_nChannels, m_nSampleRate, m_nBufferSize, m_wasapiExclusiveMode, m_wasapiEnableResampling, m_wasapiLowLatencySharedMode, &m_waveFormat, &m_pAudioClient);
}

if (!rc)
{//go through all devices and try to find the one that works for 16/48K
SAFE_RELEASE(m_pDevice)
setMostReliableFormat();
Expand Down Expand Up @@ -1815,23 +1820,25 @@ ASIOError ASIO2WASAPI::setSampleRate (ASIOSampleRate sampleRate)

ASIOError err = canSampleRate(sampleRate);
if (err != ASE_OK)
return err;
return err;

int nPrevSampleRate = m_nSampleRate;
m_nSampleRate = (int)sampleRate;
writeToRegistry();
if (m_callbacks)
{//ask the host ro reset us
int nPrevSampleRate = m_nSampleRate;
m_nSampleRate = (int)sampleRate;
writeToRegistry();
m_nSampleRate = nPrevSampleRate;
m_callbacks->asioMessage(kAsioResetRequest,0,NULL,NULL);
m_callbacks->asioMessage(kAsioResetRequest, 0, NULL, NULL);
}
else
else return ASE_NoClock;
/* In case of Cubase 5 getBufferSize has been called at this point and buffersize can change due to AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED which results in failed createBuffers thus no sound at all.
{//reinitialize us with the new sample rate
HWND hAppWindowHandle = m_hAppWindowHandle;
shutdown();
readFromRegistry();
init(hAppWindowHandle);
}
*/

return ASE_OK;
}
Expand Down
5 changes: 3 additions & 2 deletions Source/Driver/ASIO2WASAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ class ASIO2WASAPI : public IASIO, public CUnknown
void setUseDefaultDevice(bool value) { m_useDefaultDevice = value; };
private:
//for default device changed notification
CMMNotificationClient* pNotificationClient;
CMMNotificationClient* pNotificationClient = NULL;
HANDLE eventDrivenEvent = NULL;

static void PlayThreadProc(LPVOID pThis);
static void PlayThreadProcShared(LPVOID pThis);
Expand Down Expand Up @@ -178,7 +179,7 @@ class ASIO2WASAPI : public IASIO, public CUnknown
HWND m_hControlPanelHandle;

//WASAPI specific
bool m_useDefaultDevice;
bool m_useDefaultDevice = true;
AUDCLNT_SHAREMODE m_wasapiExclusiveMode = AUDCLNT_SHAREMODE_EXCLUSIVE;
BOOL m_wasapiEnableResampling = FALSE;
BOOL m_wasapiLowLatencySharedMode = FALSE;
Expand Down