I recorded and mixed everything in Garageband up until Hitch Your Wagon to a Star, which I'd done in Logic Pro (thanks to Eric ). Up until then, I didn't have a microphone or interface or anything like that. I just used my built in laptop microphone for acoustic guitar or vocals. For anything electric, I used a 10 dollar USB video capture adapter without the video input. I also got better headphones around the time of my switch, too (I was using 15 dollar sony headphones before then).
With all this new stuff, I didn't have as much of an excuse to not learn mixing or recording, so that's what I've been up to. I'm trying to learn things at the lowest level so I really understand what I'm doing.
Ecasound
Ecasound is a text-based audio workstation developed by Kai Vehmanen primarily from 1999-2000.
I think it's great because it removes the abstraction about recording and mixing that is so baked into every modern DAW. I just want my audio tracks to be files and I want to know everything the audio from those files is doing when it goes to and from them.
I also think that something good happens when you start with bare functionality and it's hard to do anything else.
It forces you to
- Identify that you want something you don't have
- Want it bad enough to go through the effort of making it happen
Not that I am a skilled mixer, but I also think there's something valuable in being forced to use your ears to make decisions. I often find that I'm just looking at graphs and twisting knobs to what 'looks right' instead of actually listening when I'm using a normal DAW.
Given all that, this is an introduction to the logic behind ecasound and some basic usage. Everything written here is likely written better somewhere on the ecasound site in the man pages or examples.
Audio Objects
Digital audio is passed around your computer in the medium of pulse-code modulation (PCM). This can be synthesized or captured, but I'll first talk about capturing. You probably have a microphone attached to your computer. Sound, in the form of more/less dense air, moves the membrane on your microphone back and forth. In some way or another (depending on your microphone), this motion puts a voltage on a wire visible to the digital world. When the sound is louder, it pushes the membrane further back and forth, resulting in a higher magnitude voltage. When the sound is higher pitched, it moves the membrane back and forth more frequently, resulting in more fluctuation in voltage. This voltage gets checked 44100 or 4800 times per second (usually). In order to put this continuous voltage in terms the computer can handle, the voltage gets rounded and represented in some number of bits (something like 32). The succession of these bits at the same rate they were captured then corresponds to the original sound wave. Of course, we can synthesize bits such that particular sound waves result; for example, a sin wave with a particular frequency.
Some small duration of this stream is a 'block' of memory that gets filled temporarily in a sort of fake file called a capture device before the whole block can get sent somewhere else. The blocks from this file, just as though it were a .WAV file, can be read and subsequently written. Whether these blocks get written to a file or to a speaker, the data transfer is essentially the same. The speaker is handled via a similar sort of fake file (a playback device) that does something special when it gets written to.
When a playback device receives a PCM block, it takes the bits and turns them into voltages which move the speaker's membrane to make a sound. When a normal file receives a PCM block, it just stores it. These various places PCM can be are called audio objects.
The only caveats with device audio objects, not that these would even be desirable, are that a playback device cannot be read from and a capture device cannot be written to.
On linux, capture and playback devices are handled by the
Advanced Linux Sound Architecture
(ALSA).
To view your available
devices, you can type alsactl info
.
Chains
A chain is, at the bare minimum, a connection between two audio objects such that one is the source/input and the other is the sink/output. A chain is always created, even if not specified. For example,
ecasound -i alsa -o alsa
creates a chain between the default ALSA capture device and the default ALSA playback device. The default chain is aptly named "default". This means that when ecasound is started, PCM blocks will be read from the capture device and written to the playback device. Running this will play audio from your microphone to your headphones or speakers (probably with horrible feedback if that's the case).
Of course, files can take the place of these devices, in which case the PCM blocks are read/written from/to the named file instead of from/to a device. For example, say you want to record an acoustic guitar track. You could just replace the playback device with a file path:
ecasound -i alsa -o guitar.wav
Chains can be explicity created or referenced with
-a CHAIN_NAME(S)
, where the CHAIN_NAME
can be any string, but it usually makes sense to just number them.
In the event of multiple chains being referenced, you can separate them
with commas like
-a 1,2,3
and
in the special case that you want to reference all chains, you can just
use -a all
.
With that knowledge, you could accomplish the same recording as above
in a more unreasonable way by executing
ecasound -a 1 -i alsa -o guitar.wav
This is useful, however, when you need to have different audio sources playing concurrently. The only reason I was using ecasound at all is because I was trying to use sox to record multitrack but it doesn't support any sort of time synchronization and I was getting tired of manually adding silence to the beginning of each track to line them up for mixing.
You've already recorded acoustic guitar to guitar.wav
.
Now, you want to record a vocal track.
You know you want to both hear guitar.wav
and record your
microphone input to a new file.
Since these are two separate required audio streams, you'll need to use
two chains, as written here:
ecasound \ -a 1 -i guitar.wav -o alsa \ -a 2 -i alsa -o vox.wav
Here, chain 1 is reading from guitar.wav
and writing to the default ALSA playback
device so you can hear it while you record through chain 2, which is
reading from the default ALSA capture device
and writing to a new file called
vox.wav
.
Now, you want to make sure your voice sounded okay with the guitar because hearing it as you sing it doesn't really mean anything. You want to hear both recordings played together. This will also require two chains, since there are two different audio streams happening (even though they're going to the same place). You would execute:
ecasound \ -a 1 -i guitar.wav -o alsa \ -a 2 -i vox.wav -o alsa
It's annoying to have to write the same output audio object for both chains. You can do something special as follows:
ecasound \ -a 1 -i guitar.wav \ -a 2 -i vox.wav \ -a all -o alsa
Now, the only problem is you sang way too loud and it otherwise just sounds grating. Luckily, you can solve this.
Effects
Each chain can not only route an audio stream from one place to another, but it can also modify that audio stream.
There are several built-in effects. To amplify a chain's audio (or in our case make it quieter), we could execute:
ecasound \ -a 1 -i guitar.wav \ -a 2 -i vox.wav -ea 50 \ -a all -o alsaThis will play the resulting vocal audio at 50% the original volume in the final mix. On the PCM level, this is just dividing the stored value for each sample by 2.
Say you also want to add some reverb to your voice. You can add multiple effects to the chain and they'll be applied in the order you supply. To accomplish this, you would write:
ecasound \ -a 1 -i guitar.wav \ -a 2 -i vox.wav -ea 50 -ete 10,50,50 \ -a all -o alsa
The parameters (comma separated) for this effect are
- room_size (meters)
- feedback-%
- wet-%
I won't give examples for every included effect. You can check the ecasound documentation for all of the options and their parameters.
I will say, however, that you can apply effects to multiple chains at a time in the same way you would specify the same output audio object for multiple chains:
ecasound \ -a 1 -i guitar.wav \ -a 2 -i vox.wav -ea 50 -ete 10,50,50 \ -a all -o alsa -etm 10,2,50
This will add a multitap delay of 10 ms with 2 delays and mixed 50% with the un-delayed signal for both chains.
The built-in effects are great, but there's a world of amazing other effects out there as well.
LADSPA
Linux Audio Developer's Simple Plugin API (LADSPA) is a simple standard for audio plugins that was first released in April 2000. This makes it possible to develop signal processors for use in a multitude of applications including, of course, ecasound.
Since then, hundreds of effects have been developed and released. Here are some useful repositories of plugins:
- C* Audio Plugin Suite (CAPS)
- Computer Music Toolkit (CMT)
- Steve Harris' Repo
- Tom's Audio Processing (TAP) LADSPA Plugins
To use a LADSPA plugin, you first need to make sure its .so
is in the LADSPA_PATH
directory.
Then, you can use it in ecasound with -el
.
For example,
ecasound \ -a 1 -i guitar.wav -el CabinetIV,0,10 \ -a 2 -i vox.wav \ -a:all -o alsa
To simulate a loudspeaker cabinet on the guitar with 10dB gain.
There are also a handful of sound-generating LADSPA plugins, like
sine waves, white noise, or synthetic drums.
When you use these, the input to the chain can technically be anything,
but you probably want it to be null
.
For example, this will generate a stream of white noise to help you fall
asleep (requires the
White
plugin from CAPS):
ecasound -i null -o alsa -el White,1
The 1, here, corresponds to the volume of the white noise. Maybe in order to fall asleep, though, you need it to have some motion, some volume change to make it sound like rolling waves. To do this, you'd need to use a chain operator.
Chain Operators
Chain operators modify parameters for the effect that was last written in the chain. To change the volume of the white noise to follow a sine wave, you could execute:
ecasound -i null -o alsa -el White,1 -kos 1,0,1,0.5,0
This will change the volume (the first parameter of the
previously-written effect) from 0 to 1 at a frequency of 0.5 times per
second, starting the sine wave at x=0
.
As you may have been able to guess from that description,
the parameters for -kos
are:
- Effect parameter index (starting at 1)
- Start Value
- End Value
- Frequency in Hz
- Initial Phase
You can also use chain operators to trigger events, if the effect
you're using works like that.
For example, there is a CMT plugin called syndrum which plays a
synthetic drum when its first parameter (trigger) changes from 0 to 1.
There are chain operators which can make sudden changes between
numbers instead of smooth ones, as we saw above. One such example is
-kf
, whose parameters are:
- Effect parameter index (starting at 1)
- Start Value
- End Value
- Frequency in Hz
- Mode (0 for static, 1 for linear interpolation)
- Generic Oscillator Index
/usr/share/ecasound/generic_oscillators
.
There, you could also write your own following their format.
More relevant is parameter 5, the mode.
We want to use
0 to ensure we get a sudden transition from 0 to 1 to
trigger our drum.
We would do this as follows:
ecasound -i null -o alsa \ -el syndrum 0,1,100,0.2,1 \ -kf 1,1,0,2,0,0
Here, twice every second we would trigger our synthetic drum, which has a frequency of 100, a resonance of 0.2, and a frequency ratio of 1. You can play with those parameters to make different sounding drums.
Interactive mode
Ecasound interactive mode (EIAM) is pretty much the same as normal ecasound, except that you can make adjustments during playback. That and you have to learn a bunch of extra commands to do anything.
To use it, you can just do anything you'd normally put and pass
-c
somewhere. For example, you could set up a simple live
chain as I showed before:
ecasound -i alsa -o alsa -c
and this will open the interactive mode.
Don't get scared that you don't hear anything, it just hasn't started.
To start it, you can type start
or t
for short.
As you might guess, stop
(or s
) stops playback.
You might notice some latency, which will only get worse the more you do.
You should always try to run EIAM as root and with the realtime flag
-r
, as follows:
sudo ecasound -i alsa -o alsa -c -r
You might need to use alsahw
instead of alsa
for one or both audio objects, but don't worry about it unless it complains
at you.
Now that ecasound has the necessary permissions for real-time, you should not hear as much latency. You can also now add and modify effects without stopping playback.
To add a new effect (for example the LADSPA plugin gverb), you can type in EIAM:
cop-add -el:gverb
You might hear a change, you might not.
All the parameters for gverb right now are set to 0, which is probably
not what you want.
If you type cop-status
, you can see the parameters
available and the indices associated with the chain, the effect, and the
parameter.
The status for a chain with only gverb should look like
Chain "default": 1. GVerb: [1] Roomsize (m) 0.000, [2] Reverb time (s) 0.000, [3] Damping 0.000, ...
and so on. You can set, for example gverb (effect 1) parameter "reverb time" (parameter 2) to 0.5 seconds with:
cop-set 1,2,0.5
This will only modify effects on the selected chain.
You can check which chain(s) is/are selected with c-status
and select chains with c-select CHAIN_IDX
.
There's a ton of other commands for chain and effect adding, removing, checking, setting, and so on, but you should read the EIAM docs for more information.