diff options
| author | yedey <myco@gmx.net> | 2014-10-06 09:31:23 +0200 |
|---|---|---|
| committer | yedey <myco@gmx.net> | 2014-10-06 09:31:23 +0200 |
| commit | b9e6faacf4b46eae0c6f05ad02d560681de4edfd (patch) | |
| tree | 88a0375f75ae0529bb4dd8dcf0e17aba98dc1193 /RtAudio.cpp | |
| parent | 440272d68fa9b7ea9bd0ac73ba43f9fa3f693056 (diff) | |
ASIO fix for crash for early callbacks (initiated from ASIOCreateBuffers), ASIO fix for strict/misbehaving drivers
Diffstat (limited to 'RtAudio.cpp')
| -rw-r--r-- | RtAudio.cpp | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/RtAudio.cpp b/RtAudio.cpp index ffb1f76..6baddc9 100644 --- a/RtAudio.cpp +++ b/RtAudio.cpp @@ -3086,6 +3086,19 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne infos->buffers[0] = infos->buffers[1] = 0;
}
+ // prepare for callbacks
+ stream_.sampleRate = sampleRate;
+ stream_.device[mode] = device;
+ if ( stream_.mode == OUTPUT && mode == INPUT )
+ // We had already set up an output stream.
+ stream_.mode = DUPLEX;
+ else
+ stream_.mode = mode;
+
+ // store this class instance before registering callbacks, that are going to use it
+ asioCallbackInfo = &stream_.callbackInfo;
+ stream_.callbackInfo.object = (void *) this;
+
// Set up the ASIO callback structure and create the ASIO data buffers.
asioCallbacks.bufferSwitch = &bufferSwitch;
asioCallbacks.sampleRateDidChange = &sampleRateChanged;
@@ -3093,11 +3106,21 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne asioCallbacks.bufferSwitchTimeInfo = NULL;
result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );
if ( result != ASE_OK ) {
+ // Standard method failed. This can happen with strict/misbehaving drivers that return valid buffer size ranges
+ // but only accept the preferred buffer size as parameter for ASIOCreateBuffers. eg. Creatives ASIO driver
+ // in that case, let's be naïve and try that instead
+ *bufferSize = preferSize;
+ stream_.bufferSize = *bufferSize;
+ result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks );
+ }
+
+ if ( result != ASE_OK ) {
errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers.";
errorText_ = errorStream_.str();
goto error;
}
buffersAllocated = true;
+ stream_.state = STREAM_STOPPED;
// Set flags for buffer conversion.
stream_.doConvertBuffer[mode] = false;
@@ -3120,11 +3143,9 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne bool makeBuffer = true;
bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] );
- if ( mode == INPUT ) {
- if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) {
- unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
- if ( bufferBytes <= bytesOut ) makeBuffer = false;
- }
+ if ( stream_.mode == DUPLEX && stream_.deviceBuffer ) {
+ unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] );
+ if ( bufferBytes <= bytesOut ) makeBuffer = false;
}
if ( makeBuffer ) {
@@ -3138,17 +3159,6 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne }
}
- stream_.sampleRate = sampleRate;
- stream_.device[mode] = device;
- stream_.state = STREAM_STOPPED;
- asioCallbackInfo = &stream_.callbackInfo;
- stream_.callbackInfo.object = (void *) this;
- if ( stream_.mode == OUTPUT && mode == INPUT )
- // We had already set up an output stream.
- stream_.mode = DUPLEX;
- else
- stream_.mode = mode;
-
// Determine device latencies
result = ASIOGetLatencies( &inputLatency, &outputLatency );
if ( result != ASE_OK ) {
|
