infos->buffers[0] = infos->buffers[1] = 0;\r
}\r
\r
+ // prepare for callbacks\r
+ stream_.sampleRate = sampleRate;\r
+ stream_.device[mode] = device;\r
+ if ( stream_.mode == OUTPUT && mode == INPUT )\r
+ // We had already set up an output stream.\r
+ stream_.mode = DUPLEX;\r
+ else\r
+ stream_.mode = mode;\r
+\r
+ // store this class instance before registering callbacks, that are going to use it\r
+ asioCallbackInfo = &stream_.callbackInfo;\r
+ stream_.callbackInfo.object = (void *) this;\r
+\r
// Set up the ASIO callback structure and create the ASIO data buffers.\r
asioCallbacks.bufferSwitch = &bufferSwitch;\r
asioCallbacks.sampleRateDidChange = &sampleRateChanged;\r
asioCallbacks.asioMessage = &asioMessages;\r
asioCallbacks.bufferSwitchTimeInfo = NULL;\r
result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );\r
+ if ( result != ASE_OK ) {\r
+ // Standard method failed. This can happen with strict/misbehaving drivers that return valid buffer size ranges\r
+ // but only accept the preferred buffer size as parameter for ASIOCreateBuffers. eg. Creatives ASIO driver\r
+ // in that case, let's be naïve and try that instead\r
+ *bufferSize = preferSize;\r
+ stream_.bufferSize = *bufferSize;\r
+ result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );\r
+ }\r
+\r
if ( result != ASE_OK ) {\r
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers.";\r
errorText_ = errorStream_.str();\r
goto error;\r
}\r
buffersAllocated = true;\r
+ stream_.state = STREAM_STOPPED;\r
\r
// Set flags for buffer conversion.\r
stream_.doConvertBuffer[mode] = false;\r
\r
bool makeBuffer = true;\r
bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );\r
- if ( mode == INPUT ) {\r
- if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {\r
- unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );\r
- if ( bufferBytes <= bytesOut ) makeBuffer = false;\r
- }\r
+ if ( stream_.mode == DUPLEX && stream_.deviceBuffer ) {\r
+ unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );\r
+ if ( bufferBytes <= bytesOut ) makeBuffer = false;\r
}\r
\r
if ( makeBuffer ) {\r
}\r
}\r
\r
- stream_.sampleRate = sampleRate;\r
- stream_.device[mode] = device;\r
- stream_.state = STREAM_STOPPED;\r
- asioCallbackInfo = &stream_.callbackInfo;\r
- stream_.callbackInfo.object = (void *) this;\r
- if ( stream_.mode == OUTPUT && mode == INPUT )\r
- // We had already set up an output stream.\r
- stream_.mode = DUPLEX;\r
- else\r
- stream_.mode = mode;\r
-\r
// Determine device latencies\r
result = ASIOGetLatencies( &inputLatency, &outputLatency );\r
if ( result != ASE_OK ) {\r