Digital Music Composition/Making Sound
There are several ways to generate sound digitally. Of course, all these techniques do is produce a stream of numbers representing the sound samples. The numbers are turned into actual audible sound through the digital-to-analog conversion process already described.
The most straightforward way for a computer to make sound is to record, or sample, an existing source of sound (like a traditional non-digital musical instrument) and play back the recording.
Of course, instead of straight playback, creative techniques can be applied, such as cutting up the samples to change their timing or order of playback, filtering and so on. Thus, the sampler becomes very much a legitimate musical instrument.
Another technique is to start with a basic periodic waveform that is easy to generate electronically. There are six different basic waveforms that most subtractive synthesizers use:
- Sine wave: The sine wave is the most basic waveform. It sounds smooth and clean, since the sound of a sine wave is made up of only one fundamental frequency. Since subtractive synthesis works by removing harmonics and a sine wave has none, this waveform has limited use cases when used in a subtractive synthesizers.
- Triangle wave: A triangle waveform has odd harmonics which taper off as they get further away from the fundamental. As such, it sounds a bit more clearer and brighter than a sine wave.
- Sawtooth wave: The sawtooth waveform is the buzziest sounding basic waveform and contains most harmonics. This makes it a great choice for subtractive synthesis.
- Square wave: The square wave contains odd harmonics and sounds harsher than a triangle wave but not as harsh as a sawtooth wave.
- Pulse wave: A variation of the square wave. Instead of a duty cycle of 50% like the square wave, it has a duty cycle other than 50%. This makes it sound thinner than a square wave.
- White noise: Instead of asimple waveform that repeats itself every cycle, white noise generates random values for each sample. It contains a mixture of all frequencies. Suitable filtering can turn this into a wide variety of non-melodic percussive sonds.
The chosen wave can be passed through filters to attenuate or remove a selection of harmonics, producing a wide variety of resultant timbres.
The opposite approach to subtractive synthesis is to start with a set of pure sine waves corresponding to the harmonic frequencies, and then mix them together with suitable amplitudes in order to synthesize the desired timbre. This can require adjusting the amplitudes of a lot of harmonic components—16 or 32 or more, which can be quite a fiddly process with hard-to-predict results.
Some musical applications allow you to draw the waveform for the sound freehand on-screen. However, it is typically quite difficult to predict in advance what a particular wave shape will sound like.
Perhaps the most computationally-intensive technique for producing real-sounding instrument emulations is to program a physical model of the instrument on a computer. For example, to produce authentic string sounds, you can formulate mathematical equations that describe the behaviour of a string, taking into account its length, mass, elasticity, tension etc, and the forces that act on it when it is bowed or plucked.
This technique can also be extended to model the sound of instruments that would be impossible to construct in real life. For example, imagine starting with the parameters of a violin, and then increasing the string length to 10 metres; what would that sound like?
Making Sound On Linux
Enough of the theory, let’s start to make some sound. After some preliminaries about how sound is handled on typical Linux systems, we will get familiar with the following steps:
- Configuring JACK startup for a music session
- Routing audio for a music app
- Routing MIDI for music apps
- Ending the music session.
ALSA, PulseAudio, JACK
Nearly all Linux distros use ALSA at the lowest layer to manage the sound hardware. Together with this, there is usually nowadays a PulseAudio daemon running to give separate user-settable volume controls for different applications. Together, this system is sufficient to handle regular sound-playback needs for user-interface feedback sounds, video streaming and common media players.
However, for music production work, we need to bring JACK into the equation. This gives us a “patchbay”, where we can see “ports” exposed by the different music and audio applications we have running (and system hardware we have available), and run virtual “wires” between these ports to make connections for both audio and control data.
It takes a little bit of setting up, but JACK and PulseAudio can be persuaded to work at the same time. PulseAudio can turn itself into a JACK client while JACK is running, and return to taking control of your audio hardware when JACK quits.
The easiest way to get this to work is to download a copy of my pajackconnect script. This contains commands for setting up PulseAudio when JACK is started, and also for resetting it when JACK terminates. For simplicity, install the script in the usual directory for site-local executables, namely /usr/local/bin, so it will automatically be found via your PATH and you don’t need to type its full pathname to invoke it.
JACK itself is a background daemon; it offers services to other applications, but has no actual user interface itself. However, there are various GUI tools that can be used to control it; here I will use QjackCtl.
When you launch QjackCtl, it will display an initial main window like this. First, click the “Messages” button to bring up a window showing various logging messages; this will typically show a line saying “jack server is not running or cannot be started”. This is fine for now. Do not click the “Start” button yet.
Also click the “Connect” button, and another window will appear, showing the connections between JACK client applications. This will have 3 tabs, labelled “Audio”, “MIDI”, and “ALSA”. The “Audio” tab will show the connections for routing audio data, while the “MIDI” and “ALSA” tabs will show two different kinds of connections for routing MIDI data. Applications that use ALSA calls to manage their MIDI interfaces will show up under the “ALSA” tab, while those that use native JACK calls will show up under “MIDI”.
Unfortunately, the two ways of routing MIDI are incompatible: you cannot make connections between ports on one tab with those on the other. It seems like “native JACK” calls are the preferred way for the future, while older apps still use the “legacy ALSA” calls. Luckily, there is a way to bridge between both worlds (explained below).
In each case, sources of data are on the left, and destinations are on the right, and you will see lines (which you can control) running between them indicating connections. Initially, you will see nothing in these displays, because JACK is not (yet) running.
Next, click the “Setup...” button. This will bring up a window where you can set the options for actually running JACK. We will concern ourselves with some important fields under the “Settings” and “Options” tabs; you can ignore the others for now.
In the “Settings” tab, the “Server Prefix” field contains the command used to launch the JACK daemon. The default (either “jackd” or “/usr/bin/jackd”) should work just fine.
Now go to the “Options” tab. You will see options to “Execute script” at various points in the startup/shutdown sequence. We will need to set two of these.
First, check the option to “Execute script after Startup”. We will need two commands to be executed here: one to run the pajackconnect script, and the other to start a2jmidid which will proxy ALSA MIDI connections through to the native JACK MIDI tab. Both commands can be entered on the same line, separated by semicolons, as follows:
pajackconnect start; a2jmidid -e &
You will first need to ensure you have the a2jmidid package installed. And note the “&” on the end of the a2jmidid command: this tells QjackCtl to start the command running and not wait for it to terminate. If you forget that, QjackCtl will hang until you kill the a2jmidid process. This program monitors all your ALSA MIDI connections, and automatically makes corresponding native JACK ports appear under the “MIDI” tab, allowing you to make connections between newer and older applications, all under the one tab. The “-e” option tells it to make JACK ports for hardware MIDI interfaces as well.
(Note that we don’t have to provide any kind of command to shut down a2jmidid at the end of the music session; it will automatically terminate when it finds that JACK is no longer running.)
Next, look for the option to “Execute script on Shutdown”: check this option, and in the corresponding command field, put in
This tells the pajackconnect script to go through its procedure for restoring normal PulseAudio operation after JACK terminates.
Having made all the above changes, click the “OK” button to dismiss the QjackCtl setup window.
OK, now you are ready to click the “Start” button to launch JACK. If all goes well, you should see a bunch of messages appear in the Messages window, indicating that JACK is running. To further confirm, bring up the “Audio” tab in the Connections window, to confirm it looks like at right: the “system” entry on the left indicates your sound input hardware, another on the right, also named “system”, is your sound output. PulseAudio will register itself in this window, and also automatically interconnect so its clients can continue playing and capturing sound like they did before.
|Leave QjackCtl running during your music session. You will need to use it to manage routing between JACK client apps.|
Does the “Audio” tab not contain connections for PulseAudio as shown? Check the Messages window for errors. Do you see
sh: 1: pajackconnect: not found
(you might have to scroll back a bit)? This means the pajackconnect script cannot be found in your PATH. Or alternatively
sh: 1: pajackconnect: Permission denied
means that the script has not been given executable permissions. You can check that the script is accessible by opening a terminal window and typing
at the shell prompt. If you see the message
Usage: pajackconnect start|stop
then pajackconnect is correctly installed.
Launching Your First JACK Client App
Now, let’s launch an application that can actually use JACK to make sound. We will start with ZynAddSubFX, because it is a fairly self-contained softsynth application that incorporates a whole variety of sound-synthesis methods.
ZynAddSubFX incorporates a huge range of controls, which can be quite bewildering at first. We’ll start with some very simple steps. When you launch it, you will see an initial window like at right. Under the “Instrument” menu, select “Virtual Keyboard...” (or click the “vK” button with the bright blue background); this will bring up another window showing an image of a music keyboard where you can click on the keys to make sound.
If you try clicking on this keyboard, you will hear nothing. Why? Because you haven’t told JACK where the audio from ZynAddSubFX should go! To fix this, go to QjackCtl’s Connections window; in the “Audio” tab, you will see an additional source has appeared, labelled “zynaddsubfx”; drag your mouse from this to the “system” entry on the right, and a line should appear between them. Or you can select the two entries in their respective lists, and click the “Connect” button to make the line appear.
Anyway, now if you click on ZynAddSubFX’s virtual keyboard, you should start to hear sounds. Initially these will not be very interesting sounds, because the default tone that ZynAddSubFX generates is a pure sine wave. While this has its uses, there are a whole lot of more interesting presets just a click away.
Go back to the “Instrument” menu in ZynAddSubFX’s main window, and this time select “Show Instrument Bank...”. This will bring up a window showing all the presets that are loaded, with a lot of buttons, including blank ones for unused preset slots. There is a popup menu at the top left, to choose from different categories of presets; select one of these, and you should see the window display change to show presets in the specified category. Click on one of the labelled buttons to change the sound. Now try clicking on the keys in the virtual keyboard, and hear how that sounds.
Using A Separate Keyboard App
Now we will launch a separate virtual keyboard app, called vmpk], or “Virtual MIDI Piano Keyboard”. Why bother, when ZynAddSubFX already includes a keyboard? Because this keyboard app can drive, not just ZynAddSubFX, but other sound sources as well, which do not provide their own keyboards.
This app should appear under the name “Virtual MIDI Piano Keyboard” in your application menu. After launching this, check the “ALSA” tab in QjackCtl’s Connections window. Run a wire from “VMPK Output” on the left to “ZynAddSubFX” on the right.
Now try clicking on the new virtual keyboard, and you should hear ZynAddSubFX making sound as before. Of course, its own keyboard still works as well.
Now, just for fun, let’s try an app called “JACK Keyboard” (package name jack-keyboard). This one shows its MIDI ports exclusively in the “MIDI” connections tab, not “ALSA”. ZynAddSubFX only does “ALSA”. But because we have a2jmidid running, you will see sources and destinations labelled “a2j” appear in the MIDI tab. Click the “>” symbol next to the one in the sources section on the right, and you will see an entry for ZynAddSubFX. Connect this up to the destination for jack-keyboard as shown, and try playing notes with this keyboard.
Deleting A JACK Connection
If you make an incorrect connection in QjackCtl, or just change your mind about routing, you can remove just that one connection by selecting its source and its destination in the respective lists, and clicking the “Disconnect” button.
Playing An Actual Keyboard
If you have an actual MIDI-capable music keyboard, you can connect it to your PC using a MIDI-USB adaptor. Linux includes standard support for such devices, so they should show up in QjackCtl’s Connections window in the “ALSA” tab, just as vmpk does. And a2jmidid will route them through to the “MIDI” tab as well.
Alternatively, both ZynAddSubFX and the virtual keyboard apps allow you to play on your computer keyboard as though it were a music keyboard. However, there may be limitations on how many simultaneous key presses your keyboard is capable of recognizing, and hence on the maximum number of notes in a chord.
Make sure any of these virtual keyboard windows is active—whether the one built into ZynAddSubFX, or vmpk or JACK Keyboard. Try pressing the bottom row of alphabetic keys: Z, X, C, V, B, N, M etc should correspond to the white keys from middle C upwards, with S, D etc on the next row up making up the associated black keys. Also, Q, W, E etc gives you another row of white keys from the C above middle C, with alphanumeric 2, 3 etc the corresponding black keys. These are just the default settings; note the little controls labelled “"qwer" Oct” and “"zxcv" Oct” in ZynAddSubFX’s keyboard: these let you change the octave assignments for those rows of keys. The bigger “Oct” control changes the pitch of all these keys as well as the clickable ones in the window.
In vmpk, the “Base Octave” control lets you transpose everything up and down by whole octaves, while the “Transpose” control lets you make semitone-level alterations to the pitch. In JACK Keyboard, the “Octave” control only changes the pitch of keys on the computer keyboard, not in the virtual keyboard window.
With all applications, you will see corresponding keys in the virtual keyboard display highlight as you press keys on your computer keyboard.
Using Multiple MIDI Channels
ZynAddSubFX can accept MIDI commands on more than one channel at once. Look at the settings marked here.
By default, only channel 1 is enabled, and the window shows the settings for channel 1. Click the channel indicator to show the settings for channel 2, and you will see the “Enabled” checkbox becomes unchecked; check it to enable channel 2. Check the “MIDI Chn Rcv” popup menu on the right of the window; this should default to “Chn2” for this channel. Also, choose a sound from the instrument bank for channel 2—something distinctively different from what you have chosen from channel 1. (Whatever instrument you choose from the bank is applied to the channel currently showing in this indicator.)
Now go to your virtual keyboard app, and switch it to send MIDI commands on channel 2. For added fun, have two keyboards open, one on channel 1 and the other on channel 2 (make sure they are both connected to drive ZynAddSubFX’s MIDI input), and try clicking keys on each one in turn.
Ending Your Music Session
When you are done making music, make sure to terminate all JACK client applications apart from QjackCtl. Then click the “Stop” button in the QjackCtl main window. A dialog will pop up warning you that “Some client audio applications are still active and connected”, even though you have quit everything; this dialog is referring to PulseAudio, which will correctly clean up after itself, so click “Yes”. You should see a bunch of messages appear in the Messages window, possibly even some that look like errors. Don’t worry too much about these; the important point is that the “Audio” and “MIDI” tabs in the Connections window are now empty (the “ALSA” tab might not be, but don’t worry about that).
Now you can quit QjackCtl, and your system sound should still remain usable by non-JACK-client applications.