gtkIOStream is a versatile software for signal processing and audio processing, amongst other features (such as GUI programming). It interfaces directly with jackd for low latency audio processing and routing. gtkIOStream also provides a nice port monitor interface which shows which jackd ports are in use and how (similar to the qjackctl connect GUI but different).

In this tutorial we will focus on full duplex streaming using jackd. Full duplex is a term given to both audio output and audio input (half duplex means either output or input). This tutorial will also introduce how to start jackd, the JackPortMonitorGui application and show you the playback and capture mixers settings required for the Audio Injector stereo cards to get input and output audio working so that you can hear something on the input at the output of your hardware.

Before we start, you have to have compiled and installed gtkIOStream. For certain components of gtkIOStream its compilation and installation isn't necessary, but for certain parts of audio processing it is necessary. Tutorial 0 and contents guides you through how to install and test the installation of gtkIOStream. Before you start this tutorial, you must have it installed first.

Lets step through the code in order of execution.
We start with good old main, which has the standard (unused) input variables argc and argv. The first thing main does is instantiate our jackd client JackFullDuplex :

Here you will see the JackClient.H file which defines our JackClient. You will also notice that we include iostream and unistd for console output (cout, endl, etc.) and the call to the function sleep respectively.

Next we define our JackFullDuplex class which inherits from the JackClient class :

This class method inputs the number of frames (audio samples for each channel) require processing and returns a number which indicates 0 for success and keep going, and any other number for error and stop calling this jackd client. The first thing we do is confirm that we have the same number of input and output channels (channels are ports in jackd) and if they differ, we print an error to console and return non zero to tell jackd to stop calling us.

Next, as we are a full duplex "copy" client, we take the input audio and copy it directly to the output. We loop over all of our ports (channels) :

and we acquire the output and input audio buffers for channel i using the jack_port_get_buffer function. We then loop over all the frames using the variable j and copy the input sample to the output sample.
Finally, we return 0 indicating that everything is good and we want to keep processing next time there are nframes of audio samples available :

Great ! So now you understand how to program a jackd audio client - it is that simple ! Oh ... if you don't want to use the input channels, then simply don't deal with them in the processAudio JackClient method. If you don't want to use the output channels, then simply don't deal with them in the processAudio JackClient method.

OK - what about the rest of main ? In the rest of the main function we tell our JackFullDuplex client (jackClient in the code) to connect to the jackd server :

this command should be reasonably familiar to you now, we are compiling the code (JackClient.C) and calling it JackClient.

We have to start jackd before we start our client, if you are using a Pi, you will have to have a sound card installed with audio input. You start jackd with two input and output ports (channels) like so :

Here we tell jackd to use the sample rate of 48 kHz.
If you don't have a DISPLAY env. variable, jackd will complain and not stare, so either log back in with "ssh -X" (assuming you used ssh to access your term) or declare one first :

One of the nice things about gtkIOStream is that it includes a port monitor which is available in both gui and non gui form. Make sure you "ssh -X" into your remote computer (if you are working over a network) so that you can see and execute the following GUI command :

It tells us the sample rate and block size and some information about latency - which isn't relevant here.

You will now observe that the JackPortMonitorGui app shows that the system and our client are fully connected and looks like so :

JackPortMonitorGui with our JackFullDuplex client connected.

JackPortMonitorGui.withClient.png (25.8 KiB) Viewed 5368 times

You will be able to drag and drop the buttons from the left side to the right side dropping on any buttons on the right to connect ports together. You can disconnect ports by dragging buttons from the right side to the left side dropping them on the ports you want to disconnect.

At this point you can verify that your client is working by plugging in an audio source to the input lines and playing the output lines through an amplifier or pair of headphones.

If you don't hear any audio then either your player isn't playing or your mixer isn't set up correctly. In the case of the audio injector stereo cards, your playback alsamixer should look like so :

Thank you so much for these tutorials! I have been trying for a long time to get duplex to work, but it just wont. I've tried simple ALSA scripts and recently also Jack. I hope your tutorials can finally help me reach my goal.

I have followed your tutorials on a fresh install of Raspbian with your stereo sound card.

- First I installed the sound card following your guide and made sure that ALSA works.
- Then I followed your guide in tutorial 0 and installed all the packages. I can confirm that the script in tutorial 1 works.

- Now, in tutorial 2, I get some problems. If I run the command 'JackPortMonitorGui' I get "bash: JackPortMonitorGui: command not found".
Also if I just run "jackd -d alsa -r 48000 -i 2 -o 2" and "./JackClient ", I get no errors, but there is no sound coming through.

Do I need to setup something for Jack myself? Like edit the .asoundrc file?

If nothing is installed, you should probably re-run tutorial 0 to install everything.
If JackPortMonitor is present but JackPortMonitorGui isn't then it is likely that you don't have the necessary gtk libraries installed on your system to compile the GUI components of gtkIOStream. You can see if they are installed by looking at the end of the ./configure command from tutorial 0 :

I have been using this board for the past few weeks and love it. Thanks for the in-depth tutorials.
The sample rate (jackClient.getSampleRate()) is defaulting to 48000 samples per second. I would like to set it to 44100 samples per second as my input audio and processing is sampled at this rate. I would very much appreciate if you could show me how to change the input sample rate.

I would like to add that I have been running ./JackClient without running the jackd -d alsa -r 48000 -i 2 -o 2 command first. It is working fine with out starting the jackd server. Do you think that is odd ?
The only thing I am missing is the ability to change the sample rate to 44100, which I would like to ideally do inside the JackClient.c code itself.