@@ -694,20 +694,20 @@ ASIO2WASAPI::ASIO2WASAPI (LPUNKNOWN pUnk, HRESULT *phr)
694694 : CUnknown(" ASIO2WASAPI" , pUnk, phr)
695695{
696696 clearState ();
697- readFromRegistry ();
697+ readFromRegistry ();
698698}
699699
700700ASIO2WASAPI::~ASIO2WASAPI ()
701701{
702- shutdown ();
702+ shutdown ();
703703}
704704
705705void ASIO2WASAPI::shutdown ()
706706{
707707 IMMDeviceEnumerator* pEnumerator = NULL ;
708708 HRESULT hr = S_OK;
709709
710- stop ();
710+ // stop(); rdundant disposeuffers calls stop()
711711 disposeBuffers ();
712712
713713 HANDLE hEvent = CreateEvent (NULL , FALSE , FALSE , NULL );
@@ -732,7 +732,12 @@ void ASIO2WASAPI::shutdown()
732732 delete (pNotificationClient);
733733 pNotificationClient = NULL ;
734734 }
735-
735+
736+ if (eventDrivenEvent)
737+ {
738+ CloseHandle (eventDrivenEvent);
739+ eventDrivenEvent = NULL ;
740+ }
736741}
737742
738743void ASIO2WASAPI::initInputFields (IMMDevice* pDevice, ASIO2WASAPI* pDriver, const HWND hwndDlg)
@@ -1308,15 +1313,15 @@ void ASIO2WASAPI::PlayThreadProcShared(LPVOID pThis)
13081313 BYTE* pData = NULL ;
13091314
13101315 hr = CoInitialize (NULL );
1311- RETURN_ON_ERROR (hr)
1312-
1313- // Create an event handle and register it for
1314- // buffer-event notifications.
1315- HANDLE hEvent = CreateEvent (NULL , FALSE , FALSE , NULL );
1316- CHandleCloser cl (hEvent );
1317-
1318- hr = pAudioClient-> SetEventHandle (hEvent);
1319- RETURN_ON_ERROR (hr)
1316+ RETURN_ON_ERROR (hr)
1317+
1318+ 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.
1319+ {
1320+ pDriver-> eventDrivenEvent = CreateEvent (NULL , FALSE , FALSE , NULL );
1321+ hr = pAudioClient-> SetEventHandle (pDriver-> eventDrivenEvent );
1322+ RETURN_ON_ERROR (hr)
1323+ }
1324+ if (pDriver-> eventDrivenEvent ) ResetEvent (pDriver-> eventDrivenEvent ); // make sure event is not signaled AudioClient start is called
13201325
13211326 hr = pAudioClient->GetService (
13221327 IID_IAudioRenderClient,
@@ -1334,7 +1339,9 @@ void ASIO2WASAPI::PlayThreadProcShared(LPVOID pThis)
13341339 // Pre-load the first buffer with data
13351340
13361341 UINT32 bufferFrameCount;
1342+ UINT32 numFramesPadding;
13371343 hr = pAudioClient->GetBufferSize (&bufferFrameCount);
1344+ hr = pAudioClient->GetCurrentPadding (&numFramesPadding);
13381345 RETURN_ON_ERROR (hr)
13391346
13401347 UINT32 startFrames;
@@ -1343,6 +1350,8 @@ void ASIO2WASAPI::PlayThreadProcShared(LPVOID pThis)
13431350 else
13441351 startFrames = pDriver->m_bufferSize ;
13451352
1353+ if (startFrames > (bufferFrameCount - numFramesPadding)) startFrames = bufferFrameCount - numFramesPadding;
1354+
13461355 hr = pRenderClient->GetBuffer (startFrames, &pData);
13471356 RETURN_ON_ERROR (hr)
13481357 // memset(pData, 0, bufferFrameCount * pDriver->m_waveFormat.Format.nBlockAlign);
@@ -1361,12 +1370,11 @@ void ASIO2WASAPI::PlayThreadProcShared(LPVOID pThis)
13611370 // char convTxt[11] = { 0 };
13621371
13631372 DWORD retval = 0 ;
1364- HANDLE events[2 ] = { pDriver->m_hStopPlayThreadEvent , hEvent };
1373+ HANDLE events[2 ] = { pDriver->m_hStopPlayThreadEvent , pDriver-> eventDrivenEvent };
13651374 while ((retval = WaitForMultipleObjects (2 , events, FALSE , INFINITE)) == (WAIT_OBJECT_0 + 1 ))
13661375 {// the hEvent is signalled and m_hStopPlayThreadEvent is not
1367- // Grab the next empty buffer from the audio device.
1368-
1369- UINT32 numFramesPadding;
1376+ // Grab the next empty buffer from the audio device.
1377+
13701378 hr = pAudioClient->GetCurrentPadding (&numFramesPadding);
13711379 if (pDriver->m_bufferSize > (int )(bufferFrameCount - numFramesPadding))
13721380 {
@@ -1422,13 +1430,13 @@ void ASIO2WASAPI::PlayThreadProc(LPVOID pThis)
14221430 hr = CoInitialize (NULL );
14231431 RETURN_ON_ERROR (hr)
14241432
1425- // Create an event handle and register it for
1426- // buffer-event notifications.
1427- HANDLE hEvent = CreateEvent (NULL , FALSE , FALSE , NULL );
1428- CHandleCloser cl (hEvent );
1429-
1430- hr = pAudioClient-> SetEventHandle (hEvent);
1431- RETURN_ON_ERROR (hr)
1433+ 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.
1434+ {
1435+ pDriver-> eventDrivenEvent = CreateEvent (NULL , FALSE , FALSE , NULL );
1436+ hr = pAudioClient-> SetEventHandle (pDriver-> eventDrivenEvent );
1437+ RETURN_ON_ERROR (hr)
1438+ }
1439+ if (pDriver-> eventDrivenEvent ) ResetEvent (pDriver-> eventDrivenEvent ); // make sure event is not signaled AudioClient start is called
14321440
14331441 hr = pAudioClient->GetService (
14341442 IID_IAudioRenderClient,
@@ -1472,7 +1480,7 @@ void ASIO2WASAPI::PlayThreadProc(LPVOID pThis)
14721480 // char convTxt[11] = { 0 };
14731481
14741482 DWORD retval = 0 ;
1475- HANDLE events[2 ] = {pDriver->m_hStopPlayThreadEvent , hEvent };
1483+ HANDLE events[2 ] = {pDriver->m_hStopPlayThreadEvent , pDriver-> eventDrivenEvent };
14761484 while ((retval = WaitForMultipleObjects (2 ,events,FALSE , INFINITE)) == (WAIT_OBJECT_0 + 1 ))
14771485 {// the hEvent is signalled and m_hStopPlayThreadEvent is not
14781486 // Grab the next empty buffer from the audio device.
@@ -1634,6 +1642,7 @@ ASIOBool ASIO2WASAPI::init(void* sysRef)
16341642 m_hAppWindowHandle = (HWND) sysRef;
16351643 m_hControlPanelHandle = 0 ;
16361644 pNotificationClient = NULL ;
1645+ eventDrivenEvent = NULL ;
16371646
16381647 HRESULT hr=S_OK;
16391648 IMMDeviceEnumerator *pEnumerator = NULL ;
@@ -1696,25 +1705,21 @@ ASIOBool ASIO2WASAPI::init(void* sysRef)
16961705 BOOL rc = FindStreamFormat (m_pDevice, m_nChannels, m_nSampleRate, m_nBufferSize, m_wasapiExclusiveMode, m_wasapiEnableResampling, m_wasapiLowLatencySharedMode, &m_waveFormat, &m_pAudioClient);
16971706 if (!rc)
16981707 {
1699- if (!m_wasapiExclusiveMode && !m_wasapiEnableResampling)
1708+ IAudioClient* pAudioClient = NULL ;
1709+ hr = m_pDevice->Activate (IID_IAudioClient, CLSCTX_ALL, NULL , (void **)&pAudioClient);
1710+ CReleaser r (pAudioClient);
1711+
1712+ WAVEFORMATEX* devFormat;
1713+ hr = pAudioClient->GetMixFormat (&devFormat);
1714+ if (SUCCEEDED (hr))
17001715 {
1701- IAudioClient* pAudioClient = NULL ;
1702- hr = m_pDevice->Activate (
1703- IID_IAudioClient, CLSCTX_ALL,
1704- NULL , (void **)&pAudioClient);
1705- CReleaser r (pAudioClient);
1706-
1707- WAVEFORMATEX* devFormat;
1708- hr = pAudioClient->GetMixFormat (&devFormat);
1709- if (SUCCEEDED (hr))
1710- {
1711- m_nChannels = devFormat->nChannels ;
1712- m_nSampleRate = devFormat->nSamplesPerSec ;
1713- CoTaskMemFree (devFormat);
1714- }
1715- FindStreamFormat (m_pDevice, m_nChannels, m_nSampleRate, m_nBufferSize, m_wasapiExclusiveMode, m_wasapiEnableResampling, m_wasapiLowLatencySharedMode, &m_waveFormat, &m_pAudioClient);
1716- }
1717- else
1716+ m_nChannels = !m_wasapiExclusiveMode ? devFormat->nChannels : 2 ;
1717+ m_nSampleRate = devFormat->nSamplesPerSec ;
1718+ CoTaskMemFree (devFormat);
1719+ rc = FindStreamFormat (m_pDevice, m_nChannels, m_nSampleRate, m_nBufferSize, m_wasapiExclusiveMode, m_wasapiEnableResampling, m_wasapiLowLatencySharedMode, &m_waveFormat, &m_pAudioClient);
1720+ }
1721+
1722+ if (!rc)
17181723 {// go through all devices and try to find the one that works for 16/48K
17191724 SAFE_RELEASE (m_pDevice)
17201725 setMostReliableFormat ();
@@ -1815,23 +1820,25 @@ ASIOError ASIO2WASAPI::setSampleRate (ASIOSampleRate sampleRate)
18151820
18161821 ASIOError err = canSampleRate (sampleRate);
18171822 if (err != ASE_OK)
1818- return err;
1823+ return err;
18191824
1820- int nPrevSampleRate = m_nSampleRate;
1821- m_nSampleRate = (int )sampleRate;
1822- writeToRegistry ();
18231825 if (m_callbacks)
18241826 {// ask the host ro reset us
1827+ int nPrevSampleRate = m_nSampleRate;
1828+ m_nSampleRate = (int )sampleRate;
1829+ writeToRegistry ();
18251830 m_nSampleRate = nPrevSampleRate;
1826- m_callbacks->asioMessage (kAsioResetRequest ,0 , NULL ,NULL );
1831+ m_callbacks->asioMessage (kAsioResetRequest , 0 , NULL , NULL );
18271832 }
1828- else
1833+ else return ASE_NoClock;
1834+ /* 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.
18291835 {//reinitialize us with the new sample rate
18301836 HWND hAppWindowHandle = m_hAppWindowHandle;
18311837 shutdown();
18321838 readFromRegistry();
18331839 init(hAppWindowHandle);
18341840 }
1841+ */
18351842
18361843 return ASE_OK;
18371844}
0 commit comments