|This page of developer code and/or digital audio documentation is part of a collection of pages for learning about our code. We aim to increasingly add interactive diagrams to these pages and over time connect better to the doxygen documentation.|
- 1 Overview
- 2 Diagram of Audacity System Architecture
- 3 Components
- 4 Cross Platform Library
- 5 Real Time Ability
- 6 Architectural Overview
|If you have questions about the architectural design of Audacity, please post them here and the developers will answer them.
This figure is a recoloured version of an illustration from The Architecture of Open Source.
Audacity uses many libraries. The principal library for user interface is wxWidgets, which is cross platform (Windows, Mac, Linux). The diagram above shows how Audacity layers additional abstractions on to the base libraries.
- BlockFile uses the OS file system, via wxWidgets wxFile, to provide a way of storing Audio in many small chunks. The small chunks make it quick to cut, paste and rearrange audio, without having to copy and modify the whole audio file for each small change.
- ShuttleGui uses the wxWidgets dialogs, buttons and other controls. It organises them with an additional structure that reduces repetitive code, used mainly to 'shuttle' values from one place to another. Most importantly user preferences such as audio quality are stored in a file. Data has to be shuttled from the file into a variable, from the variable into the widget that displays the value, and in the reverse direction too.
- The Command handling in Audacity binds keystrokes and menu items to internal commands within Audacity. It uses wxMenu from wxWWidgets.
Although PortAudio is not part of wxWidgets, it too has a 'reflection' in Audacity.
- AudioIO manages the process of moving audio between the sound card, memory and hard disk, providing additional abstractions over the cross-platform sound card handling in PortAudio.
There is more about this in the book The Architecture of Open Source.
Diagram of Audacity System Architecture
Items marked with a * are not released yet and are only available from the latest version of Audacity in SVN HEAD by enabling experimental features.
Q: What are the components in the diagram?
A click on a menu or pressing a keyboard shortcut must dispatch to a routine somewhere. This kind of code is not at all specific to Audacity. Any editor of anything could benefit from it. Perhaps this code will become a reusable library? Some of the details:
- We enable and disable commands, most particularly when audio is and is not selected.
- We have an undo/history mechanism. This has an idea of 'summary' so that several consecutive commands may be lumped together.
- The keyboard shortcuts are user configurable. That's set up in one of the preference panels.
- The GUI is translatable - you'll see _("some text here") in many places in the code. That means we use wxgettext and .po files to translate it.
- We additionally abuse the translation system slightly. Translating menu items to start with a '#' leads to those items being hidden from the menus. This is useful for simplified versions of Audacity.
The automation interface started life as Lynn Allan's CleanSpeech variant of Audacity. This is/was a simplified interface to Audacity with a sequence of operations to remove noise, normalise, truncate silence and convert to mp3. Lynn's use case was conversion of large numbers of sermons from tape so that they could be featured on the internet.
- The batch feature now has a list box to set up and modify chains of effects. The sequences though are still strictly linear.
- Built on top of this is an experimental scripting feature. An optional dll module can be loaded, mod-script-pipe, that accepts commands over a named pipe and hands them on to Audacity. Due to the skeleton nature of this feature - no errors or dialogs are handled - it is only suitable for developers at this stage.
Audacity effects are NOT real time effects. You select audio, apply the effect, then listen to the result.
- Built in: These are the easiest to work with. C++ code is in the Audacity project.
- LADSPA: Loaded as dlls and following the Ladspa standard. (See also LV2).
- Nyquist: These are Nyquist (LISP) scripts for audio processing.
- Vamp: These effects are about analyzing audio. Vamp effects may produce a curve that measures some aspect of the audio, or they may produce labels to label certain features. Nothing stops a Vamp effect from producing a curve that happens also to be audio, i.e. like a regular effect, but that is not the usual use.
One could argue that the 'mixing', gain, panning and amplification envelopes are all effects too, and that these ARE real time.
Most audio editors make the distinction between real time effects (ones you can apply and listen to immediately, and even change the parameters of as you listen to them) and non real time effects.
In Audacity we plan to gradually transition to real time effects through a mechanism that supports both kinds. Whether an effect can be real time or not is largely a matter of the speed. On a slower machine fewer effects will be real time than on a faster machine. This is an important consideration for Audacity. Audacity will not always know in advance. One plan is that rendering can be 'given a head start'. As you listen to what has been rendered your playback cursor may start to catch up. On a fast machine the render will be faster than your playback.
The many audio formats that Audacity supports are provided by third party libraries. Most of these libraries are compiled into Audacity.
- The LAME library which handles mp3, for licensing reasons, is not distributed with Audacity and is loaded separately.
wxWidgets provides some support for toolbars. With wxAUI its toolbar support has become more mature. We added our own code for docking and working with toolbars before that library existed.
We use many libraries.
These widgets are enhancements to and built on the widgets provided by wxWidgets.
- In the track panel we use some 'lightweight' widgets. In normal wxWidgets each widget has a windows object associated with it. In the track panel this doesn't hold (Flyweight pattern).
- Tracks: There are several track types for displaying audio data.
- Data: Audio is represented as a tree.
- Wave Track:
- Spectrum Track:
- Time Track:
- Label Track:
This is one of the most interesting subsystems in Audacity. The blockfiles represent a linear stream of audio data as a tree. The blocks are stored on disk. This makes it practical to make changes in the middle of audio, particularly changes that affect length, without the time cost of moving data around on disk for all the audio that comes later. This makes possible work with very long recordings.
The blockfile system also allows multiple versions of the same audio to share common data in the parts which agree.
The technique is closely related to 'unrolled linked list'.
These are the many dialogues that control parameters in Audacity.
We use ShuttleGui here. ShuttleGui is a wrapper around wxWidgets, to make the code more readable.
Cross Platform Library
Q: What widgets/controls library are you using, in order to be cross-platform?
A: wxwidgets: http://www.wxwidgets.org/
Real Time Ability
Q: Are there any plans to add any real-time DSP (Digital Signal Processing) to Audacity? It really helps when you can tweak plug-in settings as the audio is playing.
A: Agree. I'd love to see 'Postfish' (written by Monty) integrated into Audacity. It's a big change and needs to happen in evolutionary steps. I have a proposed route to it, which would start by providing a single effect, echo, as a real time effect. James 8th-March-07
Q: How can I get an overview of Audacity's architecture?
A: Download the source from GitHub. Run Doxygen to get the brief class descriptions or just look at them online here. Look at the subdivision into libraries that are outside the GUI. Ask questions here or on the developers' list.
We're using Doxygen lightly, only at the level of classes, with no intention of covering the functions too, so don't expect a greater level of detail than the class list. The class list goes into more detail than the diagram above. You can get the same class information by browsing the source code. The class descriptions are all there in the source code. They are at the start of the cpp files. You don't need to run Doxygen to find this information. Use Doxygen if you already know it and like what it does.