Main Page   Class Hierarchy   Compound List   File List   Compound Members   Related Pages  

First off, if you haven't read the main page, as well as the Qt Info page, please do so first...

The rest of this document assumes you have both QT and the QT "tmake" utility installed. If you don't have them, you'll need to download and install them first. You can do so at the Trolltech home page. Downloading QT for linux is free, although not for Windows, unless you have an academic or other type of license already.

Keep in mind that you are welcome to email me if you want to use Gape, or have questions, and this documentation isn't enough.

The first thing you need to do is download and install GAPE. Right now, alsa and directx (with MSVC++) are supported, and OSS should work too, although you'll probably have to change a couple of project files or something. Email me if you want to use OSS. If you are using Alsa or DirectX, installing GAPE should be quite simple, assuming you've installed QT and tmake, and you have your VC++ compiler set to run from the command line (this just requires that you set a few enviroment variables and change your PATH, if you haven't already - you can email me with questions, or check the MSVC++ docs). Download and decompress Gape into the directory of your choice. Then go to the Gape directory, and run either the configure_directx batch file or the configure_alsa script. You computer should compile the Gape library, as well as the supporting fftw, qwt and stk code, and the demo program.

If you want to run the demo program first, go ahead. The executable file is in the gape/projects/demo/bin directory. If it runs poorly, that probably means some of the compiler or runtime settings should be adjusted to be optimal for your machine. Reading the docs should help you figure out how to do that, or you can email me. If it crashes after awhile, thats a feature, not a bug... (sorry I had to say that, feel free to report problems to me.) There are instructions on how to use the demo program below.

Before we actually look at any code, I think a brief overview of how GAPE works and what its designed for is in order. Obviously its meant for audio programming, but that doesn't really say much - and there are plenty of audio libraries already available. Ease of use was one of the primary goals I had in mind when designing GAPE. Hopefully students at the undergraduate level (or higher) who haven't don't much audio coding in the past, but are interested in the field, can write useful programs using GAPE, and not have to spend weeks learning coding conventions, dealing with scattered insufficient documentation, etc. While some knowledge or C and/or C++ and/or Java is needed (or a good book and the willingness to learn), you don't have to be a seasoned programmer to use GAPE. On the other hand, seasoned programmers may appreciate the relatively high level of abstraction GAPE offers (who really wants to write a sound card I/O class anyway?) and also find it flexible enough for their needs. At all times, I tried to spare clients using my code from mundane and possibly tough details like writing Makefiles, cross platform details, etc.

GAPE has real time applications firmly in mind, although it could be used for non real time purposes, such as writing to wav files, etc. In addition, it's meant to be used with GUI interfaces, and this (hopefully) simplifies the process of putting a GUI front end on your code. Beta 2.0 should include MIDI control and control over a network (as well as streamed audio), but GUI is the primary focus right now. Some of the important considerations to be dealt with when writing real time audio code with a GUI controller are:

1 - Threading issues: If you're not familiar with multi threaded programming, I'll briefly describe how this matters in audio. Threads are basically the way programs do many tasks at once - each "thread" of code does something different, and these threads are run simultaneously. If you tried to draw to the screen on the same thread you were doing audio, your sound would have clicks and pauses whenever you moved your mouse, and your mouse might move in choppy jumps. It's really a bit more complicated than that, since different applications need to share a common thread when drawing to the screen, etc... but there's no need to get into that here. GapeControllers take care of all of this for you - you should look at the docs for that class for more details, and look at GapeAudioPlot for an example of this functionality.

2 - Integrating your Audio and GUI code: Where to start? What libraries to use? What if you can't make the library which gets audio samples from your sound card play well with the library you are using to draw knobs on the screen? These are the kinds of details you shouldn't have to worry about when using GAPE.

3 - Getting audio to and from your sound card, writing or reading files, etc: This is boring but formidable code to write, and GAPE takes care of it all (well OK I didn't finish my file writing classes but just wait until beta 2.0)...

4 - Time domain and Frequency domain displays: Don't you like how winamp lets you see the audio? Well GAPE does it too...

5 - Documentation: The lack of good documentation for some audio libraries has caused me no end of aggravation and wasted time. I'm sure it's caused many others the same problems. DirectX's documentation is tailored almost exclusively toward writing video games, and no one seems to like the ever changing Alsa docs. Hopefully I'm doing a better job, but if you feel something is lacking in either my doc pages or in the style of the code itself, *please email me!*

There's more stuff built into GAPE as well, but hopefully this should give you an idea of what it's meant for. Now a bit about how Gape works.


There are two main classes in GAPE - GapeUnits, and GapeControllers. GapeUnits are the classes which actually do some audio. They might be some kind of signal generator, they might be a wav file reader, they might be audio outputs. Basically, they are anything which receives samples of audio and/or produces samples of audio. You should check out the docs for GapeUnit for more details. GapeControllers are the graphical controllers for GapeUnits. It might be a "widget" (QT for graphical object) with knobs and buttons it, for instance. Once again, you should take a look at the class documentation.

The best way to get started programming with GAPE is to look at the demo program code. Also, looking at the docs for GapeUnit and GapeController is a good idea as well. If you haven't run the demo code, its basically a program which demonstrates some of the built in features of GAPE. It allows you to "draw" one period of a waveform and hear what it sounds like - you can draw in the graph at the top left of the window by holding the mouse button and dragging the pointer around in it. You can set the frequency and volume by pulling the sliders below the graph. NOTE: You can get fine grain adjustments by holding the mouse to the left or right of the slider itself (but still in the slider groove) and holding down the button. You can also mute this signal with the mute box. (I really should have made a "help" option in the menus - sorry).You can also add up to 4 other signals (ie sine wave, square wave, etc) by using the menu at the top left. The have the same types of frequency, gain, and mute controls. The top right of the window has two buttons which can mute and unmute your sound cards output and input (or mic in or line in, whichever you have active). This app is only mono, and the exact behavior (ie whether it plays mono in both channels, or just teh left ear, and whether you get only left of a stereo mic or instead get both channels mixed together) will depend on your sound card and which platform you're running. The rest of the right hand side of the window have time and frequency domain displays. You can change the number of samples which are shown in one window of the time display, as well as set the frequency display to a log scale. Both displays have buttons to "auto-scale" (which means the bounds of the graph scale dynamically to the signal level) and "freeze" (which freezes the display to the current frame until pressed again.)

If you're not familiar with OOP, I suggest you find some intro to the subject and read it, or at least email me, as this will seem terse...

Open the header file for the demo code, which is in gape/projects/demo/include. Skipping the header includes and some constants for our window size and the maximum number of signal generators we allow the user to add, we see that we've declared a class "Demo" which is a subclass of QWidget. We need a Qwidget here since "Demo" is essentially the window which we use to hold all of our controls. It's not actually a controller by itself though, so that's why it isn't a GapeController (which itself is a subclass of QWidget.) The constructor prototype for Demo is fairly standard for QWidgets - it needs to know it's parent widget, if there is one. Then we have a destructor. Now we have a declaration "public slots:". This is simply QT's way of saying that the following functions are QT "slots" suitable to be used in the signal/slot architecture. We then declare some functions which we will use to add signal generators when the user clicks on a suitable menu option. Then we have the "signals:" declaration - but since our widget doesn't need any signals, we don't actaully define any (we could have just left "signals" out). Then we have one protected function, disableMenu, which (not a suprise) we use to disable the menu when the user has added the max number of signal generators. Following that are pointers for all of our data. You can ignore the "units" array, which I decided not to use, as well as the "temp" variable. Also, I won't bother explaining how to use a popup menu QT documents it better than I can. The VBoxes and HBoxes are just to help us layout our window - once again, suitable info for this task are at teh QT doc site. The rest of the pointers are fairly inportant. Since we're going to have an audio thread separate from the GUI thread, we need a GapeAudioDriver. These basically are what tells the thread to continue generating samples. We also want input and output units, as well as our time and frequency domain displays. GapeDrawnWaveformUnit is the class which allows us to draw a periof of a waveform onto the screen and hear it. We also declare two GapeMuteControllers which we will use with the input and outputs. You may be wondering why we declared separate controllers for the input and output, but not the other units. Basically, it's b/c I unified the controller and unit for the other cases with an overloaded constructor. If yuo don't know what operator overloading is, don't worry about it for now... The last items are GapeUnitGroups. Unit Groups are very handy because they take care of connecting the slots and signals for different units, and allow you to add and remove units whenever you want (either at the start of a program or in response to something like a menu click.) without worrying about keeping unit connections in the right order.

Now take a look at the demo.cpp file, which is in gape/projects/demo/source. I've inlined alot of comments in the code, so you won't really need a description here to follow it. Look it over, and run the program - hopefully you've gotten a good start on understanding how to use Gape. You should definately also check out the known bugs page and the Technical notes page The technical notes page has some info which may explain some nitty gritty code details, as well as the project/makefile convention I use which might make your life a bit easier.


Generated at Thu Jun 21 13:28:53 2001 for GAPE by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001