Hi everyone,
As a word beforehand: I am a somewhat experienced C++ programmer but brand
new to developing with Jack.
I'm somewhat experienced in Using Jack audio tho.
I am rather ambitious and don't want to make stupid beginners mistakes so I
often ask super basic (some times really dumb) questions.
I will briefly talk about my current project so you maybe can suggest
something better or understand my thoughts better.
I'm pretty shure most of you guys have heard of automation tools like
autohotkey or something similar. I want to build such an automation tool
but tailored for midi devices instead of keyboards.
I want to have the ability to read information from a config file what so
ever. Actually thinking about a config script of sorts, instead of
json/yaml/toml files. (that's not the point tho)
I also want to be able to process multiple midi controllers with one
instance like autohotkey can have multiple instances running and supports
multiple scripts per instance.
I want to be able to register callbacks from the scripting engine that are
called if a message is received.
I want to support multiple instances of the same device (in my example I
use novation Launchpads).
I want to be able to have a function setup the device. For example change
modes or setup basic elements or ensure the device will have the right
firmware version for the script. (if the device supports it)
I want the Program to appear as one Jack client with one input and one
Output per midi device and optionally stereo outputs per Device.
Now I want to talk about my thoughts about the structure of my program:
First of all I will be working with C++14 or C++17. And want to get it
working at all before making it multithreaded and efficient.
I have some kind of main Class that is responsible for reading the main
config file/script and creates a vector of Device Objects.
I will call this main Class DeviceManager.
The device manager will run the main process function of jack.
It will receive midi events from all devices and will pass a vector of
vectors with raw midi data to the process function per device.
The Device object keeps a registry of callbacks and will call them from its
process function.
If I want to Send midi data or audio data to the Hardware it will push
vectors of raw midi data onto a queue and the process function will flush
the queue of one device per call.
I will have to implement my own midi clock per device (that controls the
blink and fade speed on the launchpad. It may be useful on other
controllers too.)
Now my real questions:
Would it be better to have the Device manager pass a reference to the
Devices and run every Device in its own thread with its own process
function?
How would I check if a external jack port exists? So it can wait until for
example a device is plugged in and comes up or a program is started.
What is the most effective way to send larger amounts of midi data?
Is there a good C++ wrapper around jack that would save me some work? I
already know about juice but I deemed it to big for the things I would use
it for.
Best regards Stefan Schmelz