Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members   Examples  

Jezabel: a tool kit for graphical real-time audio applications

Introduction

Jezabel is a collection graphical widgets that provide real-time audio processing functions. For example, there widgets for audio mixing, filtering, reverberation, distortion, and so on. These widgets allow the user to adjust their parameters in real-time, using graphical controls. For example, the mixing widget provides graphical faders and level meters, while the distortion widget allows the user to graphically adjust the distortion curve by moving the control points of a spline.

Jezabel is based on the Qt toolkit. Using Jezabel, you can quickly create real-time graphical audio applications in C++ by creating Jezabel widgets and patching them together.

Jezabel supports audio input and output via three interfaces: the OSS audio drivers, the ALSA audio drivers, and the Jack audio connection kit. Using Jack, Jezabel application can be connected to other real-time audio applications that also support Jack.

Jezabel applications

Before reading the following you should be familiar with Qt, the graphical toolkit from TrollTech. Jezabel provides a collection of Qt widgets of class JezabelWidget that have associated signal processing functions. The signal processing functions are provided by objects of class JezabelTool.

Here is an example of a very simple Jezabel application:

  #include <jezabelapplication.h>
  #include <jezabellowpassfilter.h>

  int main(int argc, char **argv){

    JezabelApplication app(argc,argv);

    JezabelWidget *filter = new JezabelLowPassFilter("filter1");

    app.setMainWidget(filter);
    app.setTool(filter->getTool());

    filter->show();
    
    return app.exec();

  }

There are two differences between this application and a standard Qt application. The first is the type of the application object "app", which is JezabelApplication instead of QApplication. The second is the line:

    app.setTool(filter->getTool());

Here, we use the JezabelWidget method getTool() to get the JezabelTool object associated with widget "filter". In this case, the JezabelTool implements a low pass filter. We then use the JezabelApplication method setTool() to install this tool as the application's signal processing function. The result is an application that applies a low pass filter to its audio input and sends the result to its audio output. The widget JezabelLowPassFilter provides sliders that allow the user to control the cutoff frequency and "Q" of the filter in real time.

Putting things together

Signal processing functions can be patched together using a special tool of class JezabelPatchTool. Here is an example of a simple application that combines a low pass and a high pass filter:

  #include <jezabelapplication.h>
  #include <jezabellowpassfilter.h>
  #include <jezabelhighpassfilter.h>
  #include <qvbox.h>

  int main(int argc, char **argv){

    JezabelApplication app(argc,argv);

    QWidget *box = new QVBox();
    JezabelWidget *filter1 = new JezabelHighPassFilter("filter1",box);
    JezabelWidget *filter2 = new JezabelLowPassFilter("filter2",box);
    JezabelPatchTool *patch = new JezabelPatchTool(1,1);

    patch->addChild(filter1->getTool());
    patch->addChild(filter2->getTool());

    patch->connectChild(0,0,0);
    patch->connectChild(0,1,2);
    patch->connectChild(1,0,2);
    patch->connectChild(1,1,1);

    app.setMainWidget(filter);
    app.setTool(filter->getTool());

    filter->show();
    
    return app.exec();

  }

Here, we create two JezabelWidgets (inside a QVBox), and a JezabelPatchTool with one input port and one output port. We use the addChild() method to insert the tools corresponding to the filter widgets into the patch. Then we use the connectChild() method to connect the ports of the tools to channels. The connectChild() method is used like this:

    connectChild(child, port, channel)

Here, "child" is the number of the child tool, "port" is the number of a port of a port of the child tool, and "channel" is the number of the channel to connect this port to. All three arguments are numbered from zero. Channels are numbered with inputs of the patch first, then outputs of the patch, with higher numbers representing internal channels. In this example, since the patch has one input and one output, channel 0 represents the input, channel 1 the output, and channels numbered 2 and higher are internal. Thus, in the above example, we have connected the input of filter1 (port 0) to the patch input, the output of filter1 (port 1) to internal channel 2, the input of filter2 to channel 2, and the output of filter2 to the patch output.

Finally, we install the patch as our main tool using the setTool() method. The result is that one audio input channel is passed first through a high-pass filter controlled by widget filter1, then through a low-pass filter controlled by widget filter2. See class JezabelGraphicFilter, however, for an easier way to do this that also provides a graphical display of the frequency response.

Presets

The JezabelPanel widget provides a way for users to save and restore the values of controls in Jezabel applications. The simplest way to use it is to make your main widget a JezabelPanel. Here is an example:

  #include <jezabelapplication.h>
  #include <jezabellowpassfilter.h>
  #include <jezabelpanel.h>

  int main(int argc, char **argv){

    JezabelApplication app(argc,argv);

    JezabelPanel *panel = new JezabelPanel("my_app","current");
    JezabelWidget *filter =
         new JezabelLowPassFilter("filter1",panel->mainArea());

    app.setMainWidget(panel);
    app.setTool(filter->getTool());

    panel->show();
    
    return app.exec();

  }

Here, "my_app" is some identifier for the application, and "current" is a name for the default configuration (the one that stores the control values from one run of the application to the next). Presets are stored in the subdirectory ".jezabel" in the user's home directory. JezabelPanel shows a list of available presets, and provides buttons to add and delete presets.

Input and Output

On Linux, Jezabel supports input and output via three kinds of devices: OSS, ALSA and Jack. JezabelApplication provides a control panel that allows the user to select an audio device, and in the case of Jack, to connect the application's ports to ports of other applications. To show this control panel, use the following call:

    app.showAudioControlPanel();

JezabelPanel also provides a button for this purpose.

Compiling and Linking

Compiling a Jezabel application is just like compiling a Qt application. To link your application, in addition to the flags used for normal Qt applications, use -ljez.

Download and installation

Jezabel is available for Linux by anonymous CVS from sourceforge.net. Use the following command to check out the sources:

    cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/jezabel login

    cvs -z3 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/jezabel co libjez
Follow the instructions in the file README to compile and install.

Real-time operation

To avoid interruptions in the audio stream of a Jezabel application, you need a "low latency" kernel. If you are using RedHat Linux, you can get a pre-built low latency kernel from the Planet CCRMA at Home project.


Generated at Tue Jan 27 23:28:16 2004 for Jezabel by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001