Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1062 lines
41KB

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