Closed jsl303 closed 2 years ago
No, I wasn't even aware that such an API exists!
Do you want to implement it?
Unfortunately beyond my head...
I found this jack_control
in the documentation of the Website Repo. Also never heard about or used it.
https://github.com/jackaudio/jackaudio.github.com/wiki/WalkThrough_User_jack_control
Maybe the tool is long gone and not maintained anymore. However, there might be code left that is worth checking out. Maybe it can be "revived" for the specific features you are interested in.
Is jack_control supposed to come with Jack?
I'm on MacOS, and I don't see jack_control in my system unfortunately.
https://github.com/jackaudio/jack2/blob/develop/example-clients/jack_control
Fount this. So it still seems to exist in the current code base. And apparently even Python 3. However, the file has no .py
ending. The implementation of the command line parameter parsing is done by hand ... by manually iterating over the parameters. I mean it looks awful, but maybe it's not better with argparse
. I kind of doubt that tho. Probably just a very old implementation that nobody really cares to improve.
However, it might provide exactly the functionality you want. Let is know if you were successful or have problems making it work.
Is jack_control supposed to come with Jack?
On my Debian Linux system it's included with the JACK package.
If I understand correctly, the jack_control
script doesn't actually use the "control API" mentioned above, but it uses dbus, right?
I just had a quick look and it looks like in the JACK1 repo there are Python bindings for the "jackctl" API: https://github.com/jackaudio/jack1/blob/master/python/jackctl.py
Be that as it may, we can try to implement the control API in jackclient-python anyway.
@jsl303 Which functions do you actually need? Which ones do you think are nice to have? Which are useless in our case?
I think essentials features to start are:
Choose buffer size
Choose sampling rate
List and choose back ends (coreaudio, dummy, and so on)
List supported devices for a particular backend
Choose device to use as input
Choose device as output
start/Stop jackd server
It is possible to set the buffer size of instantiated JACK clients with this API (see property below). This can be done before actually starting the client, so no adaptation is required. Doing this for a client will update this setting for the entire jackd server and other clients. Is that correct @mgeier ? https://github.com/spatialaudio/jackclient-python/blob/0151633118518a6b9bae406d1b66428b085e23f7/src/jack.py#L263
However, the option above is only available to the buffer size and not the sampling rate for example. Hence, a proper API to administrate jackd might be desirable. This should also provide to not only set, but also receive information on the parameters and status of the server of course.
Also, one should always keep in mind that it is possible to run multiple jackd servers at a time, right? I have no idea what viable use cases are or if this actually utilized by someone. However, a server API should definitely support that, I guess.
Doing this for a client will update this setting for the entire jackd server and other clients. Is that correct @mgeier ?
I'm not sure, but I think so.
Here's the call to jack_set_buffer_size()
:
I've never actually used this, though, so I don't know if that works in practice.
However, the option above is only available to the buffer size and not the sampling rate for example.
Yes, it looks like that. There seems to be only jack_get_sample_rate()
but no jack_set_sample_rate()
: https://jackaudio.org/api/group__ServerControl.html
The sample rate can change, though, at least theoretically, because there is jack_set_sample_rate_callback()
, which is available as Client.set_samplerate_callback()
.
Also, one should always keep in mind that it is possible to run multiple jackd servers at a time, right?
Yes, I think so. I have never used multiple servers, though.
But there has been an issue with multiple servers: #46.
It looks like jackctl_server_create()
has been deprecated in JACK2 (in favor of jackctl_server_create2()
):
Did anyone of you try https://github.com/jackaudio/jack1/blob/master/python/jackctl.py?
I'm unable to create a jackctl.Server
object because of many errors similar to this:
Could not open component .so '/usr/lib/x86_64-linux-gnu/jack/jack_alsa.so': /usr/lib/x86_64-linux-gnu/jack/jack_alsa.so: undefined symbol: _ZTIN4Jack15JackAudioDriverE
Could not open component .so '/usr/lib/x86_64-linux-gnu/jack/jack_alsa.so': /usr/lib/x86_64-linux-gnu/jack/jack_alsa.so: undefined symbol: _ZTIN4Jack15JackAudioDriverE
jack_get_descriptor : dll jack_alsa.so is not a driver
jack_get_descriptor returns null for 'jack_alsa.so'
When I try to manually call jackctl_server_create()
/jackctl_server_create2()
(using CFFI instead of ctypes
), I get the same errors.
Apart from these problems, it's a bit strange to include this in the jackclient-python project, because:
libjackserver.so
(instead of libjack.so
)It would probably be better to create a separate project for this?
Did anyone of you try https://github.com/jackaudio/jack1/blob/master/python/jackctl.py?
No.
Apart from these problems, it's a bit strange to include this in the jackclient-python project, because:
* it's not a "client" * it needs a separate library named `libjackserver.so` (instead of `libjack.so`)
It would probably be better to create a separate project for this?
Totally.
I wrote this simple wrapper API for the jack_control
module to allow it to be imported and run from Python. It may be useful to someone. To the extent that the jack_control
script works and is maintained, this gives you the same commands. It's a little ugly (to work around the fact that the main()
function in jack_control
always looks at sys.argv
and writes to sys.stdout
), but should be reliable.
"""
Run the jack_control program, with source code linked below, from Python.
https://github.com/jackaudio/jack2/blob/develop/tools/jack_control
"""
import sys
import io
import jack_control as jc # Must be in `sys.path` list with `.py` extension.
class FakeSys:
pass
jc.sys = FakeSys # Override the `sys` module that was imported in jc.
def jack_control(*args):
"""Run `jack_control` as if it were called from the command-line with the
parameter strings as command-line arguments. Returns the exit code and
the string that would have been written to stdout."""
args = [str(a) for a in args] # Convert any ints which were passed in.
jc.sys.argv = ["jack_control"] + args
old_sys_stdout = sys.stdout
sys.stdout = io.StringIO()
retcode = jc.main() # Call the real `jack_control` function.
msg = sys.stdout.getvalue()
sys.stdout = old_sys_stdout
return retcode, msg
# Test.
if __name__ == "__main__":
exit_code, msg = jack_control("help") # Get help message.
print(msg) # Print the help message (redirected from stdout).
# Toggle start/stop state.
status_code, msg = jack_control("status")
if status_code == 0:
jack_control("stop")
else:
jack_control("start")
print("Status msg is:\n", msg)
# Get the long description for the engine parameter "driver".
exit_code, msg = jack_control("epd", "driver")
print(msg)
# Set the "rate" parameter.
exit_code, msg = jack_control("dps", "rate", 44100)
print("Rate set exit code was:", exit_code)
print("Rate set msg:\n", msg, sep="")
I agree to @jsl303 it would be so nice if we could control sampling rate, buffer size, and so on from this python layer. : )
I think it would be better to have this functionality in a separate module (in a separate project) because this is done by a different library (see https://github.com/spatialaudio/jackclient-python/issues/90#issuecomment-671547742).
@takanoha001 Do you want to start such a project?
Hey there! I created a package to control JACK server with Python. It uses Jack Control API and is kind of modern replacement for jackctl
.
@jsl303 @mgeier @abarker @HaHeho @takanoha001 Check it out guys! https://github.com/vrslev/jack_server
Cool @vrslev, I've added a link to the docs: #114.
I guess we can close this issue now?
Amazing, thanks! I plan to maintain that package, so probably yes.
@mgeier Should the issue be closed?
Yes, I think this can be closed.
If there are further questions or suggestions, everyone should feel free to add a comment here or create a new issue.
However, the option above is only available to the buffer size and not the sampling rate for example.
Yes, it looks like that. There seems to be only
jack_get_sample_rate()
but nojack_set_sample_rate()
: https://jackaudio.org/api/group__ServerControl.html
FTR, in JACK implementation by Pipewire there is a jack_set_sample_rate
function since 0.3.84 release
Is there python binding for API to start and control a JACK server? https://jackaudio.org/api/group__ControlAPI.html I wasn't able to find them in the documentation. I'd love to control how it starts the server like setting inputs and outputs, sampling rate, and so on.