[Jack-Devel] How to use jackd as a 'system-wide' server?

classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|

[Jack-Devel] How to use jackd as a 'system-wide' server?

Christophe Lohr
Hello,
  I'm looking for some advices for configuring my system.

I plan to use the Jack plugin for the Asterisk PBX
https://blog.russellbryant.net/2008/01/13/jack-interfaces-for-asterisk/
https://wiki.asterisk.org/wiki/display/AST/Asterisk+12+Application_JACK

Since Asterisk is started as a daemon by systemd, I guess that I should
also start Jackd as a system-wide server, and not within a user
graphical session.
In such a case, jackd does not rely on dbus, isn't it?

So, how does jack clients may reach the jackd server?
Is there some well known entry point, or discovering mechanisms (without
dbus)?

I'm lost. Any explanations are welcome ;-)

Best regards
Christophe

_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Joakim Hernberg-2
I think you'd need to run the jackd server in promiscuous mode.  IIRC
that is broken on jack2, but worked last time I tried it with jack1.

Here is a unit file I wrote a long time ago to run it on archlinux:

cat /etc/systemd/system/jackd.service
[Unit]
Description=Start the JACK server in promiscuous mode

[Service]
Type=simple
Environment="JACK_PROMISCUOUS_SERVER="
UMask=0
ExecStart=/usr/bin/jackd -P80 -p512 -t5000 -dalsa -dhw:DSP -r44100 -p128 -n2 -i18 -o18 -I47 -O48

[Install]
WantedBy=multi-user.target


Note that you'll have to set the JACK_PROMISCUOUS_SERVER environment
variable in your user login shell too for the client libs to find the
server.

On Wed, 9 May 2018 11:16:21 +0200
Christophe Lohr <[hidden email]> wrote:

> Hello,
>   I'm looking for some advices for configuring my system.
>
> I plan to use the Jack plugin for the Asterisk PBX
> https://blog.russellbryant.net/2008/01/13/jack-interfaces-for-asterisk/
> https://wiki.asterisk.org/wiki/display/AST/Asterisk+12+Application_JACK
>
> Since Asterisk is started as a daemon by systemd, I guess that I
> should also start Jackd as a system-wide server, and not within a user
> graphical session.
> In such a case, jackd does not rely on dbus, isn't it?
>
> So, how does jack clients may reach the jackd server?
> Is there some well known entry point, or discovering mechanisms
> (without dbus)?
>
> I'm lost. Any explanations are welcome ;-)
>
> Best regards
> Christophe
>
> _______________________________________________
> Jack-Devel mailing list
> [hidden email]
> http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org



--

   Joakim
_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Thomas Brand
In reply to this post by Christophe Lohr
On Wed, May 9, 2018 12:16, Christophe Lohr wrote:

> Hello,
>   I'm looking for some advices for configuring my system.
>
>
> I plan to use the Jack plugin for the Asterisk PBX
> https://blog.russellbryant.net/2008/01/13/jack-interfaces-for-asterisk/
> https://wiki.asterisk.org/wiki/display/AST/Asterisk+12+Application_JACK
>
>
> Since Asterisk is started as a daemon by systemd, I guess that I should
> also start Jackd as a system-wide server, and not within a user graphical
> session. In such a case, jackd does not rely on dbus, isn't it?
>
>
> So, how does jack clients may reach the jackd server?
> Is there some well known entry point, or discovering mechanisms (without
> dbus)?
>
> I'm lost. Any explanations are welcome ;-)
>

You can start jackd early in the boot process *without* DBUS device
reservation etc. You should not start it as root but as the user that will
start clients in it. Root can start a screen session as the target user
and then feed the jackd command to it.

Greetings
Thomas


_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Thomas Brand
In reply to this post by Christophe Lohr
 So, how does jack clients may reach the jackd server?
> Is there some well known entry point, or discovering mechanisms (without
> dbus)?

If jackd is running with default settings, discovery is done by simply
looking for a JACK server named "default".

Greetings
Thomas

_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Chris Caudle
In reply to this post by Christophe Lohr
On Wed, May 9, 2018 4:16 am, Christophe Lohr wrote:
> I plan to use the Jack plugin for the Asterisk PBX

> Since Asterisk is started as a daemon by systemd, I guess that I should
> also start Jackd as a system-wide server, and not within a user
> graphical session.

What user account is used for the asterisk server?  Probably jackd should
be started under the same user.

> In such a case, jackd does not rely on dbus, isn't it?

You may need to compile jackd yourself, I think many distributions which
ship jack2 enable dbus support in the build shipped by the distribution.
There was a thread on the mailing list in the past where someone posted a
way to "fake" some of the dbus information required to get jackd with dbus
support running without a graphical session started, you could search for
that, but probably just compiling without dbus support enabled would be
more straight forward.

--
Chris Caudle


_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Thomas Brand
On Wed, May 9, 2018 17:00, Chris Caudle wrote:

> On Wed, May 9, 2018 4:16 am, Christophe Lohr wrote:
>
>> I plan to use the Jack plugin for the Asterisk PBX
>>
>
>> Since Asterisk is started as a daemon by systemd, I guess that I should
>>  also start Jackd as a system-wide server, and not within a user
>> graphical session.
>
> What user account is used for the asterisk server?  Probably jackd should
>  be started under the same user.
>
>> In such a case, jackd does not rely on dbus, isn't it?
>>
>
> You may need to compile jackd yourself, I think many distributions which
> ship jack2 enable dbus support in the build shipped by the distribution.
> There was a thread on the mailing list in the past where someone posted a
>  way to "fake" some of the dbus information required to get jackd with
> dbus support running without a graphical session started, you could search
> for that, but probably just compiling without dbus support enabled would
> be more straight forward.
>

It's all in the manpage.. search for $JACK_NO_AUDIO_RESERVATION and
$JACK_PROMISCUOUS_SERVER respectively.

Greetings




_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Christophe Lohr
Many thanks all four your advices.
I start jackd in promisuous mode.

I created a Unix group named 'jack-access', with all participants for
the task (including the asterisk user)
I set  JACK_PROMISCUOUS_SERVER=jack-access  everywhere (including within
the systemd script for asterisk)
I can check that this environment variable is really set via  
/proc/<asterisk pid>/environ
All participants are able to execute  jack_mixer
So all participants are able to reach the jackd server.

Unfortunately I still have errors when I place a call to this asterisk
channel:
    ../..
    -- Executing [6000@default:5] JACK("SIP/6007-00000003", "") in new stack
[May 10 13:34:25] NOTICE[2899][C-00000003]: app_jack.c:192
log_jack_status: Client Open Status: Failure, Server Error
  == Spawn extension (default, 6000, 5) exited non-zero on
'SIP/6007-00000003'
  ../..

How can I get more log messages from the jackd server?

Best regards
Christophe


_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Chris Caudle
On Thu, May 10, 2018 8:50 am, Christophe Lohr wrote:
> How can I get more log messages from the jackd server?

You can try starting jackd from a shell so that you can capture any error
messages.

Are you sure that jackd is starting and running properly from your init
script or systemd file?  Can you start any other applications that
communicate with jackd, such as the command line utilities (jack_lsp,
jack_connect, etc.)?

--
Chris Caudle


_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Ruslan N. Marchenko
In reply to this post by Christophe Lohr
Am Donnerstag, den 10.05.2018, 15:50 +0200 schrieb Christophe Lohr:

>
> Unfortunately I still have errors when I place a call to this
> asterisk
> channel:
>     ../..
>     -- Executing [6000@default:5] JACK("SIP/6007-00000003", "") in
> new stack
> [May 10 13:34:25] NOTICE[2899][C-00000003]: app_jack.c:192
> log_jack_status: Client Open Status: Failure, Server Error
>   == Spawn extension (default, 6000, 5) exited non-zero on
> 'SIP/6007-00000003'
>   ../..
>
> How can I get more log messages from the jackd server?
>
Long time ago I was using Jack2 as a system-wide service on HTPC
running Ubuntu using following upstart script
////
start on runlevel [2345] or local-filesystems
stop on runlevel [!2345]
emits audio-bus

console log

env HOME=/root

pre-start script
if [ ! -f /run/dbus/.env ]; then
  eval `dbus-launch --auto-syntax`
  echo "export DBUS_SESSION_BUS_PID=$DBUS_SESSION_BUS_PID" >
/run/dbus/.env
  echo "export DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS" >>
/run/dbus/.env
  chmod 600 /run/dbus/.env
fi
end script

post-start script
. /run/dbus/.env
jack_control start
if [ -f /etc/default/jackd ]; then
  awk '/^[esdri]/{system("jack_control "$0)}' /etc/default/jackd
  awk '/^ /{system("jack_load "$0)}' /etc/default/jackd
  awk '/^>/{  
        system("jack_connect "$2":capture_1 "$3":playback_1");
        system("jack_connect "$2":capture_2 "$3":playback_2");
  }' /etc/default/jackd
fi
end script

post-stop script
. /run/dbus/.env
if [ -f /etc/default/jackd ]; then
  awk '/^ /{system("jack_unload "$1)}' /etc/default/jackd
fi
jack_control exit
end script
\\\\
upstart is now a history but the principle should be the same I guess.
systemd allows you even to have user-level session initiation, so
should be much mroe flexible in this regard.

The key point back then was /run/dbus/.env - that one allowed me to
join same DBus session where JackDBus was spawned.

Then each application which was going to use Jack should be started
with .env file loaded populating the environment variables.

You can ignore /etc/default/jackd - that one was my custom recipe file
which pre-loaded required modules and made required connections at the
early start.
_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Christophe Lohr
In reply to this post by Chris Caudle
Le 11/05/2018 à 17:26, Chris Caudle a écrit :
> You can try starting jackd from a shell so that you can capture any error
> messages.
>
> Are you sure that jackd is starting and running properly from your init
> script or systemd file?  Can you start any other applications that
> communicate with jackd, such as the command line utilities (jack_lsp,
> jack_connect, etc.)?

After a system reboot, I get some advances. (systemd includes too much
sorcery for me)

Now I can execute jack_evmon in another terminal and see activity of the
jackd server:
$ jack_evmon
Graph reordered
Client SIP/6007-00000000 registered
Graph reordered
Graph reordered
Port 5 registered
Port 6 registered
Graph reordered
Graph reordered
Port 5 unregistered
Port 6 unregistered
Graph reordered
Client SIP/6007-00000000 unregistered
Graph reordered


Unfortunately there are still (other) errors in the asterisk console:
    -- Executing [6000@default:5] JACK("SIP/6007-00000000", "") in new stack
[May 11 20:30:00] WARNING[30222][C-00000000]: app_jack.c:600
queue_voice_frame: Tried to write 3844 bytes to the ringbuffer, but only
wrote 1679
[May 11 20:30:00] WARNING[30222][C-00000000]: app_jack.c:600
queue_voice_frame: Tried to write 3844 bytes to the ringbuffer, but only
wrote 0
[May 11 20:30:00] WARNING[30222][C-00000000]: app_jack.c:600
queue_voice_frame: Tried to write 3844 bytes to the ringbuffer, but only
wrote 0
../..
[May 11 20:30:10] WARNING[30222][C-00000000]: app_jack.c:600
queue_voice_frame: Tried to write 3844 bytes to the ringbuffer, but only
wrote 0
    -- Unregistered SIP '6007'



Indeed, I have no audio in the phone.
There are probably other issues elsewhere in my system...
The adventure goes on!

Best regards
Christophe





_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Christophe Lohr
In reply to this post by Ruslan N. Marchenko
Le 11/05/2018 à 22:02, Ruslan N. Marchenko a écrit :

> pre-start script
> if [ ! -f /run/dbus/.env ]; then
>   eval `dbus-launch --auto-syntax`
>   echo "export DBUS_SESSION_BUS_PID=$DBUS_SESSION_BUS_PID" >
> /run/dbus/.env
>   echo "export DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS" >>
> /run/dbus/.env
>   chmod 600 /run/dbus/.env
> fi
> end script
../..
> The key point back then was /run/dbus/.env - that one allowed me to
> join same DBus session where JackDBus was spawned.
>
> Then each application which was going to use Jack should be started
> with .env file loaded populating the environment variables.

Thankyou for the trick!

Best regards
Christophe

_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Chris Caudle
In reply to this post by Christophe Lohr
On Fri, May 11, 2018 3:41 pm, Christophe Lohr wrote:
> Now I can execute jack_evmon in another terminal and see activity of the
> jackd server:

Perhaps I missed it, but I don't recall seeing any information about the
arguments given to jackd.  Can you post the parameters used?

> [May 11 20:30:00] WARNING[30222][C-00000000]: app_jack.c:600
> queue_voice_frame: Tried to write 3844 bytes to the ringbuffer, but only
> wrote 1679

Are you running an RT kernel? Is it possible that the period size is just
too small and asterisk can't keep up?

I see that app_jack includes a resampler, what sample rate is asterisk
using, and what sample rate is jackd using?

The error message is here, but it is not obvious yet what controls the
length written:

        res = jack_ringbuffer_write(jack_data->output_rb, (const char *) f_buf,
f_buf_used * sizeof(float));
        if (res != (f_buf_used * sizeof(float))) {
                ast_log(LOG_WARNING, "Tried to write %d bytes to the ringbuffer, but
only wrote %d\n",
                        (int) (f_buf_used * sizeof(float)), (int) res);
}


I don't see jack_ringbuffer_write() in that same app_jack.c file and I
don't really have time to search through the other files right now.
Have you asked on the asterisk developer list?  They may have a better
idea of what often causes problems for asterisk.

--
Chris Caudle


_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Chris Caudle
On Fri, May 11, 2018 3:59 pm, Chris Caudle wrote:
> I don't see jack_ringbuffer_write() in that same app_jack.c file and I

OK, I had time to search a little.  That function is from jack, not
asterisk, but I think the asterisk code may not be using it correctly.
The jack ringbuffer.h file has this note:
return the number of bytes write, which may range from 0 to cnt

So it seems that the write() function is documented as possibly writing
less than the full data given.

There is also this function, which seems to be for getting the amount of
free space available in the ringbuffer, but I cannot see that the asterisk
code ever calls this function:

/**
 * Return the number of bytes available for writing.
 *
 * @param rb a pointer to the ringbuffer structure.
 *
 * @return the amount of free space (in bytes) available for writing.
 */
size_t jack_ringbuffer_write_space(const jack_ringbuffer_t *rb);


In short, I think this is a bug in the asterisk implementation.  It should
be checking how much free space is available and only attempting to write
that, or  should just deal with write() not writing the full amount of
data and calling write() again later to finish writing all the data.

--
Chris C


_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Thomas Brand
In reply to this post by Christophe Lohr
On Fri, May 11, 2018 23:41, Christophe Lohr wrote:

>
> Unfortunately there are still (other) errors in the asterisk console:
>     -- Executing [6000@default:5] JACK("SIP/6007-00000000", "") in new
> stack [May 11 20:30:00] WARNING[30222][C-00000000]: app_jack.c:600
> queue_voice_frame: Tried to write 3844 bytes to the ringbuffer, but only
> wrote 1679 [May 11 20:30:00] WARNING[30222][C-00000000]: app_jack.c:600
> queue_voice_frame: Tried to write 3844 bytes to the ringbuffer, but only
> wrote 0 [May 11 20:30:00] WARNING[30222][C-00000000]: app_jack.c:600
> queue_voice_frame: Tried to write 3844 bytes to the ringbuffer, but only
> wrote 0 ../..
> [May 11 20:30:10] WARNING[30222][C-00000000]: app_jack.c:600
> queue_voice_frame: Tried to write 3844 bytes to the ringbuffer, but only
> wrote 0     -- Unregistered SIP '6007'

This is just a warning. If you'd check the available size before writing
the result would be the same.

Why the ringbuffer has not enough write space can have several reasons
from logic errors to random other reasons.

However you could simply enlarge the ringbuffer capacity and see if the
warning still appears.

in app_jack.c:

/* The number of frames the ringbuffers can store. The actual size is
RINGBUFFER_FRAME_CAPACITY * jack_data->frame_datalen */
#define RINGBUFFER_FRAME_CAPACITY 100

set this to 1000 just for a test and re-compile.

Greetings
Thomas



_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Thomas Brand
In reply to this post by Chris Caudle
> On Fri, May 11, 2018 3:59 pm, Chris Caudle wrote:
> In short, I think this is a bug in the asterisk implementation.  It
> should be checking how much free space is available and only attempting to
> write that, or  should just deal with write() not writing the full amount
> of data and calling write() again later to finish writing all the data.

Not writing the full amount of data won't be a solution, it just hides the
warning.

Writing it later seems to be no solution since the data is "gone" once the
function returns.

The ringbuffer actually solves this by providing that storage between
functions/threads. It just has to be big enough and read out at a rate
that will allow for more input data in time.

Greetings
Thomas

_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Christophe Lohr
In reply to this post by Thomas Brand
Le 12/05/2018 à 14:41, Thomas Brand a écrit :

> However you could simply enlarge the ringbuffer capacity and see if the
> warning still appears.
>
> in app_jack.c:
>
> /* The number of frames the ringbuffers can store. The actual size is
> RINGBUFFER_FRAME_CAPACITY * jack_data->frame_datalen */
> #define RINGBUFFER_FRAME_CAPACITY 100
>
> set this to 1000 just for a test and re-compile.

Nice shot! Tested and approved
I have no more those warning messages
... well, I still don't have sound in my headphone, maybe due to issues
in my app plugged at the other side of jack... ;-)

Best regards
Christophe
 

_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Christophe Lohr
In reply to this post by Chris Caudle
Le 16/05/2018 à 22:45, Chris Caudle a écrit :
> I would set to the same sample rate that asterisk expects so that no
> rate conversion is needed.

Well, in fact Asterisk does not expect a specific sample rate. This
depends of the codecs that have been negotiated with the peer for the
ongoing call...
By default, the sip trunk uses  ilbc g729 gsm g723 ulaw codecs. The
sampling rate can be 8kHz, 16kHz, or 13.3...
Maybe I can tell jack to use 16kHz sampling rate, and let it convert
when needed.


>> Linux xaal-c 4.15.17-1-MANJARO #1 SMP PREEMPT Thu Apr 12 17:29:48 UTC
>> 2018 x86_64 GNU/Linux
> That has the low-latency configuration set (PREEMPT), but not the full
> realtime patch (that would show PREEMPT-RT).  Should be fine for most use,
> but you may not be able to set to the very lowest latency settings. The
> dummy backend uses 1024 sample period size by default.

The use-case is about voice calls. Humans are rather tolerant about the
latency of a phone call. isn't it?

> What app do you have connected?

The app is the speech-to-text Pocketsphinx (the code is slightly
modified for my needs)
Pocketsphinx uses pulseaudio as audio interface. So I need its jack
source/sink plugin.

So, there is no physical audio device in my system: the audio of the
caller is to be passed to the STT recognition system via the audio server.


Best regards
Christophe

_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org
Reply | Threaded
Open this post in threaded view
|

Re: How to use jackd as a 'system-wide' server?

Chris Caudle
On Thu, May 17, 2018 2:03 am, Christophe Lohr wrote:
> Maybe I can tell jack to use 16kHz sampling rate, and let it convert
> when needed.

Jack does no sample rate conversion, all ports always run at the sample
rate specified when jackd was started, but the comments in the asterisk
module indicated that asterisk would convert rates if needed.  I did not
check to see if it was using one of the resampling libraries commonly used
on linux, but I would assume that audio quality and constant latency is
much less of an issue for telephony, so changing over to a more modern
resampler with higher quality e.g. zita-resampler would not really be
worth the effort.

> The use-case is about voice calls. Humans are rather tolerant about the
> latency of a phone call. isn't it?

I would say yes up to a point, but 1024 sample buffer is very far under
that point.  As long as you get no over or under runs with the PREEMPT
kernel you probably will not have a need to use a full RT patch.

>> What app do you have connected?
>
> The app is the speech-to-text Pocketsphinx (the code is slightly
> modified for my needs)
> Pocketsphinx uses pulseaudio as audio interface. So I need its jack
> source/sink plugin.

OK, that is a little convoluted with all the different matching interfaces
required, but is actually a good use case for jackd and the dummy backend.

--
Chris Caudle


_______________________________________________
Jack-Devel mailing list
[hidden email]
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org