Routing Audio from an External Application into a JUCE Application using JACK


#1

I am trying build a JUCE application that receives audio from an external application (for example, a DAW like Cubase) and analyzes it. I need to be able to get audio from lots of different channels and sources, so I need at least 32 inputs into my JUCE application. I am on Windows, so it seemed like JACK would be a good way to do this. 

I can setup and run the JACK server on windows successfully, and connect to the JackRouter (an ASIO device) from my DAW (Cubase). However, I cannot figure out how to connect to the JackRouter from my JUCE application. I've tried doing

AudioIODeviceType* device = AudioIODeviceType::createAudioIODeviceType_JACK();

AudioIODeviceType* device = AudioIODeviceType::createAudioIODeviceType_ASIO();

and both return null, meaning that there is no available device of either type. I've also tried using the AudioDeviceManager class to scan for devices, but the only devices it finds are my speakers.

 The JACK website says that "any ASIO application will be able to use the JackRouter ASIO linker to connect to Jack, and Jack can then be used to route that audio to other applications connected to the Jack Audio Server, or out to the system sound device.", and so I think that I need to somehow connect directly to the JACK Audio Server rather than to the JackRouter, but I have no idea how to go about doing this.

Does anyone know how to connect to JACK from JUCE on windows? Or if it's not possible, is there some other way to do this? Thanks for your help in advance.


#2

You can enable ASIO by setting the JUCE_ASIO flag (it's off by default because people don't all have the headers). But there's no JACK implementation for windows, just linux.


#3

Okay, I've switched over to Linux and I am still having the same issue. The jack server runs successfully on my machine and I can connect to it via other applications.

 

#define JUCE_JACK 1

.
.
.

AudioIODeviceType* device = AudioIODeviceType::createAudioIODeviceType_JACK();

When I set the flags and try to create a device, it fails and returns null.

The AudioDeviceManager now connects to an ALSA device. When the device connects, the jack server prints out some messages about "XRUN callback", but I don't see any extra inputs or outputs in the Jack Control panel, so I'm not really sure what is going on (my ALSA device was intialised with 2 inputs/outputs).

What am I doing wrong?


#4

So I've made some progress with this and was able to create a Jack device from my JUCE app. The problem was that I wasn't editing the flag in the module code itself. However, I'm having trouble figuring out how to create virtual inputs/outputs to route audio.

When I instantiate the Jack server, I am only able to create 2 input and 4 output channels (due to hardware constraints), but my application needs many inputs since it needs to read audio data of individual tracks. So I need to make additional inputs/outputs and I'm not sure how.

This is how I am currently creating my device

audioIODeviceType = AudioIODeviceType::createAudioIODeviceType_JACK();
    if (audioIODeviceType != nullptr)
    {
        audioIODeviceType->scanForDevices();
        StringArray deviceNames (audioIODeviceType->getDeviceNames());
        for (int i=0; i<deviceNames.size(); ++i) {
            textEditor->insertTextAtCaret("device: ");
            textEditor->insertTextAtCaret(deviceNames[i]);
            textEditor->insertTextAtCaret("\n");
            audioIODevice = audioIODeviceType->createDevice(deviceNames[i],deviceNames[i]);
        }
    } else {
        textEditor->insertTextAtCaret("Error, could not open Jack audio device. Is your Jack Server running?\n");
    }
    
    addAndMakeVisible (visualizer = new Visualizer());
    audioIODevice->open(BigInteger(15),BigInteger(15),48000,1024);
    if (audioIODevice->isOpen())
    {
        textEditor->insertTextAtCaret("Audio device is open\n");
        audioIODevice->start(visualizer);
    } else {
        textEditor->insertTextAtCaret("Error, could not start Jack audio device.\n");
    }

One workaround I can find is here, http://alsa.opensrc.org/Jack_and_Loopback_device_as_Alsa-to-Jack_bridge . It should work but is not a good solution because all of my end users would have to also do this, and it is not a trivial amount of work.

How can I create more inputs/outputs with my jack device?


#5

Okay, so I was able to create a custom Jack device by throwing jpo's code from this thread (http://www.juce.com/forum/topic/jackaudioiodevice-input/output-channel-count#comment-form) into my source code and then calling

audioIODeviceType = AudioIODeviceType::createAudioIODeviceType_JACK_Custom();
 

It works for creating the correct number of inputs and outputs, but now my app keeps stalling every 5 seconds or so for about (exactly?) 2 seconds. Here is the stack trace when it stalls, it looks like it is stuck waiting for messages or something but not sure why...

Does anyone have any idea? I tried googling for the  ../sysdeps/unix/syscall-template.S: No such file or directory. error and attempted to resolve that by doing "sudo apt-get install eglibc-source" but the same thing still happens with my app so I'm guessing that is unrelated.

 

^C
Program received signal SIGINT, Interrupt.

0x00007ffff5f7dc33 in select () at ../sysdeps/unix/syscall-template.S:81
81    ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) backtrace
#0  0x00007ffff5f7dc33 in select () at ../sysdeps/unix/syscall-template.S:81
#1  0x00000000005a6865 in juce::InternalMessageQueue::sleepUntilEvent (
    this=0xf33bc0, timeoutMs=2000)
    at ../../JuceLibraryCode/modules/juce_events/native/juce_linux_Messaging.cpp:129
#2  0x00000000005a3ed1 in juce::MessageManager::dispatchNextMessageOnSystemQueue (returnIfNoPendingMessages=false)
    at ../../JuceLibraryCode/modules/juce_events/native/juce_linux_Messaging.cpp:394
#3  0x00000000005a00b1 in juce::MessageManager::runDispatchLoopUntil (
    this=0xf33ac0, millisecondsToRunFor=-1)
    at ../../JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.cpp:94
#4  0x00000000005a003f in juce::MessageManager::runDispatchLoop (this=0xf33ac0)
    at ../../JuceLibraryCode/modules/juce_events/messages/juce_MessageManager.cpp:81
#5  0x000000000059f5ba in juce::JUCEApplicationBase::main ()
    at ../../JuceLibraryCode/modules/juce_events/messages/juce_ApplicationBase.cpp:235
#6  0x000000000059f4e2 in juce::JUCEApplicationBase::main (argc=1,
    argv=0x7fffffffdfa8)
    at ../../JuceLibraryCode/modules/juce_events/messages/juce_ApplicationBase.cpp:213