1diff --git a/RtAudio.cpp b/RtAudio.cpp 2index 2ac2179..5fce9b2 100644 3--- a/RtAudio.cpp 4+++ b/RtAudio.cpp 5@@ -76,7 +76,7 @@ const unsigned int RtApi::SAMPLE_RATES[] = { 6 return s; 7 } 8 9-#elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__) 10+#elif defined(__LINUX_ALSA__) || defined(__UNIX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__) || defined(__HAIKU__) 11 // pthread API 12 #define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL) 13 #define MUTEX_DESTROY(A) pthread_mutex_destroy(A) 14@@ -110,8 +110,8 @@ void RtAudio :: getCompiledApi( std::vector<RtAudio::Api> &apis ) 15 #if defined(__LINUX_ALSA__) 16 apis.push_back( LINUX_ALSA ); 17 #endif 18-#if defined(__LINUX_PULSE__) 19- apis.push_back( LINUX_PULSE ); 20+#if defined(__UNIX_PULSE__) 21+ apis.push_back( UNIX_PULSE ); 22 #endif 23 #if defined(__LINUX_OSS__) 24 apis.push_back( LINUX_OSS ); 25@@ -147,8 +147,8 @@ void RtAudio :: openRtApi( RtAudio::Api api ) 26 if ( api == LINUX_ALSA ) 27 rtapi_ = new RtApiAlsa(); 28 #endif 29-#if defined(__LINUX_PULSE__) 30- if ( api == LINUX_PULSE ) 31+#if defined(__UNIX_PULSE__) 32+ if ( api == UNIX_PULSE ) 33 rtapi_ = new RtApiPulse(); 34 #endif 35 #if defined(__LINUX_OSS__) 36@@ -222,11 +222,12 @@ void RtAudio :: openStream( RtAudio::StreamParameters *outputParameters, 37 unsigned int *bufferFrames, 38 RtAudioCallback callback, void *userData, 39 RtAudio::StreamOptions *options, 40+ RtAudioBufferSizeCallback bufSizeCallback, 41 RtAudioErrorCallback errorCallback ) 42 { 43 return rtapi_->openStream( outputParameters, inputParameters, format, 44 sampleRate, bufferFrames, callback, 45- userData, options, errorCallback ); 46+ userData, options, bufSizeCallback, errorCallback ); 47 } 48 49 // *************************************************** // 50@@ -259,6 +260,7 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams, 51 unsigned int *bufferFrames, 52 RtAudioCallback callback, void *userData, 53 RtAudio::StreamOptions *options, 54+ RtAudioBufferSizeCallback bufSizeCallback, 55 RtAudioErrorCallback errorCallback ) 56 { 57 if ( stream_.state != STREAM_CLOSED ) { 58@@ -282,7 +284,7 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams, 59 return; 60 } 61 62- if ( oParams == NULL && iParams == NULL ) { 63+ if ( oParams == NULL && iParams == NULL && getCurrentApi() != RtAudio::RTAUDIO_DUMMY ) { 64 errorText_ = "RtApi::openStream: input and output StreamParameters structures are both NULL!"; 65 error( RtAudioError::INVALID_USE ); 66 return; 67@@ -340,6 +342,7 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams, 68 69 stream_.callbackInfo.callback = (void *) callback; 70 stream_.callbackInfo.userData = userData; 71+ stream_.callbackInfo.bufSizeCallback = (void *) bufSizeCallback; 72 stream_.callbackInfo.errorCallback = (void *) errorCallback; 73 74 if ( options ) options->numberOfBuffers = stream_.nBuffers; 75@@ -1587,6 +1590,8 @@ static void *coreStopStream( void *ptr ) 76 77 object->stopStream(); 78 pthread_exit( NULL ); 79+ 80+ return NULL; 81 } 82 83 bool RtApiCore :: callbackEvent( AudioDeviceID deviceId, 84@@ -1925,7 +1930,7 @@ const char* RtApiCore :: getErrorCode( OSStatus code ) 85 // devices are available (i.e., the JACK server is not running), a 86 // stream cannot be opened. 87 88-#include <jack/jack.h> 89+#include "jackbridge/JackBridge.hpp" 90 #include <unistd.h> 91 #include <cstdio> 92 93@@ -1934,7 +1939,6 @@ const char* RtApiCore :: getErrorCode( OSStatus code ) 94 struct JackHandle { 95 jack_client_t *client; 96 jack_port_t **ports[2]; 97- std::string deviceName[2]; 98 bool xrun[2]; 99 pthread_cond_t condition; 100 int drainCounter; // Tracks callback counts when draining 101@@ -1944,17 +1948,9 @@ struct JackHandle { 102 :client(0), drainCounter(0), internalDrain(false) { ports[0] = 0; ports[1] = 0; xrun[0] = false; xrun[1] = false; } 103 }; 104 105-#if !defined(__RTAUDIO_DEBUG__) 106-static void jackSilentError( const char * ) {}; 107-#endif 108- 109 RtApiJack :: RtApiJack() 110 :shouldAutoconnect_(true) { 111 // Nothing to do here. 112-#if !defined(__RTAUDIO_DEBUG__) 113- // Turn off Jack's internal error reporting. 114- jack_set_error_function( &jackSilentError ); 115-#endif 116 } 117 118 RtApiJack :: ~RtApiJack() 119@@ -1964,128 +1960,40 @@ RtApiJack :: ~RtApiJack() 120 121 unsigned int RtApiJack :: getDeviceCount( void ) 122 { 123- // See if we can become a jack client. 124- jack_options_t options = (jack_options_t) ( JackNoStartServer ); //JackNullOption; 125- jack_status_t *status = NULL; 126- jack_client_t *client = jack_client_open( "RtApiJackCount", options, status ); 127- if ( client == 0 ) return 0; 128- 129- const char **ports; 130- std::string port, previousPort; 131- unsigned int nChannels = 0, nDevices = 0; 132- ports = jack_get_ports( client, NULL, NULL, 0 ); 133- if ( ports ) { 134- // Parse the port names up to the first colon (:). 135- size_t iColon = 0; 136- do { 137- port = (char *) ports[ nChannels ]; 138- iColon = port.find(":"); 139- if ( iColon != std::string::npos ) { 140- port = port.substr( 0, iColon + 1 ); 141- if ( port != previousPort ) { 142- nDevices++; 143- previousPort = port; 144- } 145- } 146- } while ( ports[++nChannels] ); 147- free( ports ); 148- } 149- 150- jack_client_close( client ); 151- return nDevices; 152+ return 2; 153 } 154 155 RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device ) 156 { 157- RtAudio::DeviceInfo info; 158- info.probed = false; 159+ static RtAudio::DeviceInfo devInfo[3]; 160 161- jack_options_t options = (jack_options_t) ( JackNoStartServer ); //JackNullOption 162- jack_status_t *status = NULL; 163- jack_client_t *client = jack_client_open( "RtApiJackInfo", options, status ); 164- if ( client == 0 ) { 165- errorText_ = "RtApiJack::getDeviceInfo: Jack server not found or connection error!"; 166- error( RtAudioError::WARNING ); 167- return info; 168- } 169- 170- const char **ports; 171- std::string port, previousPort; 172- unsigned int nPorts = 0, nDevices = 0; 173- ports = jack_get_ports( client, NULL, NULL, 0 ); 174- if ( ports ) { 175- // Parse the port names up to the first colon (:). 176- size_t iColon = 0; 177- do { 178- port = (char *) ports[ nPorts ]; 179- iColon = port.find(":"); 180- if ( iColon != std::string::npos ) { 181- port = port.substr( 0, iColon ); 182- if ( port != previousPort ) { 183- if ( nDevices == device ) info.name = port; 184- nDevices++; 185- previousPort = port; 186- } 187- } 188- } while ( ports[++nPorts] ); 189- free( ports ); 190- } 191- 192- if ( device >= nDevices ) { 193- jack_client_close( client ); 194- errorText_ = "RtApiJack::getDeviceInfo: device ID is invalid!"; 195- error( RtAudioError::INVALID_USE ); 196- return info; 197- } 198- 199- // Get the current jack server sample rate. 200- info.sampleRates.clear(); 201- 202- info.preferredSampleRate = jack_get_sample_rate( client ); 203- info.sampleRates.push_back( info.preferredSampleRate ); 204- 205- // Count the available ports containing the client name as device 206- // channels. Jack "input ports" equal RtAudio output channels. 207- unsigned int nChannels = 0; 208- ports = jack_get_ports( client, info.name.c_str(), NULL, JackPortIsInput ); 209- if ( ports ) { 210- while ( ports[ nChannels ] ) nChannels++; 211- free( ports ); 212- info.outputChannels = nChannels; 213- } 214- 215- // Jack "output ports" equal RtAudio input channels. 216- nChannels = 0; 217- ports = jack_get_ports( client, info.name.c_str(), NULL, JackPortIsOutput ); 218- if ( ports ) { 219- while ( ports[ nChannels ] ) nChannels++; 220- free( ports ); 221- info.inputChannels = nChannels; 222+ if (! devInfo[0].probed) 223+ { 224+ devInfo[0].probed = devInfo[1].probed = true; 225+ devInfo[0].outputChannels = devInfo[1].outputChannels = 2; 226+ devInfo[0].inputChannels = devInfo[1].inputChannels = 2; 227+ devInfo[0].duplexChannels = devInfo[1].duplexChannels = 2; 228+ devInfo[0].isDefaultOutput = devInfo[1].isDefaultOutput = true; 229+ devInfo[0].isDefaultInput = devInfo[1].isDefaultInput = true; 230+ devInfo[0].nativeFormats = devInfo[1].nativeFormats = RTAUDIO_FLOAT32; 231+ devInfo[0].name = "Auto-connect ON"; 232+ devInfo[1].name = "Auto-connect OFF"; 233 } 234 235- if ( info.outputChannels == 0 && info.inputChannels == 0 ) { 236- jack_client_close(client); 237- errorText_ = "RtApiJack::getDeviceInfo: error determining Jack input/output channels!"; 238- error( RtAudioError::WARNING ); 239- return info; 240- } 241+ if (device > 2) 242+ device = 2; 243 244- // If device opens for both playback and capture, we determine the channels. 245- if ( info.outputChannels > 0 && info.inputChannels > 0 ) 246- info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; 247+ return devInfo[device]; 248+} 249 250- // Jack always uses 32-bit floats. 251- info.nativeFormats = RTAUDIO_FLOAT32; 252+static int jackBufferSizeHandler( jack_nframes_t nframes, void *infoPointer ) 253+{ 254+ CallbackInfo *info = (CallbackInfo *) infoPointer; 255 256- // Jack doesn't provide default devices so we'll use the first available one. 257- if ( device == 0 && info.outputChannels > 0 ) 258- info.isDefaultOutput = true; 259- if ( device == 0 && info.inputChannels > 0 ) 260- info.isDefaultInput = true; 261+ RtApiJack *object = (RtApiJack *) info->object; 262+ if ( object->bufferSizeEvent( (unsigned long) nframes ) == false ) return 1; 263 264- jack_client_close(client); 265- info.probed = true; 266- return info; 267+ return 0; 268 } 269 270 static int jackCallbackHandler( jack_nframes_t nframes, void *infoPointer ) 271@@ -2101,7 +2009,7 @@ static int jackCallbackHandler( jack_nframes_t nframes, void *infoPointer ) 272 // This function will be called by a spawned thread when the Jack 273 // server signals that it is shutting down. It is necessary to handle 274 // it this way because the jackShutdown() function must return before 275-// the jack_deactivate() function (in closeStream()) will return. 276+// the jackbridge_deactivate() function (in closeStream()) will return. 277 static void *jackCloseStream( void *ptr ) 278 { 279 CallbackInfo *info = (CallbackInfo *) ptr; 280@@ -2110,6 +2018,8 @@ static void *jackCloseStream( void *ptr ) 281 object->closeStream(); 282 283 pthread_exit( NULL ); 284+ 285+ return NULL; 286 } 287 static void jackShutdown( void *infoPointer ) 288 { 289@@ -2139,7 +2049,7 @@ static int jackXrun( void *infoPointer ) 290 } 291 292 bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 293- unsigned int firstChannel, unsigned int sampleRate, 294+ unsigned int firstChannel, unsigned int, 295 RtAudioFormat format, unsigned int *bufferSize, 296 RtAudio::StreamOptions *options ) 297 { 298@@ -2151,9 +2061,9 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne 299 jack_options_t jackoptions = (jack_options_t) ( JackNoStartServer ); //JackNullOption; 300 jack_status_t *status = NULL; 301 if ( options && !options->streamName.empty() ) 302- client = jack_client_open( options->streamName.c_str(), jackoptions, status ); 303+ client = jackbridge_client_open( options->streamName.c_str(), jackoptions, status ); 304 else 305- client = jack_client_open( "RtApiJack", jackoptions, status ); 306+ client = jackbridge_client_open( "Carla", jackoptions, status ); 307 if ( client == 0 ) { 308 errorText_ = "RtApiJack::probeDeviceOpen: Jack server not found or connection error!"; 309 error( RtAudioError::WARNING ); 310@@ -2165,75 +2075,24 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne 311 client = handle->client; 312 } 313 314- const char **ports; 315- std::string port, previousPort, deviceName; 316- unsigned int nPorts = 0, nDevices = 0; 317- ports = jack_get_ports( client, NULL, NULL, 0 ); 318- if ( ports ) { 319- // Parse the port names up to the first colon (:). 320- size_t iColon = 0; 321- do { 322- port = (char *) ports[ nPorts ]; 323- iColon = port.find(":"); 324- if ( iColon != std::string::npos ) { 325- port = port.substr( 0, iColon ); 326- if ( port != previousPort ) { 327- if ( nDevices == device ) deviceName = port; 328- nDevices++; 329- previousPort = port; 330- } 331- } 332- } while ( ports[++nPorts] ); 333- free( ports ); 334- } 335- 336- if ( device >= nDevices ) { 337- errorText_ = "RtApiJack::probeDeviceOpen: device ID is invalid!"; 338- return FAILURE; 339- } 340- 341- // Count the available ports containing the client name as device 342- // channels. Jack "input ports" equal RtAudio output channels. 343- unsigned int nChannels = 0; 344- unsigned long flag = JackPortIsInput; 345- if ( mode == INPUT ) flag = JackPortIsOutput; 346- ports = jack_get_ports( client, deviceName.c_str(), NULL, flag ); 347- if ( ports ) { 348- while ( ports[ nChannels ] ) nChannels++; 349- free( ports ); 350- } 351- 352- // Compare the jack ports for specified client to the requested number of channels. 353- if ( nChannels < (channels + firstChannel) ) { 354- errorStream_ << "RtApiJack::probeDeviceOpen: requested number of channels (" << channels << ") + offset (" << firstChannel << ") not found for specified device (" << device << ":" << deviceName << ")."; 355- errorText_ = errorStream_.str(); 356- return FAILURE; 357- } 358- 359 // Check the jack server sample rate. 360- unsigned int jackRate = jack_get_sample_rate( client ); 361- if ( sampleRate != jackRate ) { 362- jack_client_close( client ); 363- errorStream_ << "RtApiJack::probeDeviceOpen: the requested sample rate (" << sampleRate << ") is different than the JACK server rate (" << jackRate << ")."; 364- errorText_ = errorStream_.str(); 365- return FAILURE; 366- } 367- stream_.sampleRate = jackRate; 368+ stream_.sampleRate = jackbridge_get_sample_rate( client ); 369 370 // Get the latency of the JACK port. 371- ports = jack_get_ports( client, deviceName.c_str(), NULL, flag ); 372+ const char **ports; 373+ ports = jackbridge_get_ports( client, "system:", NULL, JackPortIsInput ); 374 if ( ports[ firstChannel ] ) { 375 // Added by Ge Wang 376 jack_latency_callback_mode_t cbmode = (mode == INPUT ? JackCaptureLatency : JackPlaybackLatency); 377 // the range (usually the min and max are equal) 378 jack_latency_range_t latrange; latrange.min = latrange.max = 0; 379 // get the latency range 380- jack_port_get_latency_range( jack_port_by_name( client, ports[firstChannel] ), cbmode, &latrange ); 381+ jackbridge_port_get_latency_range( jackbridge_port_by_name( client, ports[firstChannel] ), cbmode, &latrange ); 382 // be optimistic, use the min! 383 stream_.latency[mode] = latrange.min; 384- //stream_.latency[mode] = jack_port_get_latency( jack_port_by_name( client, ports[ firstChannel ] ) ); 385+ //stream_.latency[mode] = jack_port_get_latency( jackbridge_port_by_name( client, ports[ firstChannel ] ) ); 386 } 387- free( ports ); 388+ jackbridge_free( ports ); 389 390 // The jack server always uses 32-bit floating-point data. 391 stream_.deviceFormat[mode] = RTAUDIO_FLOAT32; 392@@ -2250,7 +2109,7 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne 393 394 // Get the buffer size. The buffer size and number of buffers 395 // (periods) is set when the jack server is started. 396- stream_.bufferSize = (int) jack_get_buffer_size( client ); 397+ stream_.bufferSize = (int) jackbridge_get_buffer_size( client ); 398 *bufferSize = stream_.bufferSize; 399 400 stream_.nDeviceChannels[mode] = channels; 401@@ -2281,11 +2140,10 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne 402 stream_.apiHandle = (void *) handle; 403 handle->client = client; 404 } 405- handle->deviceName[mode] = deviceName; 406 407 // Allocate necessary internal buffers. 408 unsigned long bufferBytes; 409- bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat ); 410+ bufferBytes = stream_.nUserChannels[mode] * 8192 * formatBytes( stream_.userFormat ); 411 stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 ); 412 if ( stream_.userBuffer[mode] == NULL ) { 413 errorText_ = "RtApiJack::probeDeviceOpen: error allocating user buffer memory."; 414@@ -2306,7 +2164,7 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne 415 } 416 417 if ( makeBuffer ) { 418- bufferBytes *= *bufferSize; 419+ bufferBytes *= 8192; 420 if ( stream_.deviceBuffer ) free( stream_.deviceBuffer ); 421 stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 ); 422 if ( stream_.deviceBuffer == NULL ) { 423@@ -2333,28 +2191,34 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne 424 stream_.mode = DUPLEX; 425 else { 426 stream_.mode = mode; 427- jack_set_process_callback( handle->client, jackCallbackHandler, (void *) &stream_.callbackInfo ); 428- jack_set_xrun_callback( handle->client, jackXrun, (void *) &stream_.apiHandle ); 429- jack_on_shutdown( handle->client, jackShutdown, (void *) &stream_.callbackInfo ); 430+ jackbridge_set_buffer_size_callback( handle->client, jackBufferSizeHandler, (void *) &stream_.callbackInfo ); 431+ jackbridge_set_process_callback( handle->client, jackCallbackHandler, (void *) &stream_.callbackInfo ); 432+ jackbridge_set_xrun_callback( handle->client, jackXrun, (void *) &stream_.apiHandle ); 433+ jackbridge_on_shutdown( handle->client, jackShutdown, (void *) &stream_.callbackInfo ); 434 } 435 436 // Register our ports. 437 char label[64]; 438 if ( mode == OUTPUT ) { 439 for ( unsigned int i=0; i<stream_.nUserChannels[0]; i++ ) { 440- snprintf( label, 64, "outport %d", i ); 441- handle->ports[0][i] = jack_port_register( handle->client, (const char *)label, 442+ snprintf( label, 64, "audio-out%d", i+1 ); 443+ handle->ports[0][i] = jackbridge_port_register( handle->client, (const char *)label, 444 JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); 445 } 446 } 447 else { 448 for ( unsigned int i=0; i<stream_.nUserChannels[1]; i++ ) { 449- snprintf( label, 64, "inport %d", i ); 450- handle->ports[1][i] = jack_port_register( handle->client, (const char *)label, 451+ snprintf( label, 64, "audio-in%d", i+1 ); 452+ handle->ports[1][i] = jackbridge_port_register( handle->client, (const char *)label, 453 JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ); 454 } 455 } 456 457+ // auto-connect-off "device" is at index 1 458+ shouldAutoconnect_ = (device != 1 && 459+ std::getenv("LADISH_APP_NAME") == nullptr && 460+ std::getenv("NSM_URL") == nullptr); 461+ 462 // Setup the buffer conversion information structure. We don't use 463 // buffers to do channel offsets, so we override that parameter 464 // here. 465@@ -2367,7 +2231,7 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne 466 error: 467 if ( handle ) { 468 pthread_cond_destroy( &handle->condition ); 469- jack_client_close( handle->client ); 470+ jackbridge_client_close( handle->client ); 471 472 if ( handle->ports[0] ) free( handle->ports[0] ); 473 if ( handle->ports[1] ) free( handle->ports[1] ); 474@@ -2403,9 +2267,9 @@ void RtApiJack :: closeStream( void ) 475 if ( handle ) { 476 477 if ( stream_.state == STREAM_RUNNING ) 478- jack_deactivate( handle->client ); 479+ jackbridge_deactivate( handle->client ); 480 481- jack_client_close( handle->client ); 482+ jackbridge_client_close( handle->client ); 483 } 484 485 if ( handle ) { 486@@ -2442,8 +2306,8 @@ void RtApiJack :: startStream( void ) 487 } 488 489 JackHandle *handle = (JackHandle *) stream_.apiHandle; 490- int result = jack_activate( handle->client ); 491- if ( result ) { 492+ bool result = jackbridge_activate( handle->client ); 493+ if ( ! result ) { 494 errorText_ = "RtApiJack::startStream(): unable to activate JACK client!"; 495 goto unlock; 496 } 497@@ -2452,8 +2316,8 @@ void RtApiJack :: startStream( void ) 498 499 // Get the list of available ports. 500 if ( shouldAutoconnect_ && (stream_.mode == OUTPUT || stream_.mode == DUPLEX) ) { 501- result = 1; 502- ports = jack_get_ports( handle->client, handle->deviceName[0].c_str(), NULL, JackPortIsInput); 503+ result = false; 504+ ports = jackbridge_get_ports( handle->client, "system:", NULL, JackPortIsInput); 505 if ( ports == NULL) { 506 errorText_ = "RtApiJack::startStream(): error determining available JACK input ports!"; 507 goto unlock; 508@@ -2463,21 +2327,21 @@ void RtApiJack :: startStream( void ) 509 // allow the user to select particular channels of a device, we'll 510 // just open the first "nChannels" ports with offset. 511 for ( unsigned int i=0; i<stream_.nUserChannels[0]; i++ ) { 512- result = 1; 513+ result = false; 514 if ( ports[ stream_.channelOffset[0] + i ] ) 515- result = jack_connect( handle->client, jack_port_name( handle->ports[0][i] ), ports[ stream_.channelOffset[0] + i ] ); 516- if ( result ) { 517- free( ports ); 518+ result = jackbridge_connect( handle->client, jackbridge_port_name( handle->ports[0][i] ), ports[ stream_.channelOffset[0] + i ] ); 519+ if ( ! result ) { 520+ jackbridge_free( ports ); 521 errorText_ = "RtApiJack::startStream(): error connecting output ports!"; 522 goto unlock; 523 } 524 } 525- free(ports); 526+ jackbridge_free(ports); 527 } 528 529 if ( shouldAutoconnect_ && (stream_.mode == INPUT || stream_.mode == DUPLEX) ) { 530- result = 1; 531- ports = jack_get_ports( handle->client, handle->deviceName[1].c_str(), NULL, JackPortIsOutput ); 532+ result = false; 533+ ports = jackbridge_get_ports( handle->client, "system:", NULL, JackPortIsOutput ); 534 if ( ports == NULL) { 535 errorText_ = "RtApiJack::startStream(): error determining available JACK output ports!"; 536 goto unlock; 537@@ -2485,16 +2349,16 @@ void RtApiJack :: startStream( void ) 538 539 // Now make the port connections. See note above. 540 for ( unsigned int i=0; i<stream_.nUserChannels[1]; i++ ) { 541- result = 1; 542+ result = false; 543 if ( ports[ stream_.channelOffset[1] + i ] ) 544- result = jack_connect( handle->client, ports[ stream_.channelOffset[1] + i ], jack_port_name( handle->ports[1][i] ) ); 545- if ( result ) { 546- free( ports ); 547+ result = jackbridge_connect( handle->client, ports[ stream_.channelOffset[1] + i ], jackbridge_port_name( handle->ports[1][i] ) ); 548+ if ( ! result ) { 549+ jackbridge_free( ports ); 550 errorText_ = "RtApiJack::startStream(): error connecting input ports!"; 551 goto unlock; 552 } 553 } 554- free(ports); 555+ jackbridge_free(ports); 556 } 557 558 handle->drainCounter = 0; 559@@ -2502,7 +2366,7 @@ void RtApiJack :: startStream( void ) 560 stream_.state = STREAM_RUNNING; 561 562 unlock: 563- if ( result == 0 ) return; 564+ if ( result ) return; 565 error( RtAudioError::SYSTEM_ERROR ); 566 } 567 568@@ -2524,7 +2388,7 @@ void RtApiJack :: stopStream( void ) 569 } 570 } 571 572- jack_deactivate( handle->client ); 573+ jackbridge_deactivate( handle->client ); 574 stream_.state = STREAM_STOPPED; 575 } 576 577@@ -2546,7 +2410,7 @@ void RtApiJack :: abortStream( void ) 578 // This function will be called by a spawned thread when the user 579 // callback function signals that the stream should be stopped or 580 // aborted. It is necessary to handle it this way because the 581-// callbackEvent() function must return before the jack_deactivate() 582+// callbackEvent() function must return before the jackbridge_deactivate() 583 // function will return. 584 static void *jackStopStream( void *ptr ) 585 { 586@@ -2555,6 +2419,8 @@ static void *jackStopStream( void *ptr ) 587 588 object->stopStream(); 589 pthread_exit( NULL ); 590+ 591+ return NULL; 592 } 593 594 bool RtApiJack :: callbackEvent( unsigned long nframes ) 595@@ -2565,8 +2431,8 @@ bool RtApiJack :: callbackEvent( unsigned long nframes ) 596 error( RtAudioError::WARNING ); 597 return FAILURE; 598 } 599- if ( stream_.bufferSize != nframes ) { 600- errorText_ = "RtApiCore::callbackEvent(): the JACK buffer size has changed ... cannot process!"; 601+ if ( nframes > 8192 ) { 602+ errorText_ = "RtApiCore::callbackEvent(): the JACK buffer size is too big ... cannot process!"; 603 error( RtAudioError::WARNING ); 604 return FAILURE; 605 } 606@@ -2600,7 +2466,7 @@ bool RtApiJack :: callbackEvent( unsigned long nframes ) 607 handle->xrun[1] = false; 608 } 609 int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1], 610- stream_.bufferSize, streamTime, status, info->userData ); 611+ nframes, streamTime, status, info->userData ); 612 if ( cbReturnValue == 2 ) { 613 stream_.state = STREAM_STOPPING; 614 handle->drainCounter = 2; 615@@ -2621,7 +2487,7 @@ bool RtApiJack :: callbackEvent( unsigned long nframes ) 616 if ( handle->drainCounter > 1 ) { // write zeros to the output stream 617 618 for ( unsigned int i=0; i<stream_.nDeviceChannels[0]; i++ ) { 619- jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[0][i], (jack_nframes_t) nframes ); 620+ jackbuffer = (jack_default_audio_sample_t *) jackbridge_port_get_buffer( handle->ports[0][i], (jack_nframes_t) nframes ); 621 memset( jackbuffer, 0, bufferBytes ); 622 } 623 624@@ -2631,13 +2497,13 @@ bool RtApiJack :: callbackEvent( unsigned long nframes ) 625 convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] ); 626 627 for ( unsigned int i=0; i<stream_.nDeviceChannels[0]; i++ ) { 628- jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[0][i], (jack_nframes_t) nframes ); 629+ jackbuffer = (jack_default_audio_sample_t *) jackbridge_port_get_buffer( handle->ports[0][i], (jack_nframes_t) nframes ); 630 memcpy( jackbuffer, &stream_.deviceBuffer[i*bufferBytes], bufferBytes ); 631 } 632 } 633 else { // no buffer conversion 634 for ( unsigned int i=0; i<stream_.nUserChannels[0]; i++ ) { 635- jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[0][i], (jack_nframes_t) nframes ); 636+ jackbuffer = (jack_default_audio_sample_t *) jackbridge_port_get_buffer( handle->ports[0][i], (jack_nframes_t) nframes ); 637 memcpy( jackbuffer, &stream_.userBuffer[0][i*bufferBytes], bufferBytes ); 638 } 639 } 640@@ -2653,14 +2519,14 @@ bool RtApiJack :: callbackEvent( unsigned long nframes ) 641 642 if ( stream_.doConvertBuffer[1] ) { 643 for ( unsigned int i=0; i<stream_.nDeviceChannels[1]; i++ ) { 644- jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[1][i], (jack_nframes_t) nframes ); 645+ jackbuffer = (jack_default_audio_sample_t *) jackbridge_port_get_buffer( handle->ports[1][i], (jack_nframes_t) nframes ); 646 memcpy( &stream_.deviceBuffer[i*bufferBytes], jackbuffer, bufferBytes ); 647 } 648 convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] ); 649 } 650 else { // no buffer conversion 651 for ( unsigned int i=0; i<stream_.nUserChannels[1]; i++ ) { 652- jackbuffer = (jack_default_audio_sample_t *) jack_port_get_buffer( handle->ports[1][i], (jack_nframes_t) nframes ); 653+ jackbuffer = (jack_default_audio_sample_t *) jackbridge_port_get_buffer( handle->ports[1][i], (jack_nframes_t) nframes ); 654 memcpy( &stream_.userBuffer[1][i*bufferBytes], jackbuffer, bufferBytes ); 655 } 656 } 657@@ -2670,6 +2536,26 @@ bool RtApiJack :: callbackEvent( unsigned long nframes ) 658 RtApi::tickStreamTime(); 659 return SUCCESS; 660 } 661+ 662+bool RtApiJack :: bufferSizeEvent( unsigned long nframes ) 663+{ 664+ if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS; 665+ if ( stream_.state == STREAM_CLOSED ) { 666+ errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!"; 667+ error( RtAudioError::WARNING ); 668+ return FAILURE; 669+ } 670+ if ( nframes > 8192 ) { 671+ errorText_ = "RtApiCore::callbackEvent(): the JACK buffer size is too big ... cannot process!"; 672+ error( RtAudioError::WARNING ); 673+ return FAILURE; 674+ } 675+ 676+ CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo; 677+ 678+ RtAudioBufferSizeCallback callback = (RtAudioBufferSizeCallback) info->bufSizeCallback; 679+ return callback( nframes, info->userData ); 680+} 681 //******************** End of __UNIX_JACK__ *********************// 682 #endif 683 684@@ -2691,10 +2577,10 @@ bool RtApiJack :: callbackEvent( unsigned long nframes ) 685 // on information found in 686 // http://www.cs.wustl.edu/~schmidt/win32-cv-1.html. 687 688-#include "asiosys.h" 689-#include "asio.h" 690-#include "iasiothiscallresolver.h" 691-#include "asiodrivers.h" 692+#include "asio.cpp" 693+#include "asiodrivers.cpp" 694+#include "asiolist.cpp" 695+#include "iasiothiscallresolver.cpp" 696 #include <cmath> 697 698 static AsioDrivers drivers; 699@@ -5487,8 +5373,8 @@ bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned 700 // two. This is a judgement call and a value of two is probably too 701 // low for capture, but it should work for playback. 702 int nBuffers = 0; 703- if ( options ) nBuffers = options->numberOfBuffers; 704 if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) nBuffers = 2; 705+ if ( options && options->numberOfBuffers > 0 ) nBuffers = options->numberOfBuffers; 706 if ( nBuffers < 2 ) nBuffers = 3; 707 708 // Check the lower range of the user-specified buffer size and set 709@@ -6795,7 +6681,9 @@ unsigned int RtApiAlsa :: getDeviceCount( void ) 710 nDevices++; 711 } 712 nextcard: 713- snd_ctl_close( handle ); 714+ if (result == 0) { 715+ snd_ctl_close( handle ); 716+ } 717 snd_card_next( &card ); 718 } 719 720@@ -8012,12 +7900,14 @@ static void *alsaCallbackHandler( void *ptr ) 721 } 722 723 pthread_exit( NULL ); 724+ 725+ return NULL; 726 } 727 728 //******************** End of __LINUX_ALSA__ *********************// 729 #endif 730 731-#if defined(__LINUX_PULSE__) 732+#if defined(__UNIX_PULSE__) 733 734 // Code written by Peter Meerwald, pmeerw@pmeerw.net 735 // and Tristan Matthews. 736@@ -8092,6 +7982,8 @@ static void *pulseaudio_callback( void * user ) 737 } 738 739 pthread_exit( NULL ); 740+ 741+ return NULL; 742 } 743 744 void RtApiPulse::closeStream( void ) 745@@ -8502,7 +8394,7 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode, 746 return FAILURE; 747 } 748 749-//******************** End of __LINUX_PULSE__ *********************// 750+//******************** End of __UNIX_PULSE__ *********************// 751 #endif 752 753 #if defined(__LINUX_OSS__) 754@@ -9446,6 +9338,8 @@ static void *ossCallbackHandler( void *ptr ) 755 } 756 757 pthread_exit( NULL ); 758+ 759+ return NULL; 760 } 761 762 //******************** End of __LINUX_OSS__ *********************// 763diff --git a/RtAudio.h b/RtAudio.h 764index 34a2534..289e254 100644 765--- a/RtAudio.h 766+++ b/RtAudio.h 767@@ -46,16 +46,7 @@ 768 #define __RTAUDIO_H 769 770 #define RTAUDIO_VERSION "5.0.0" 771- 772-#if defined _WIN32 || defined __CYGWIN__ 773- #define RTAUDIO_DLL_PUBLIC 774-#else 775- #if __GNUC__ >= 4 776- #define RTAUDIO_DLL_PUBLIC __attribute__( (visibility( "default" )) ) 777- #else 778- #define RTAUDIO_DLL_PUBLIC 779- #endif 780-#endif 781+#define RTAUDIO_DLL_PUBLIC 782 783 #include <string> 784 #include <vector> 785@@ -255,6 +246,9 @@ class RTAUDIO_DLL_PUBLIC RtAudioError : public std::runtime_error 786 */ 787 typedef void (*RtAudioErrorCallback)( RtAudioError::Type type, const std::string &errorText ); 788 789+//! RtAudio buffer size change callback. 790+typedef bool (*RtAudioBufferSizeCallback)( unsigned int bufferSize, void* userData ); 791+ 792 // **************************************************************** // 793 // 794 // RtAudio class declaration. 795@@ -278,8 +272,8 @@ class RTAUDIO_DLL_PUBLIC RtAudio 796 enum Api { 797 UNSPECIFIED, /*!< Search for a working compiled API. */ 798 LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */ 799- LINUX_PULSE, /*!< The Linux PulseAudio API. */ 800 LINUX_OSS, /*!< The Linux Open Sound System API. */ 801+ UNIX_PULSE, /*!< The PulseAudio API. */ 802 UNIX_JACK, /*!< The Jack Low-Latency Audio Server API. */ 803 MACOSX_CORE, /*!< Macintosh OS-X Core Audio API. */ 804 WINDOWS_WASAPI, /*!< The Microsoft WASAPI API. */ 805@@ -416,7 +410,7 @@ class RTAUDIO_DLL_PUBLIC RtAudio 806 ~RtAudio(); 807 808 //! Returns the audio API specifier for the current instance of RtAudio. 809- RtAudio::Api getCurrentApi( void ); 810+ RtAudio::Api getCurrentApi( void ) const; 811 812 //! A public function that queries for the number of audio devices available. 813 /*! 814@@ -503,7 +497,9 @@ class RTAUDIO_DLL_PUBLIC RtAudio 815 RtAudio::StreamParameters *inputParameters, 816 RtAudioFormat format, unsigned int sampleRate, 817 unsigned int *bufferFrames, RtAudioCallback callback, 818- void *userData = NULL, RtAudio::StreamOptions *options = NULL, RtAudioErrorCallback errorCallback = NULL ); 819+ void *userData = NULL, RtAudio::StreamOptions *options = NULL, 820+ RtAudioBufferSizeCallback bufSizeCallback = NULL, 821+ RtAudioErrorCallback errorCallback = NULL ); 822 823 //! A function that closes a stream and frees any associated stream memory. 824 /*! 825@@ -597,7 +593,7 @@ class RTAUDIO_DLL_PUBLIC RtAudio 826 typedef uintptr_t ThreadHandle; 827 typedef CRITICAL_SECTION StreamMutex; 828 829-#elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__) 830+#elif defined(__LINUX_ALSA__) || defined(__UNIX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__) || defined(__HAIKU__) 831 // Using pthread library for various flavors of unix. 832 #include <pthread.h> 833 834@@ -620,6 +616,7 @@ struct CallbackInfo { 835 ThreadHandle thread; 836 void *callback; 837 void *userData; 838+ void *bufSizeCallback; 839 void *errorCallback; 840 void *apiInfo; // void pointer for API specific callback information 841 bool isRunning; 842@@ -628,7 +625,7 @@ struct CallbackInfo { 843 844 // Default constructor. 845 CallbackInfo() 846- :object(0), callback(0), userData(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false), priority(0) {} 847+ :object(0), callback(0), userData(0), bufSizeCallback(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false), priority(0) {} 848 }; 849 850 // **************************************************************** // 851@@ -687,7 +684,7 @@ public: 852 853 RtApi(); 854 virtual ~RtApi(); 855- virtual RtAudio::Api getCurrentApi( void ) = 0; 856+ virtual RtAudio::Api getCurrentApi( void ) const = 0; 857 virtual unsigned int getDeviceCount( void ) = 0; 858 virtual RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0; 859 virtual unsigned int getDefaultInputDevice( void ); 860@@ -697,6 +694,7 @@ public: 861 RtAudioFormat format, unsigned int sampleRate, 862 unsigned int *bufferFrames, RtAudioCallback callback, 863 void *userData, RtAudio::StreamOptions *options, 864+ RtAudioBufferSizeCallback bufSizeCallback, 865 RtAudioErrorCallback errorCallback ); 866 virtual void closeStream( void ); 867 virtual void startStream( void ) = 0; 868@@ -836,7 +834,7 @@ protected: 869 // 870 // **************************************************************** // 871 872-inline RtAudio::Api RtAudio :: getCurrentApi( void ) { return rtapi_->getCurrentApi(); } 873+inline RtAudio::Api RtAudio :: getCurrentApi( void ) const { return rtapi_->getCurrentApi(); } 874 inline unsigned int RtAudio :: getDeviceCount( void ) { return rtapi_->getDeviceCount(); } 875 inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); } 876 inline unsigned int RtAudio :: getDefaultInputDevice( void ) { return rtapi_->getDefaultInputDevice(); } 877@@ -865,7 +863,7 @@ public: 878 879 RtApiCore(); 880 ~RtApiCore(); 881- RtAudio::Api getCurrentApi( void ) { return RtAudio::MACOSX_CORE; } 882+ RtAudio::Api getCurrentApi( void ) const { return RtAudio::MACOSX_CORE; } 883 unsigned int getDeviceCount( void ); 884 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 885 unsigned int getDefaultOutputDevice( void ); 886@@ -903,7 +901,7 @@ public: 887 888 RtApiJack(); 889 ~RtApiJack(); 890- RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; } 891+ RtAudio::Api getCurrentApi( void ) const { return RtAudio::UNIX_JACK; } 892 unsigned int getDeviceCount( void ); 893 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 894 void closeStream( void ); 895@@ -918,6 +916,9 @@ public: 896 // will most likely produce highly undesireable results! 897 bool callbackEvent( unsigned long nframes ); 898 899+ // Buffer size change callback 900+ bool bufferSizeEvent( unsigned long nframes ); 901+ 902 private: 903 904 bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, 905@@ -938,7 +939,7 @@ public: 906 907 RtApiAsio(); 908 ~RtApiAsio(); 909- RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_ASIO; } 910+ RtAudio::Api getCurrentApi( void ) const { return RtAudio::WINDOWS_ASIO; } 911 unsigned int getDeviceCount( void ); 912 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 913 void closeStream( void ); 914@@ -974,7 +975,7 @@ public: 915 916 RtApiDs(); 917 ~RtApiDs(); 918- RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_DS; } 919+ RtAudio::Api getCurrentApi( void ) const { return RtAudio::WINDOWS_DS; } 920 unsigned int getDeviceCount( void ); 921 unsigned int getDefaultOutputDevice( void ); 922 unsigned int getDefaultInputDevice( void ); 923@@ -1015,7 +1016,7 @@ public: 924 RtApiWasapi(); 925 ~RtApiWasapi(); 926 927- RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_WASAPI; } 928+ RtAudio::Api getCurrentApi( void ) const { return RtAudio::WINDOWS_WASAPI; } 929 unsigned int getDeviceCount( void ); 930 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 931 unsigned int getDefaultOutputDevice( void ); 932@@ -1050,7 +1051,7 @@ public: 933 934 RtApiAlsa(); 935 ~RtApiAlsa(); 936- RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; } 937+ RtAudio::Api getCurrentApi() const { return RtAudio::LINUX_ALSA; } 938 unsigned int getDeviceCount( void ); 939 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 940 void closeStream( void ); 941@@ -1076,13 +1077,13 @@ public: 942 943 #endif 944 945-#if defined(__LINUX_PULSE__) 946+#if defined(__UNIX_PULSE__) 947 948 class RtApiPulse: public RtApi 949 { 950 public: 951 ~RtApiPulse(); 952- RtAudio::Api getCurrentApi() { return RtAudio::LINUX_PULSE; } 953+ RtAudio::Api getCurrentApi() const { return RtAudio::UNIX_PULSE; } 954 unsigned int getDeviceCount( void ); 955 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 956 void closeStream( void ); 957@@ -1116,7 +1117,7 @@ public: 958 959 RtApiOss(); 960 ~RtApiOss(); 961- RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; } 962+ RtAudio::Api getCurrentApi() const { return RtAudio::LINUX_OSS; } 963 unsigned int getDeviceCount( void ); 964 RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); 965 void closeStream( void ); 966@@ -1147,7 +1148,7 @@ class RtApiDummy: public RtApi 967 public: 968 969 RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( RtAudioError::WARNING ); } 970- RtAudio::Api getCurrentApi( void ) { return RtAudio::RTAUDIO_DUMMY; } 971+ RtAudio::Api getCurrentApi( void ) const { return RtAudio::RTAUDIO_DUMMY; } 972 unsigned int getDeviceCount( void ) { return 0; } 973 RtAudio::DeviceInfo getDeviceInfo( unsigned int /*device*/ ) { RtAudio::DeviceInfo info; return info; } 974 void closeStream( void ) {} 975diff --git a/include/asio.h b/include/asio.h 976index 8ec811f..656f681 100644 977--- a/include/asio.h 978+++ b/include/asio.h 979@@ -3,11 +3,12 @@ 980 981 /* 982 Steinberg Audio Stream I/O API 983- (c) 1997 - 2005, Steinberg Media Technologies GmbH 984+ (c) 1997 - 2013, Steinberg Media Technologies GmbH 985 986- ASIO Interface Specification v 2.1 987+ ASIO Interface Specification v 2.3 988 989 2005 - Added support for DSD sample data (in cooperation with Sony) 990+ 2012 - Added support for drop out detection 991 992 993 basic concept is an i/o synchronous double-buffer scheme: 994@@ -916,6 +917,7 @@ enum 995 kAsioCanInputMeter, 996 kAsioCanOutputGain, 997 kAsioCanOutputMeter, 998+ kAsioOptionalOne, 999 1000 // DSD support 1001 // The following extensions are required to allow switching 1002@@ -923,6 +925,9 @@ enum 1003 kAsioSetIoFormat = 0x23111961, /* ASIOIoFormat * in params. */ 1004 kAsioGetIoFormat = 0x23111983, /* ASIOIoFormat * in params. */ 1005 kAsioCanDoIoFormat = 0x23112004, /* ASIOIoFormat * in params. */ 1006+ // Extension for drop out detection 1007+ kAsioCanReportOverload = 0x24042012, /* return ASE_SUCCESS if driver can detect and report overloads */ 1008+ kAsioGetInternalBufferSamples = 0x25042012 /* ASIOInternalBufferInfo * in params. Deliver size of driver internal buffering, return ASE_SUCCESS if supported */ 1009 }; 1010 1011 typedef struct ASIOInputMonitor 1012@@ -1003,6 +1008,14 @@ typedef struct ASIOIoFormat_s 1013 char future[512-sizeof(ASIOIoFormatType)]; 1014 } ASIOIoFormat; 1015 1016+// Extension for drop detection 1017+// Note: Refers to buffering that goes beyond the double buffer e.g. used by USB driver designs 1018+typedef struct ASIOInternalBufferInfo 1019+{ 1020+ long inputSamples; // size of driver's internal input buffering which is included in getLatencies 1021+ long outputSamples; // size of driver's internal output buffering which is included in getLatencies 1022+} ASIOInternalBufferInfo; 1023+ 1024 1025 ASIOError ASIOOutputReady(void); 1026 /* Purpose: 1027diff --git a/include/asiosys.h b/include/asiosys.h 1028index 37f7a48..c974fc3 100644 1029--- a/include/asiosys.h 1030+++ b/include/asiosys.h 1031@@ -1,7 +1,7 @@ 1032 #ifndef __asiosys__ 1033 #define __asiosys__ 1034 1035- #ifdef WIN32 1036+ #if defined(WIN32) || defined(_WIN64) 1037 #undef MAC 1038 #define PPC 0 1039 #define WINDOWS 1 1040diff --git a/include/ginclude.h b/include/ginclude.h 1041index b627dc2..8c609c7 100644 1042--- a/include/ginclude.h 1043+++ b/include/ginclude.h 1044@@ -8,7 +8,7 @@ 1045 // 1046 #define ASIO_BIG_ENDIAN 1 1047 #define ASIO_CPU_MIPS 1 1048-#elif defined WIN32 1049+#elif defined(WIN32) || defined(_WIN64) 1050 #undef BEOS 1051 #undef MAC 1052 #undef SGI 1053diff --git a/include/iasiodrv.h b/include/iasiodrv.h 1054index 64d2dbb..860675c 100644 1055--- a/include/iasiodrv.h 1056+++ b/include/iasiodrv.h 1057@@ -1,3 +1,4 @@ 1058+#pragma once 1059 #include "asiosys.h" 1060 #include "asio.h" 1061 1062