Thursday, January 1, 2009

Recording music with Ubuntu Linux (Intrepid Ibex)

Here's a quick tutorial on setting up Ubuntu Linux for recording audio. This is not hard to set up, but can be a little confusing if you don't do it every day.

1. Basic linux setup.

First off, you will need to turn on the audio capture for the "line in" or "microphone in" for your sound card, and of course, plug in your wires. The easiest way to get to the Linux mixer is to double click the little speaker icon at the top bar:



Then go to:

Volume Control -> Preferences

And make sure that "Line In capture" or "Microphone Capture" switches are checked. This will give you additional check box options under the "switches" tab. Make sure at least one of these options are checked.



I prefer using "line in capture," taking the the output from a small mackie mixer. This will give you a lot more control over the input signal. Of course you can plug a mic directly in the back of the computer, but depending on the microphone, it might not sound as good.

Also you may want to turn off "line in" for playback, and only enable it for recording. Otherwise, you might heard a slight double hit for every sound, or phase shifting.

As a quick check you can try recording with something simple like Sound Recorder just to verify that the basic wire connections and linux audio settings are basically correct. This will verify that the audio signal is at least going through the sound card.


2. Now from synaptic or apt-get, install:

ardour (multi-track recorder),
jack-rack (a LADSPA effects rack), and
lame (mp3 converter)

In my opinion ardour is probably the best open source multi-track recorder for linux. My second favorite is traverso, although the interface is a little counter intuitive if you are used to something like ardour or cubase.

3. Now close any other programs which may be using the sounds card (like browsers, games, etc). You should be able to start Ardour, under the Applications group "Sound & Video".

Note: by default Ardour has a dark color scheme (which might make it a little hard to see where things are). To change to a lighter color scheme, you can go to (from the top menu bar):

Window -> Theme Manager

4. Now before you can record anything you need to add a new audio track. This is under

Session -> Add Track/Bus

For example:





Then you can select mono or stereo, depending on your input. Pick mono if you don't need stereo .. it will save disk space.

Also what the "Normal" and "Tape" mode means: in normal mode you can record multiple times on the same track. Overlapping clips in the same track are blended together, or can be moved independently. In tape mode, think of a tape recorder with one long continuous piece of tape. Whatever is recorded overwrites whatever was on the track. It's handy when mixing down (or bouncing) multiple tracks to a single stereo track. If you don't want to have to delete audio clips before re-recording.

The rest of the defaults are fine.

5. Now to actually record onto a track, it must be "armed." Otherwise, the tracks are protected from accidentally recording over them. To "arm" the track click on the little red circle on the leftmost end of the track:



Note the slider here controls the volume for playback (for quick mixing).
The "m" button "mutes" the track (during playback)
The "s" button "solos" the track, which is the inverse of mute (meaning you mute everything but that track)

If you press mute and solo together, your machine will blow up. Of course I'm just kidding :)

7. You should now be able to see the recording levels here (to the right of these buttons). If the signal is too loud you will see red clipping. Be sure to adjust the volume levels of the input sound, so that it's not too loud (distorted) or too quiet (not enough signal/noise).

8. Now the recording controls are similar to any standard tape recorder. Click the red circle and triangle to actually start recording onto the armed track. The square stops the recording.



The "|<" returns the play head to the beginning of the recording. Or you can move the play head around with the scrubber (the horizontal slider in the picture above). Or you can click on the timecode to move the play head to a specific location.



9. Basic audio editing: You can trim, change the fade in/out, or move the clips around with the pointer tool selected (the little hand).



This is the default editing selection tool. The "|<->|" icon, next to the hand pointer, is another important mode. It is for selecting time ranges of one or more tracks. For example if you want to cut a whole clip, use the hand. If you want to cut a region out of the clip, use the range selector.

One of the most useful edits is under Edit -> Split Region. It will split a recorded clip into two regions that can be moved independently. Like scissors. Select the tracks of the audio that you want to split. You can select, as a general convention, multiple items by holding down the CTRL key and clicking on the track(s).

Also, note the "Markers" on the time line. Punch in/out and looping is especially handy. If you don't see a "Loop/Punch Ranges" heading in the Markers area, right click, and check "Loop/Punch."

Suppose that 98% of a take is good but contains a mistake in the middle. You can set a range containing the mistake and record only the few seconds of the track within the punch in/out range. This protects the rest of the track from recording over it.

To set up a punch in/out region, drag a region in the time line, and select "Set Punch Range":



Then click the "Punch In" "Punch Out" buttons.



Click on the time line to position the playhead before the mistake. Then record as usual. The only section that will be recorded is the region within the punch markers. Click the punch in/out buttons again to turn off.

These simple edits should give you enough to mix down the "best-of" multiple takes and correct small mistakes.

10. After you record several tracks, you can do a initial mix (volume / pan) in the mixer window under:

Window -> Show Mixer

Mixing is a matter of taste and pretty intuitive I think. The main (vertical) slider controls the volume of each track. The horizontal slider (at bottom) controls the left/right panning. The rest of the defaults should be fine.




11. Post processing and effects. With jack-rack you can go to:

Window -> Track/Bus Inspector

to look at the routing and add effects to particular tracks. To add an effect to a track, select the audio track (on the left)

Pre-fader and post-fader means the effect is inserted before and after your volume slider control (on the mixing board). To make things easiest, I prefer pre-fader effects, then I can control the overall volume with the fader.

Then right click. You will get the following options:




These are categorized by the developer which makes them a little hard to find. There is a "Plugin Manager" also, although I'd avoid it for now, since it seems to be a little slow and has crashed more than once (at least on my machine).

A couple general purpose effects that are worth checking out:

Steve Harris -> Multiband EQ
Steve Harris -> Dyson Compressor
CMT -> FreeVerb

By default these effects are by-passed (meaning, off). Click the Bypass button to make them active. Also to compare the signal, you can toggle back and forth between the original and modified signal.

To adjust the effect setting double click on the effect.



A general rule on E.Q. is: to clean up muddy audio, think of cutting a notch in the spectrum for another sound to live in. Two sounds competing for the same audio space will sound muddy. Alternately, two similar sounds might be separated out by panning left and right respectively.

12. Importing existing wav audio files: The easiest thing IMO is to drag a clip from Gnome's file manager (nautilus) onto a track in ardour. This will import the audio, and then you can move it around.

13. Exporting to wav audio file: Use the Range Markers to define the start and stop of the song. To set the region, click and drag in the "Range Markers" time line:



Then go to:

Session -> Export -> Export Range to audiofile

If you are burning a CD, you can usually just drop the wav files onto the blank CD and burn them. Note though that CD audio is 44100 samples per second, and by default ardour records/exports at 48000.

14. If you want to create an mp3's copies, you can open up a terminal window, and run a command like:

lame /path/to/file.wav /path/to/new/file.mp3

This will create a copy of the wav, in mp3 format. I'm sure there's a graphical front end, but if you understand a little about the terminal it's really easier to use use the command line version for this.

Or you could rip a CD after it is complete.

15. Misc:

That should cover mosts all the basics of multi-track recording on Linux.

After you record a lot of audio takes, those unused files are still on the hard drive wasting space. To compress the size of the project, and delete unused audio, select:

Session -> Cleanup

Of course if you plan on doing a lot of multimedia work check out Ubuntu Studio (which is a flavor of Ubuntu optimized for audio/video production).

Also note, you may need to close out ardour when playing wav files off your hard drive (in case it locks down the audio driver).

Thursday, December 4, 2008

SVN -- recursive diffs

It's odd that svn (source control) doesn't have an easy way to see the entire evolution of a file. Since I'm usually wondering how and when something was changed, or just want to see the progression of the changes.

So I just wrote a quick shell script to do this:


#!/bin/bash

# 2008 GPL

if [[ $1 == "" ]]
then

echo "SVN RECURSIVE DIFF"
echo ""
echo "This script will list all svn changes to a file"
echo "the first and last file in the repository"
echo "and a series of diffs that connect them."
echo "IE, you can see the complete evolution of the file."
echo "It's probably best to pipe the output to a file."
echo ""
echo "USE"
echo " svnrdiff "
echo ""
echo "EXAMPLE"
echo " svnrdiff Model/ModelExample.cs > somefile.txt"
echo ""
echo "NOTES"
echo ""
echo "If your log is out of date, use"
echo ""
echo " svn up"
echo ""
echo "If you just want to see who last touched a line, use"
echo ""
echo " svn praise "
exit

fi

v1=""
v2=""
show_current="0"

while read log
do

echo ===================================================================
echo $log
echo ===================================================================

# grab revision numbers of file
v1=$( echo $log | sed -e 's/^r//' -e 's/ .*//' -e 's/-//g' )

if [[ $v2 != "" ]]
then

# print succesive diffs
svn diff -r $v2:$v1 $1

show_current="1"

else

# print first file
svn cat -r $v1 $1

fi

v2=$v1

# list in cronological order (tac)
done < <( svn log $1 | grep -E -e "^r[0-9]+ \| " | tac )

# print last file (if haven't already)
echo ===================================================================
echo "Current snapshot:"
echo ===================================================================
if [[ $show_current == "1" ]]
then
svn cat $1
else
echo "Same as above."
fi

Monday, May 19, 2008

Screaming frog?!

Hmmm ... I didn't know frogs could scream :)

Thursday, April 3, 2008

Elephant paints self-portrait

Wow this elephant is terrible. He draws the feet directly on top of the ground rather than inset. Doesn't he know anything about linear perspective???? :)

Friday, March 21, 2008

giant starfish found

From
http://www.cnn.com/2008/TECH/science/03/21/antarctic.search.ap/index.html


Looks like a giant species of star fish has been found. These guys would look better with faces. I propose that we tattoo faces on all star fish:


Tuesday, November 13, 2007

war haiku

two soldiers each see
a cruel and mindless killer.
young face peers through door.

Monday, October 29, 2007

Robust DHTML

DHTML is the technique of combining JavaScript and CSS to create dynamic page elements that are not possible with static HTML. For example, it's easy to dynamically show or hide page elements, or move them.

Given the differences in broswers, it is by nature a bit difficult to write clean DHTML. And worse, most free DHTML examples of code on the internet are written poorly, as they have countless little browser checks, and conditional code branches like:


if(isIE){
//do something one way
} else if(isNetscape6){
//do something else another way
} else if(isNetscape4){
//do something else yet another way
//...
}


This is poor design, as it is brittle, hard to maintain, and often breaks when new browsers are released or change. And likely, any browser not in the checks will not supprted correctly either. Also I see a lot of newer DHTML scripts doing more css and in place of javascript, although, I still think css support across browsers is still a bit flakey.

A better way is to design something with these simple principles:


1. sniff for functionality rather than browser name/version
2. create a single wrapper function that encapsulates brower specific code
3. page should "degrade gracefully" if possible (meaning the page will still be readable and functional if javascript or dhtml not supported)


Here is a small example designed with these principles in mind (modified from Apple Developer's site):



// cross-browser dhtml utilities
// wrap blocks of html in div> tags with unique id's

// try to get a style object given its id
function getStyleObject( objectId ) {
if ( document.getElementById &&
document.getElementById( objectId ) ) {
// W3C DOM
return document.getElementById( objectId ).style;

} else if ( document.all && document.all( objectId ) ) {
// MSIE 4 DOM
return document.all( objectId ).style;

} else if ( document.layers &&
document.layers[ objectId ] ) {
// NN 4 DOM.. note: this won't find nested layers
return document.layers[ objectId ];

} else {
return false;
}
}

// a template function for setting two-state style properties
function setStyleBoolean( objectId, booleanValue,
propertyName, valueOn, valueOff ) {
var styleObject = getStyleObject( objectId );

if ( styleObject ) {
if ( booleanValue ) {
styleObject[ propertyName ] = valueOn;

} else {
styleObject[ propertyName ] = valueOff;
}

return true;

} else {
return false;
}
}

// try to show/hide object. a empty visual space will remain in place
function setObjectVisibility( objectId, booleanValue ) {
return setStyleBoolean( objectId, booleanValue,
'visibility', 'visible', 'hidden' );
}

// try to insert/remove object from display. page will redraw and no space will remain in place
function setObjectDisplay( objectId, booleanValue ) {
return setStyleBoolean( objectId, booleanValue,
'display', '', 'none' );
}

// try to move object
function moveObject( objectId, newXCoordinate, newYCoordinate ) {
var styleObject = getStyleObject( objectId );

if ( styleObject ) {
styleObject.left = newXCoordinate;
styleObject.top = newYCoordinate;
return true;

} else {
return false;
}
}



This code works in all javascript-enabled browsers I've tested (FireFox 1+, IE 4+, Netscape 4+, Opera), despite having no checks for any specific browser. Also, all code that interfaces directly with the broswer api is isolated, so it is very easy to extend or debug if there ever is a problem.

To use the code above, for example, save it to a file named "dhtmlutil.js" and use it like:



<html>
<head>
<script language="javascript"
src="dhtmlutil.js"></script>
</head>
<body>

<h2>Clean DHTML example</h2>

<div id="test1">
this is a block of html that can be hidden or removed
</div>

<p>
you can change the properties of the
block above with these buttons:

<p> set display
<input type=button
onclick="setObjectDisplay('test1', false);"
value = "off">
<input type=button
onclick="setObjectDisplay('test1', true);"
value = "on">

<p> set visibility

<input type=button
onclick="setObjectVisibility('test1', false);"
value = "off">
<input type=button
onclick="setObjectVisibility('test1', true);"
value = "on">

</body>
</html>



If you add more functions, put them all together in the head with the included file.

to use hyperlinks, use a dead link with an onclick handler like:


<A HREF="javascript:void(0)" onClick="....">


DEGRADING GRACEFULLY

A fundamental problem with DHTML is figuring out how to design the page so that it degrades gracefully. In other words, if javascript or css aren't supported, the user can still use the page. This is especially difficult for menus, and othter page entitties that are hidden/collapsed by default. A menu is the most important element on the screen, and should be viewable on the lowest common denominator. Even if old browsers are obsolete, there is always a chance it won't be compatible with future broswer releases/bugs (for example, the Netscape 6 to 7 fiasco). The general rule is:


4. Any hidden entity should be visible if DHTML is broken.
5. No core functionality should ever depend on DHTML.


The best way to achieve this is to wrap javascript around css elements in the header, such as:



//write styles via javascript, to degrade gracefully
var idx = 'yourid';
if (document.getElementById ||
document.all || document.layers ){
document.write('<style type="text/css">')
document.write('.switchcontent{display:none;}')
document.write('<\/style>')
document.write('<style type="text/css">')
document.write('#' + idx + '{display:block;}')
document.write('<\/style>')
}



This code, for instance, will hide all members of the class "switchcontent," except for the one with the id "sc1". So, if javascript or css is broken, all these entities will be visible. Note that these tags conflict, but that the style closest to the element takes precedence. Corresponding div tags for this code might look like:



<div id="sc1" class="switchcontent">
something visible by default
</div>
<div id="sc2" class="switchcontent">
something invisible
</div>
<div id="sc3" class="switchcontent">
something invisible
</div>