.jucer GUI project run on Linux without desktop... can I?

So, I continue my quest for a “GUI-independent” audio processing block.
Here’s what I’ve done so far:

  1. Created a GUI project using Projucer (as suggested by @ed95)
  2. I added a new class (acloc) that I think should give me the audio processor portion of this…

acloc.h::

#pragma once

#include<JuceHeader.h>

class acloc: public juce::AudioIODeviceCallback
{
public:
acloc();
~acloc();

bool init(juce::String devname, int sampfreq, int bufsz);

void audioDeviceAboutToStart (juce::AudioIODevice*) override;
void audioDeviceStopped() override;
void audioDeviceIOCallback (const float** inputChannelData, int numInputChannels,
                            float** outputChannelData, int numOutputChannels,
                            int numberOfSamples) override;


juce::AudioDeviceManager audMgr;
juce::AudioDeviceManager::AudioDeviceSetup audSetup;

private:
int SampFreq;
int BufSz;
juce::String AudioDevice;

};

acloc.cpp:

#include “acloc.h”

acloc::acloc() { std::cout << func << std::endl; }

acloc::~acloc() {std::cout << func << std::endl; }

bool
acloc::init(juce::String devname, int sampfreq, int bufsz)
{
juce::String resp;

std::cout << "acloc::init(" << devname << ", " << sampfreq << ", " << bufsz << ")" << std::endl;

SampFreq = sampfreq;
BufSz = bufsz;
AudioDevice = devname;

resp = audMgr.initialise(6,0,nullptr,false);
if (resp != "") {
    std::cout << "audMgr.initialize() failed: " << resp << std::endl;
    exit(1);    // TODO
}

audSetup = audMgr.getAudioDeviceSetup();
std::cout << "in/out: " << audSetup.inputChannels.toString(2) << "/" << audSetup.outputChannels.toString(2) << std::endl;

audSetup.inputDeviceName = devname;
audSetup.useDefaultInputChannels = false;
audSetup.outputDeviceName = "";
audSetup.useDefaultOutputChannels = false;
audSetup.bufferSize = bufsz;
audSetup.sampleRate = sampfreq;
resp = audMgr.setAudioDeviceSetup(audSetup, true);
if (resp != "") {
    std::cout << "audMgr.setAudioDeviceSetup() failed: " << resp << std::endl;
    exit(1);    // TODO
}
std::cout << "in/out: " << audSetup.inputChannels.toString(2) << "/" << audSetup.outputChannels.toString(2) << std::endl;

//audMgr.addAudioCallback(acloc::AudioIODeviceCallback);  ????

return(true);

}

void
acloc::audioDeviceAboutToStart (juce::AudioIODevice*) { std::cout << func << std::endl; }

void
acloc::audioDeviceStopped() { std::cout << func << std::endl; }

void
acloc::audioDeviceIOCallback (const float** inputChannelData, int numInputChannels,
float** outputChannelData, int numOutputChannels,
int numberOfSamples)
{
std::cout << func << std::endl;
}

With this new class, I then kick things off from Main.cpp…

class aclocApplication : public juce::JUCEApplication
{
public:
//==========================================================================
aclocApplication() {}

const juce::String getApplicationName() override       { return ProjectInfo::projectName; }
const juce::String getApplicationVersion() override    { return ProjectInfo::versionString; }
bool moreThanOneInstanceAllowed() override             { return true; }

acloc aclocmain;

//========================================================================
void initialise (const juce::String& commandLine) override
{
    // This method is where you should put your application's initialisation code..
    if (!juce::Desktop::getInstance().isHeadless()) {
        std::cout << "System is not headless" << std::endl;
        mainWindow.reset (new MainWindow (getApplicationName()));
    }
    else {
        std::cout << "System is headless" << std::endl;
    }
    aclocmain.init(MICARRAY_DEVNAME,48000,1024);
}

I can see that it does actually connect to my audio device, but once that happens how do I hook in my version of the callback to process the buffers? I assume the callbacks I need are “AboutToStart”, “DeviceStopped” and “IOCallback”. Is this even close to correct?
Again, if there is any reference documentation please don’t hesitate to point me to it.
Ed

I added

audMgr.addAudioCallback(this);

to the end of acloc::init() and now I get the callbacks…
Hopefully this is good.

Ok, looks like this works…
I put real code in the callback:

void
acloc::audioDeviceIOCallback (const float** inData, int inChTot, float** outData, int outChTot, int sampleTot)
{
float *lOut, *rOut;
const float *lIn, *rIn;

    lOut = outData[0];
    rOut = outData[1];
    lIn = inData[0];
    rIn = inData[1];

    for(int i=0;i<sampleTot;i++) {
        *lOut++ = *lIn++;
        *rOut++ = *rIn++;
    }

}

and I can confirm that audio is looped back…

@edsut
This is example of JUCE console app. Yes, it doesn’t have audioprocessing.

@ed95 @kcoul @reuk,
If interested I pushed a basic JUCE application to github that “works for me”…

Since this is my first JUCE application, I may be violating a lot of rules,
so if someone cares, please take a look and let me know…
Bottom line, I managed to get what I was asking for at the top of this thread, so
thanks to all for the input…