Christian Gröger wrote:
Hey,
thanks for this, I just tried it, it works (kind of)...
Thank _you_ for trying it out!
- Install my branch of Asterisk that contains app_jack.
$ svn co http://svn.digium.com/svn/asterisk/team/russell/jack asterisk-jack $ cd asterisk-jack $ ./configure && make $ sudo make install
The jack interface is in apps/app_jack.c in case anyone cares.
There was the first problem, app_jack somehow didn't build without any errors, configure said jack...h was there, but there was no app_jack.so build. I had to do a 'make menuconfig' and disable+reenable app_jack.
Hm, that's odd. The build system should automatically include it if jack was found on the system. I'll have to play around with it to see if it happens to me ...
- Make sure jackd is running. For the sake of efficiency, specify 8 kHz,
because for most codecs used for phone calls, that's all you get. Also, specify 160 frames per period. For 8 kHz audio, this comes out to 20 ms periods, which is generally the packet size used for Voice over IP.
$ sudo jackd -d dummy -r 8000 -p 160
I used 128 frames, this sounded a bit better. But I think it would be much better if app_jack would adapt to the running jack. I sometimes use jack for connecting to a firewire-soundcard and with 8KHz it's impossible to have good sound out of your speakers ;)
The short answer is that I have all intentions to make app_jack work transparently with any period size and sample rate used by jack itself.
Longer response ...
In theory, any period size should work just fine. I just happened to choose 160 because I was thinking that it would be more efficient, since that was the period size of packets coming through Asterisk. However, due to the way audio is passed between Asterisk and jack, it really shouldn't matter at all. All of the raw audio goes through ringbuffers that have no concept of a period. I will play around with different period sizes to see if I can cause a problem to occur.
Also, I have all intentions to support more than 8 kHz mode for jack. :) The trick is, with 8 kHz, app_jack doesn't have to resample anything. With any other sample rate, it does. I have code that attempts to handle resampling the audio in both directions using libresample. However, it currently makes the audio sound absolutely terrible. I'll get it fixed, though ...
- Make a call to the extension created in Asterisk in step 2. You should see
the two new jack ports become available. In theory, they are available for connection to any application that can use Jack. The only thing I have done so far is to use the "patchage" application to connect the ports directly together to verify that the audio is flowing correctly.
I tried Pd and had some strange problems (I don't know where they come from) No problem if you connect adc~ from Asterisk to dac~ on Asterisk, I hear myself with a rather extreme echo. But I can't hear a simple osc~ on the phone, neither can I hear myself on my PC-speakers when I talk into the phone.
Would you mind sharing the Pd patch that you were using to test this out?
The extreme echo is a good sign, I think. I assume you mean you just heard your own voice coming back to you, with some delay. Anything beyond that is probably acoustic echo with whatever phone you're using. :)
The reason that connecting Asterisk to itself works but not with anything else could have something to do with the way I did sample value normalization in Asterisk. Asterisk uses a 16 bit integer representation per sample. However, I had to convert it to float for jack.
I wasn't sure of the right way to do it, so I simply scaled the values based on the maximum values of the type ...
(f_buf is a buffer of floats, s_buf is a buffer of int16_t's)
for (i = 0; i < f->samples; i++) f_buf[i] = s_buf[i] * (FLT_MAX / SHRT_MAX);
Now, to figure out how to hook up arbitrary jack ports to Pd ... if anyone has any pointers, it would be much appreciated. I'm still very new to Pd. :)
You could do this in Asterisk with a System(jack_connect ...) ;) Do you think it would be possible to tell app_jack to connect to jack-server running as Pid x? Jack sometimes screws up your system when it runs as root, or other software does, because it has to run as root too. I configured my Asterisk to run as myself, but that's quite complex.
The System() option is certainly amusing. Hey, if it works, why not. I think what I want to do eventually is be able to send a message that you could receive in a Pd patch that a new pair of jack ports has become available. But, that's not as important to me right now as getting the audio flow working properly.
I don't know about adding an argument that says connect to PID X. However, there appears to be an option in the jack C API which allows you to specify a server name to connect to. That may do what is needed to connect to jackd running as a different user.
Thanks for the suggestions.
Anyway, it's cool you coded all this, thanks.
Thanks for the kind words, and for the testing! Hopefully I can get it working well and make it easy to use. I will work on incorporating your suggestions.
-- Russell Bryant
Russell Bryant wrote:
Longer response ...
In theory, any period size should work just fine. I just happened to choose 160 because I was thinking that it would be more efficient, since that was the period size of packets coming through Asterisk. However, due to the way audio is passed between Asterisk and jack, it really shouldn't matter at all. All of the raw audio goes through ringbuffers that have no concept of a period. I will play around with different period sizes to see if I can cause a problem to occur.
I heard some klicking noise when I tried with 160 frames
Also, I have all intentions to support more than 8 kHz mode for jack. :) The trick is, with 8 kHz, app_jack doesn't have to resample anything. With any other sample rate, it does. I have code that attempts to handle resampling the audio in both directions using libresample. However, it currently makes the audio sound absolutely terrible. I'll get it fixed, though ...
I tried it first with 48KHz and only got noise
Would you mind sharing the Pd patch that you were using to test this out?
The extreme echo is a good sign, I think. I assume you mean you just heard your own voice coming back to you, with some delay. Anything beyond that is probably acoustic echo with whatever phone you're using. :)
The reason that connecting Asterisk to itself works but not with anything else could have something to do with the way I did sample value normalization in Asterisk. Asterisk uses a 16 bit integer representation per sample. However, I had to convert it to float for jack.
I wasn't sure of the right way to do it, so I simply scaled the values based on the maximum values of the type ...
(f_buf is a buffer of floats, s_buf is a buffer of int16_t's)
for (i = 0; i < f->samples; i++) f_buf[i] = s_buf[i] * (FLT_MAX / SHRT_MAX);
A really long delay, but that may was because of my setup... (ISDN <-> Asterisk <-> IAX over Wlan <-> Asterisk with Jack) ;)
Pd patch was a really simple [adc~ 1] for audio input from the first jack-channel, a [osc~ 440] for testing and a [dac~ 1] for audio output to the first jack-channel
When I connected the osc~ with the dac~ I heard nothing at my phone, when I connected the adc~ from asterisk to a dac~ patched to alsa I neither heard a thing from the phone.
what I want to do eventually is be able to send a message that you could receive in a Pd patch that a new pair of jack ports has become available. But, that's not as important to me right now as getting the audio flow working properly.
I don't know about adding an argument that says connect to PID X. However, there appears to be an option in the jack C API which allows you to specify a server name to connect to. That may do what is needed to connect to jackd running as a different user.
I don't know if you can patch two jack-channels together in pd, telling app_jack to connect it's channel to a specific pd-channel would be really easy, but having Pd handling it would be more flexible. Anyway, sending something to pd, that there's a new caller definitely is a good idea for various reasons.
--Chris
Chris wrote:
I tried it first with 48KHz and only got noise
I'm surprised it didn't just crash, actually. :)
I have made a lot of fixes to the resampling code. I think it works now, but haven't been able to test since my last set of changes.
A really long delay, but that may was because of my setup... (ISDN <-> Asterisk <-> IAX over Wlan <-> Asterisk with Jack) ;)
Ha, yes, there is a little bit of noticeable delay in that setup ...
Pd patch was a really simple [adc~ 1] for audio input from the first jack-channel, a [osc~ 440] for testing and a [dac~ 1] for audio output to the first jack-channel
When I connected the osc~ with the dac~ I heard nothing at my phone, when I connected the adc~ from asterisk to a dac~ patched to alsa I neither heard a thing from the phone.
Oh, alright. That makes sense...
I don't know if you can patch two jack-channels together in pd, telling app_jack to connect it's channel to a specific pd-channel would be really easy, but having Pd handling it would be more flexible. Anyway, sending something to pd, that there's a new caller definitely is a good idea for various reasons.
Thanks for the feedback. Adding a feature to app_jack such that you can not just create the ports, but have them connected to some other jack ports sounds like a reasonable feature to add. Like you said, having more control over connecting jack ports via Pd sounds more flexible, but that will take me some more time to figure out. :)
Thanks again for the feedback. It is very much appreciated.
-- Russell
Hi, app_jack doesn't compile...
[CC] app_jack.c -> app_jack.o app_jack.c: In function ‘handle_input’: app_jack.c:221: error: ‘FLT_MAX’ undeclared (first use in this function) app_jack.c:221: error: (Each undeclared identifier is reported only once app_jack.c:221: error: for each function it appears in.) app_jack.c: In function ‘queue_voice_frame’: app_jack.c:411: error: ‘FLT_MAX’ undeclared (first use in this function) make[1]: *** [app_jack.o] Error 1
So long, Chris
Russell Bryant schrieb:
Chris wrote:
I tried it first with 48KHz and only got noise
I'm surprised it didn't just crash, actually. :)
I have made a lot of fixes to the resampling code. I think it works now, but haven't been able to test since my last set of changes.
A really long delay, but that may was because of my setup... (ISDN <-> Asterisk <-> IAX over Wlan <-> Asterisk with Jack) ;)
Ha, yes, there is a little bit of noticeable delay in that setup ...
Pd patch was a really simple [adc~ 1] for audio input from the first jack-channel, a [osc~ 440] for testing and a [dac~ 1] for audio output to the first jack-channel
When I connected the osc~ with the dac~ I heard nothing at my phone, when I connected the adc~ from asterisk to a dac~ patched to alsa I neither heard a thing from the phone.
Oh, alright. That makes sense...
I don't know if you can patch two jack-channels together in pd, telling app_jack to connect it's channel to a specific pd-channel would be really easy, but having Pd handling it would be more flexible. Anyway, sending something to pd, that there's a new caller definitely is a good idea for various reasons.
Thanks for the feedback. Adding a feature to app_jack such that you can not just create the ports, but have them connected to some other jack ports sounds like a reasonable feature to add. Like you said, having more control over connecting jack ports via Pd sounds more flexible, but that will take me some more time to figure out. :)
Thanks again for the feedback. It is very much appreciated.
-- Russell
Chris wrote:
Hi, app_jack doesn't compile...
[CC] app_jack.c -> app_jack.o app_jack.c: In function ‘handle_input’: app_jack.c:221: error: ‘FLT_MAX’ undeclared (first use in this function) app_jack.c:221: error: (Each undeclared identifier is reported only once app_jack.c:221: error: for each function it appears in.) app_jack.c: In function ‘queue_voice_frame’: app_jack.c:411: error: ‘FLT_MAX’ undeclared (first use in this function) make[1]: *** [app_jack.o] Error 1
Fixed ... I broke it when I fixed it for compiling on mac. Oops. :)
-- Russell
I tried it again,
I had problems again with compiling. app_jack.c didn't find libresample.h, so I copied that file to include/asterisk.
Well, there are still the same problems with it, weird noise when jack is running with 48kHz and still no sound from Pd in my phone.
Russell Bryant wrote:
Chris wrote:
Hi, app_jack doesn't compile...
[CC] app_jack.c -> app_jack.o app_jack.c: In function ‘handle_input’: app_jack.c:221: error: ‘FLT_MAX’ undeclared (first use in this function) app_jack.c:221: error: (Each undeclared identifier is reported only once app_jack.c:221: error: for each function it appears in.) app_jack.c: In function ‘queue_voice_frame’: app_jack.c:411: error: ‘FLT_MAX’ undeclared (first use in this function) make[1]: *** [app_jack.o] Error 1
Fixed ... I broke it when I fixed it for compiling on mac. Oops. :)
-- Russell
PD-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Chris wrote:
I had problems again with compiling. app_jack.c didn't find libresample.h, so I copied that file to include/asterisk.
Sorry about that, libresample got moved around the source tree about 4 times in the past day, and it kept breaking my branch. :)
Well, there are still the same problems with it, weird noise when jack is running with 48kHz and still no sound from Pd in my phone.
I just fixed the audio from Pd to the phone issue. I am able to connect an echo of myself through I am now able hook up a simple [osc~ 440] -> [*~ 0.1] -> [dac~] and hear it just fine (with jackd running in 8 kHz mode).
Now, I'm going to keep working on the resampling part to find where I went wrong with it.
As always, thank you for the feedback!
-- Russell
Russell Bryant wrote:
Chris wrote:
Well, there are still the same problems with it, weird noise when jack is running with 48kHz and still no sound from Pd in my phone.
I just fixed the audio from Pd to the phone issue. I am able to connect an echo of myself through I am now able hook up a simple [osc~ 440] -> [*~ 0.1] -> [dac~] and hear it just fine (with jackd running in 8 kHz mode).
Now, I'm going to keep working on the resampling part to find where I went wrong with it.
And I think I just fixed the resampling issues, as well. I just tested it with jackd running 8 kHz, 16 kHz, and 48 kHz modes and all of them worked fine. Yay, I hope. :)
-- Russell Bryant