Shhhhh….recording in progress

Everyone’s been asking about the new Seneca Hawk record so I thought I’d post an update. Here’s a status matrix of the songs

Track “main street”* Las Cruces Light from Light “Wind that bends all things”** Bloodburner Hot Sky
Takes 2 1 2 1 1 3
Drums y y y y y y
Bass y y y y y y
Rhythm Guitar y y y y y y
Lead Guitar y y y y
Aux Guitar y y
Aux Track 1
Aux Track 2
Aux Track 3
Lead Vocals
Background Vocals 1
Background Vocals 2

To summarize this table, we have bass and drums for 6 songs, guitars for 4 songs. For these six songs, we still have to track vocals and some additional auxiliary parts like piano, organ, tambourine, etc. One we complete tracking for these 6, we’ll record another 4 - 6. We’re going to finish tracking the next time we see Adam Lasus.

Recording has been really fun and challenging for me. Because we’re using analog 2-inch tape, I can’t really f*ck up. And if I do f*ck up, we have to stop taping and start over again. Kyle and Jonah can punch in if they need to (they didn’t really need to though - Kyle punched-in maybe twice), but drums is a different story. The reason you can’t punch in drums is mainly because of the complexity of micing drums. We used 4 close mics, 2 overhead mics, and 3 room mics. Getting a seemless punch-in on tape would require me to play the drums with the exact same time, volume, feel and pressure on all drums. If I were good at this, I’d probably be a professional studio musician. This is why you just start over. Because by the time it takes you to punch-in, align the two different drum tracks, get them to sound seemless, you could have just recorded 10 more versions of the same track. In the digital world, punching in is easier (mainly because sewing up parts is easier), but is still very difficult for drums.

Tape forces you to keep tracking until you get the take you’re satisfied with. This is unlike digital recording where you can settle for a decent take and just rely on post-production to clean up the mess-ups. But that’s not to say there aren’t a few mess-up on the record. There are, but these are the good mess-ups, the accidental “i didn’t mean to hit that drum, but it actually sounds really cool” mess-ups. This is exactly why the old recordings have more character than the new pro-tools era recordings: they had more mess-ups, more imperfections, more idiosyncrasies. Most drum recordings today sound perfect, too perfect - all the cymbal hits sound exactly the same and the pressure of each bass drum note is exactly the same. Also, most singing today sounds too in-tune. It’s lost a bit of that human feel, as if a real person were singing to you. The recording process has been mechanized and digitized. I read an interesting quote by a producer whose point was that today’s producers and engineers record with their eyes, not their ears. This is exactly true - I’ve recorded 2 prior albums, and we spent a lot of time looking at the waveform in pro-tools to see if the bass and drums lined up and to see if it “sounded” good. That’s pretty idiotic. It’s like trying to listen to your computer noise to see if your photoshop work “looks” good.

Hmmm…I ended up ranting about pro-tools. Anywho, back to the recording. Even though tape is harder to record to, I’m very proud to say that we nailed some songs on the first take. This we can attribute to our chemistry, our recent tour and our collective improvement as musicians. I’m a much better drummer now than I was when I recorded my first record. So far, I’m most proud of Las Cruces. We just nailed the feel of that song, and we got it on the first take. It has a bottomless pocket, a feel I’ve been trying to achieve for years. I’m excited to share it with everyone…hopefully we’ll release some early cuts and mixes…

I have a lot more to say, but between recording, helping to launch myspace’s developer platform, and the holiday season, I’m spent.

* So we don’t have a name for this song yet. In true band fashion, I gave the song a crappy (yet somewhat catchy) working title which we used during recording so Adam had something to call it.
** We don’t have a title for this song either, but we’re temporarily using a line from the song.

Bananas are a ticking time-bomb

bananas

Here’s the problem: You buy a bunch of bananas at the store and initially, they’re all green. Then one day…BOOM!!!…they’re all ripe at the same time. Now it’s a race against time. You might even have to eat two in one day. It’s banana overdose. Then you get sick of them and don’t want to buy bananas for a month. Then you miss them and the whole process begins anew.

Here’s my solution: Bananas should be sold individually, like apples. And stores should keep bananas at a variety of ripeness stages. This way, I could buy several bananas and enjoy them immediately and for the rest of the week. This doesn’t preclude stores from selling bananas the old-fashioned way, but it just offers the CHOICE of enjoying a bunch of bananas on MY schedule.

Ultimately, it’s a question of power. Why do bananas make the rules? And why do they all gang up against me?

This is a pointless rant on bananas. I’m sorry if you read this all the way through. God help you.

Getting the selected (or de-selected) ListBoxItems in WPF

Getting the ListBoxItem during a selection event used to be much easier in standard winforms. In the new SelectionChanged event in WPF, you don’t get the ListBoxItem that generated the selection event, you get back the data item that was used to bind to that ListBoxItem. So how do you get the ListBoxItem? It’s actually not so hard, you just have to ask the ItemContainerGenerator to give it to you. For example:


void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBox listBox = (ListBox) sender;

// handle selected items
foreach (MyClass datum in e.AddedItems)
{
ListBoxItem listBoxItem = (ListBoxItem) listBox.ItemContainerGenerator.ContainerFromItem(datum);
// do something with the listBoxItem
}

// handle deselected items
foreach (MyClass datum in e.RemovedItems)
{
ListBoxItem listBoxItem = (ListBoxItem) listBox.ItemContainerGenerator.ContainerFromItem(datum);
// sometimes this can be null
if (listBoxItem == null)
break;

// do something with the listBoxItem
}
}

Starting and stopping an iterator

Sometimes you want to stop and start an iterator and continue from where you last stopped. For example, in the code below, we ask for 2 names, stop and then ask for 3 more names.


static void Main(string[] args)
{
NameSource nameSource = new NameSource();

// get 2 names
foreach(string s in nameSource.GetNames(2))
{
Console.Out.WriteLine(”{0}”, s);
}

// get 3 more names
foreach (string s in nameSource.GetNames(3))
{
Console.Out.WriteLine(”{0}”, s);
}

Console.ReadLine();
}

To have the iterator know where it left off, we simple store the current place in the iteration in state variable. For example, in the code below we store the index of the current item being iterated over in the state variable ‘current’:


public class NameSource
{
///


/// Keeps track of the names already returned and starts off where it left off.
///

public IEnumerable GetNames(int amount)
{
for(int i = 0; i < amount; i++)
{
yield return strings[current++];
}
}

///


/// initialize state variable ‘current’
///

private int current = 0;
private static readonly string[] strings =
new string[] { “ankur”, “buster”, “ricardo”, “jerome”, “constantine”};
}

Actually, the article title is a misnomer. We’re not actually starting and stopping the same iterator, we’re creating two iterators that are referencing the same state variable. This makes it appear as one continuous iteration.

Logging the machine name (hostname) in Log4net

If you have a web farm where all servers are logging to the same place, then you’ll likely need to log the machine name as part of the log message. You can use the conversion pattern %P{log4net:HostName} to output the hostname. So, here’s what that looks like in context:





Invoking ASP.NET Web Services using a GET Request

To enable your .asmx webservices as GET requests, simply add the following to Web.config in the System.Web section. This will also fix the class of errors with this description: “Request format is unrecognized for URL unexpectedly ending in /MethodName”

Karate Typing

This game is awesome.

Decompressing a dict-formatted dictionary file using gunzip

For some reason this took me an hour to figure out. If you have a dictionary formatted in the dict database format, i.e. a .dict.dz file, you can decompress it using gunzip. That is, you don’t need the dictunzip tool, which is probably unavailable on a windows machine. The trick with using gunzip is to just specify the correct suffix (file extension). For some reason gunzip checks this before attempting to decompress. The command looks like this:

$ gunzip --suffix="dz" english.dict.dz

This command will generate an english.dict file that you can open in any ascii text editor.

Tracking UPS / Fedex / etc Packages Using isnoop.net RSS and Google Reader

isnoop.net Tracking is a great little site that shows you your package / shipment status in a google map. You can visually see the geographic location of your package as updated by the shipping carrier. They also generate you an rss link to your tracking page. You can copy this link and add it as subscription in Google Reader. I created a subscription folder called “Shipments” that has my multiple isnoop.net tracking rss feeds. This has been a great way to monitor all my shipments.

Uploading (’Putting’) binary files to Amazon S3 in C#

So I’ve had a technology crush on S3 since it came out but I’ve only recently started to explore it. After downloading the C# S3 SOAP sample code, the first thing I tried to do was upload a jpeg. The upload was pretty easy, but upon trying to access the file via the s3 url, I only received an unintelligible string sequence. Opening it in a hex editor proved that the file didn’t get uploaded as a byte sequence, but as one long string. The reason, it turns out, was that I was using the wrong api call (duh), the call that accepts a string parameter:

public PutObjectResult put(string bucket, string key, string obj, MetadataEntry[] metadata, Grant[] accessControlList)
{
DateTime timestamp = AWSDateFormatter.GetCurrentTimeResolvedToMillis();
string signature = makeSignature(”PutObjectInline”, timestamp);
ASCIIEncoding ae = new ASCIIEncoding();
return s3.PutObjectInline(bucket, key, metadata, ae.GetBytes( obj ), obj.Length, accessControlList, StorageClass.STANDARD, false, awsAccessKeyId, timestamp, true, signature, null);
}

To use this call, I had to convert my byte sequence into a string, which was then converted to another byte sequence using an ascii encoding. That process corrupts your original byte sequence because not all bytes fit into the ascii spectrum. But where was the correct method signature? It turns out it was omitted, at least in version dated 2006-10-13. Adding the following method to AwsConnection.cs fixed my upload woes:

public PutObjectResult put(string bucket, string key, byte[] objBytes, MetadataEntry[] metadata, Grant[] accessControlList)
{
DateTime timestamp = AWSDateFormatter.GetCurrentTimeResolvedToMillis();
string signature = makeSignature(”PutObjectInline”, timestamp);
return s3.PutObjectInline(bucket, key, metadata, objBytes, objBytes.Length, accessControlList, StorageClass.STANDARD, false, awsAccessKeyId, timestamp, true, signature, null);
}