Skip to content

Commit 806da09

Browse files
committed
Allow portaudio driver on any system, use device reservation too
Signed-off-by: falkTX <falktx@falktx.com>
1 parent 7d08d7f commit 806da09

File tree

3 files changed

+99
-5
lines changed

3 files changed

+99
-5
lines changed

windows/portaudio/JackPortAudioDriver.cpp

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,43 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2929
#include <iostream>
3030
#include <assert.h>
3131

32+
#ifdef __linux__
33+
#include "JackServerGlobals.h"
34+
#endif
35+
3236
using namespace std;
3337

3438
namespace Jack
3539
{
3640

41+
#ifdef __linux__
42+
static volatile bool device_reservation_loop_running = false;
43+
44+
static void* on_device_reservation_loop(void*)
45+
{
46+
while (device_reservation_loop_running && JackServerGlobals::on_device_reservation_loop != NULL) {
47+
JackServerGlobals::on_device_reservation_loop();
48+
usleep(50*1000);
49+
}
50+
51+
return NULL;
52+
}
53+
54+
static bool name_to_num(const char* paDeviceName, char* entry)
55+
{
56+
if (const char* sep = strstr(paDeviceName, " (hw:"))
57+
{
58+
sep += 5;
59+
while (*sep != '\0' && *sep != ',' && *sep != ')')
60+
*entry++ = *sep++;
61+
*entry = '\0';
62+
return true;
63+
}
64+
65+
return false;
66+
}
67+
#endif
68+
3769
int JackPortAudioDriver::Render(const void* inputBuffer, void* outputBuffer,
3870
unsigned long framesPerBuffer,
3971
const PaStreamCallbackTimeInfo* timeInfo,
@@ -231,6 +263,27 @@ int JackPortAudioDriver::Open(jack_nframes_t buffer_size,
231263
fCaptureChannels = inchannels;
232264
fPlaybackChannels = outchannels;
233265

266+
#ifdef __linux__
267+
if (JackServerGlobals::on_device_acquire != NULL) {
268+
char audio_name[32];
269+
snprintf(audio_name, sizeof(audio_name), "Audio");
270+
271+
if (name_to_num(capture_driver_name, audio_name+5)) {
272+
if (!JackServerGlobals::on_device_acquire(audio_name)) {
273+
jack_error("Audio device %s cannot be acquired...", capture_driver_name);
274+
return -1;
275+
}
276+
}
277+
278+
if (strcmp(capture_driver_name, playback_driver_name) && name_to_num(playback_driver_name, audio_name+5)) {
279+
if (!JackServerGlobals::on_device_acquire(audio_name)) {
280+
jack_error("Audio device %s cannot be acquired...", playback_driver_name);
281+
return -1;
282+
}
283+
}
284+
}
285+
#endif
286+
234287
err = OpenStream(buffer_size);
235288
if (err != paNoError) {
236289
jack_error("Pa_OpenStream error = %s", Pa_GetErrorText(err));
@@ -243,6 +296,15 @@ int JackPortAudioDriver::Open(jack_nframes_t buffer_size,
243296
fEngineControl->fConstraint = fEngineControl->fPeriodUsecs * 1000;
244297
#endif
245298

299+
#ifdef __linux__
300+
if (JackServerGlobals::on_device_reservation_loop != NULL) {
301+
device_reservation_loop_running = true;
302+
if (JackPosixThread::StartImp(&fReservationLoopThread, 0, 0, on_device_reservation_loop, NULL) != 0) {
303+
device_reservation_loop_running = false;
304+
}
305+
}
306+
#endif
307+
246308
return 0;
247309

248310
error:
@@ -260,6 +322,28 @@ int JackPortAudioDriver::Close()
260322
if (err != paNoError) {
261323
jack_error("Pa_CloseStream error = %s", Pa_GetErrorText(err));
262324
}
325+
326+
#ifdef __linux__
327+
if (device_reservation_loop_running) {
328+
device_reservation_loop_running = false;
329+
JackPosixThread::StopImp(fReservationLoopThread);
330+
}
331+
332+
if (JackServerGlobals::on_device_release != NULL)
333+
{
334+
char audio_name[32];
335+
snprintf(audio_name, sizeof(audio_name), "Audio");
336+
337+
if (name_to_num(fCaptureDriverName, audio_name+5)) {
338+
JackServerGlobals::on_device_release(audio_name);
339+
}
340+
341+
if (strcmp(fCaptureDriverName, fPlaybackDriverName) && name_to_num(fPlaybackDriverName, audio_name+5)) {
342+
JackServerGlobals::on_device_release(audio_name);
343+
}
344+
}
345+
#endif
346+
263347
delete fPaDevices;
264348
fPaDevices = NULL;
265349
return (err != paNoError) ? -1 : 0;
@@ -269,9 +353,9 @@ int JackPortAudioDriver::Attach()
269353
{
270354
if (JackAudioDriver::Attach() == 0) {
271355

356+
#if defined(HAVE_ASIO)
272357
const char* alias;
273358

274-
#if defined(HAVE_ASIO)
275359
if (fInputDevice != paNoDevice && fPaDevices->GetHostFromDevice(fInputDevice) == "ASIO") {
276360
for (int i = 0; i < fCaptureChannels; i++) {
277361
if (PaAsio_GetInputChannelName(fInputDevice, i, &alias) == paNoError) {

windows/portaudio/JackPortAudioDriver.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2222

2323
#include "JackAudioDriver.h"
2424
#include "JackPortAudioDevices.h"
25+
26+
#ifdef _WIN32
2527
#include "JackMMCSS.h"
28+
#endif
2629

2730
namespace Jack
2831
{
@@ -31,7 +34,11 @@ namespace Jack
3134
\brief The PortAudio driver.
3235
*/
3336

34-
class JackPortAudioDriver : public JackMMCSS, public JackAudioDriver
37+
class JackPortAudioDriver :
38+
#ifdef _WIN32
39+
public JackMMCSS,
40+
#endif
41+
public JackAudioDriver
3542
{
3643

3744
private:
@@ -42,6 +49,7 @@ class JackPortAudioDriver : public JackMMCSS, public JackAudioDriver
4249
PaDeviceIndex fInputDevice;
4350
PaDeviceIndex fOutputDevice;
4451
PortAudioDevices* fPaDevices;
52+
jack_native_thread_t fReservationLoopThread;
4553

4654
static int Render(const void* inputBuffer, void* outputBuffer,
4755
unsigned long framesPerBuffer,
@@ -55,8 +63,11 @@ class JackPortAudioDriver : public JackMMCSS, public JackAudioDriver
5563

5664
public:
5765

58-
JackPortAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, PortAudioDevices* pa_devices)
59-
: JackMMCSS(), JackAudioDriver(name, alias, engine, table), fStream(NULL), fInputBuffer(NULL), fOutputBuffer(NULL),
66+
JackPortAudioDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table, PortAudioDevices* pa_devices) :
67+
#ifdef _WIN32
68+
JackMMCSS(),
69+
#endif
70+
JackAudioDriver(name, alias, engine, table), fStream(NULL), fInputBuffer(NULL), fOutputBuffer(NULL),
6071
fInputDevice(paNoDevice), fOutputDevice(paNoDevice), fPaDevices(pa_devices)
6172
{}
6273

wscript

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ def options(opt):
151151
'portaudio',
152152
help='Enable Portaudio driver',
153153
conf_dest='BUILD_DRIVER_PORTAUDIO')
154-
portaudio.check(header_name='windows.h') # only build portaudio on windows
155154
portaudio.check_cfg(
156155
package='portaudio-2.0 >= 19',
157156
uselib_store='PORTAUDIO',

0 commit comments

Comments
 (0)