Archive for March, 2008

Who do ya gotta do at Google

Tuesday, March 25th, 2008

Google wouldn’t know harmful content if it sucked them off for $50.

Google! Fix this stopbadware flagging nonsense!

They are totally unresponsive despite repeated requests for review. They don’t even mention what they object to – I’ve read their guidelines – I see no problems. As far as I can see – Google IS the badware.

Google boycott starts now. Because this is evil.

Mike Arrington, Software Pirate

Monday, March 24th, 2008

The ever clueless and abrasive Mike Arrington says something even more ridiculous than usual. I can see both sides of the Bebo thing and frankly, social networking makes me yawn. I have no patience or interest in it. Seems like a phenomenal waste of bits to me. Musicians uploaded their music without expectation of compensation. So sure, they’re probably not ‘entitled’ to a payout. OTOH, Bragg’s point is well taken – the musicians made them successful and it would be a nice gesture to give back. But I wouldn’t hold my breath on that. They’re internet entrepreneurs. Thus greedy bastards by definition.

OTOH, the thing that really ticks me off is this little comment by Arrington.

…it costs exactly the same to produce one copy of the song (the first one) as 10 million copies. Simple economics takes over. Free.

Which, if true, implies that Microsoft ought to be giving away Vista, Office, and everything else. Because Music is Software. It costs as much to develop as software, it takes every bit as much time, talent, and skill.

Just because you can make a second copy for a buck, doesn’t mean that’s all it is worth. If it costs $30k to record a song (which is kind of typical these days), and we are expecting to sell 100 copies, then this song needs to make $300 per copy to break even. If its 10 copies, then its $3000 a copy. The same economics apply as software. Just like there is free software, shareware, and commercial software, there are many business models around music. No single model is right all of the time.

Arrington should stick to his little blog about the shiny things – he obviously knows fuck all about the economics of creation.

Music IS Software

Monday, March 24th, 2008

Reprinted from my old blog – written in 2002.

I’ve been having a discussion with Amy Wohl on this copyright stuff. I don’t think I’ve quite made the point I’m trying to make. I think I’m a witness to one of the greatest hypocracies ever placed squarely in the public eye.

Perhaps I’m in a unique position. It could be that
I have special powers of insight. I can’t tell.
I know this much. I’ve been a professional
performing and recording musician as well as
songwriter. My one public triump was winning a local
radio sonwriting contest in Albuquerque New Mexico
around 1985. I was proclaimed “The hottest band in
New Mexico”. Technically it was a recording project
performed by myself, computers and friends.

I am presently a professional software sytems architect and developer.

And I am amazed.

The very short thesis is that somedevelopers are simultaneously calling for greater access to music, video and entertainment by while insisting that software is different and must be more protected.

The argument for pushing for online access to music is that the increased sales more than compensate for any losses from pirating. The recording industry is labeled as fearful and unwilling to trust the users. Those music people ought to be ashamed!

The take away is that improved access to creative works increases sales. I think this is true.

These same people bristle at the suggestion that improved access to their creative works might also improve sales. Now we’re holding a gun to their head they say. Releasing my ten year old source code will ruin me!

The software industry is trying to rely on the same mechanisms that the recording industry relies on. That copying a work is technically infeasible and should stay that way. The music industry used to keep control by releasing inferior copies that degraded with successive generations of copying. The software industry keeps control by refusing to release source code.

With the advent of digital music, the music industry has lost its built in copy protection. Yet the software people say “have courage”. “Increased exposure will increase your sales.” The numbers seem to imply that this is true.

Of course, if we turn the tables and require the same of software developers they cry “foul”.

Fueling the fire is the rising indignation regarding the ever growing term of copyright. A couple of legal luminaries have begun to fight this on the grounds that the public good is being subverted in the name of corporate profits. A really good explanation of why copyright terms aren’t forever is described in this paper by legal professor Glenn Reynolds.

For those with short attention spans, the paper basically says providing permanent copyright impedes progress because nobody can afford to build on the work of the past. But no copyright impedes progress because nobody is incented to produce new inventions if they can’t make money from them. So a middle ground – limited term copyright (or patents – these also expire) – allows inventors to both build upon the work of the past while getting paid for their work. Its a good mechanism that has been subverted in the name of corporate profits. Because long term copyright holds our culture hostage.

A great example is the Happy Birthday song. It is said to be among the top 3 best known songs in the english speaking world. But it remains encumbered. Unlike the music of the great composers which is all in the public domain now, the song Happy Birthday, truly a core part of our culture, remains a hostage of Warner Communications. This is the best example of copyright abuse I know of.

Of course the software people all agree. Those greedy corporations! Free Mickey Mouse!

The upshot of this uproar is that people are beginning to realize that long term copyright holds our culture hostage, that creative works ought to eventually pass into the public domain.

Even software works.

But they don’t. When a software company goes bust or simply changes direction, old products die. They don’t get updated. The source code disappears. Files written by the software containing content owned by other people become inaccessable. Imagine if this happend to all of our creative content.

The original music business was so primitive that songwriters made money by selling you the sheet music to the song and you had to perform it yourself. Completely open source. Still, Stephen Foster and Scott Joplin made plenty of money in spite of sharing. Today, their works are in the public domain and they are a much loved part of our history and tradition.

Sadly, this isn’t happening with software. Although if Lessig gets his way, that will change and source code will be escrowed to be released into the public domain at the expiration of copyright. This is the duty of the copyright holder and beneficiary.

I suspect that part of the fear among closed source developers is that their work will be borrowed piecemeal and new products built upon it without their being compensated. But they get a ten year lag before that will happen. Thats better than Van Halen got when Tone Loc sampled the opening drum riff for “Jamie’s Cryin” for his “Wild Thing”, or the deal David Bowie and Queen got when Vanilla Ice borrowed the signature riff from “Pressure” for his “Ice Ice Baby”.

It would be very hard to argue that Van Halen lost any record sales to Tone Loc or that David Bowie and Queen lost sales to Vanilla Ice. The financial loss isn’t real. In much the same way that casual Napster downloaders weren’t going to buy the music they pirated anyway, the loss is impossible to quantify in any financial way.

Its called fair use and in general its good for everybody. But it takes courage to see it. Source code must pass into the public domain on expiration of copyright. Its the right thing to do for everybody.

JambaLaya site updated with documentation

Thursday, March 20th, 2008

mainscreen.png

Today I uploaded a whole bunch of shots and comments – primarily to serve as a proxy for a user’s manual. It is such a straight forward simple app, I can’t imagine it needs much of a manual. Basically live music performance oriented MIDI and audio processing.

Anyhow, check it out. http://www.audiofreakshow.com

About the only thing preventing a full on launch is the back end stuff to take payments and issue serial numbers, and finishing up the serial number handling in the application. It doesn’t adequately cripple things if there is no serial yet. Few more bottlenecks to install checks into. Also, one little bug with lyric editing. Minor, but a little annoying.

Curse You Google!

Thursday, March 20th, 2008

A friend sent me an email telling me my site has been blacklisted by Google – largely because some spammer (die, spammers, die) hacked a message and put a bunch of link spam in. I really have to question the security of wordpress. If they can’t keep it clean, I’ll have to migrate to something else.

There is an interface to request removal from the blacklist, but while you can be blacklisted in seconds, it apparently takes several days to get off of the blacklist. Nice.

JambaLaya approaching final candidate

Wednesday, March 19th, 2008

I’ve been working on it like crazy, stomping bugs and adding polish. It is pretty close to RC. Still need to add registration and complete the website infrastructure to automate dispensing of serials. I’m sure it will be huge because I just added the killer must-have feature.

Behold – Murph and the MagicTones Mode!

murphaboutbox.png

JambaLaya covered in “Thick Red Shag!” No other Audio Units host has that! Take that MainStage!

JambaLaya Website Updated

Monday, March 17th, 2008

I finally got the JambaLaya website looking decent – installed Drupal’s forum module, did a lot of work on a theme. It needs more marketing stuff – more recent screen shots and better feature exposition – but as a start its not bad.

If you’ve downloaded JambaLaya and tried it – the place to report bugs is definitely in the forums.

JambaLaya Updated

Monday, March 17th, 2008

New beta released

Download it.

Release Notes

Lots of new goodies including integration with external synthesizers, full audio IO capabilities, note doubling (stacking octaves and 5ths), and it is much leaner on resources.

The Audio IO bit arrived just in time as I joined a group purchase of AmpliTube 2, AmpliTube Jimi Hendrix Edition, and some other goodies. This let me route my guitar into one of the inputs on my MOTU UltraLight, set up the AmpliTube as an effect, and get some really sweet guitar sounds. No more lugging a guitar amp around!

Addressing HAL Devices with Apple’s Core Audio in JambaLaya

Sunday, March 16th, 2008

I play guitar and keyboards in a rock band for fun. I’m basically a guitarist, but I have this knack for programming things, like computers and, as it turns out, synthesizers. Thus, I always end up doing some keyboard work in any band I play with. I have a lot of classic hardware synthesizers from the 80’s. But these days a lot of software emulations for hardware have come out and I use these as much as possible.

Occasionally, however, there is no replacement for an external synthesizer. It would be great if JambaLaya could present and allow routing to the hardware instruments in the same way as it does software instruments. While I’m at it, I might as well add support for audio routing. Currently JambaLaya just uses the default audio device and plays to its default outputs.

An AudioUnit MusicDevice takes in MIDI control information and outputs audio signals. A hardware synth does the same, but to get its audio, I have to map it to an audio input in my audio interface and then sort of pretend that the audio is generated from the device. The idea being a hardware synth is a midi endpoint, channel, and audio input set. While I’m at it, I might as well provide HAL support and allow any kind of audio routing the user wants. My live audio interface is a MOTU UltraLite. It has 12 audio inputs and 14 audio outputs. It also acts as my MIDI interface. The goal is to make a hardware synthesizer look and act just like an AudioUnit MusicDevice.

AUGraph Channels vs Busses

AUGraph connections connect BUSSES. A buss can contain many channels. How many is determined by setting the AudioStreamBasicDescription on the kAudioUnitProperty_StreamFormat for the buss. Each node in an AUGraph has a number of input and output busses. For some AudioUnits, the number of busses are fixed. Most MusicDevices just have one output buss. Others, like the MatrixMixer can be configured with any number of busses.

Connecting Busses

To connect busses, you make node connections using

AUGraphConnectNodeInput(graph, sourceNode,sourceBussNumber, destinationNode,destinationBussNumber)

Before you can do this though, you have to configure the busses on both sides by setting kAudioUnitProperty_StreamFormat using an AudioStreamBasicDescription on both sides to make sure the signal formats and number of channels is compatible. If you don’t do this, things don’t work the way you expect. This is especially true when connecting a mixer because the number of channels in the stream format determines the number of channels in mixer. The total number of input channels in the mixer is the sum of the number of channels of each of its input busses. Same for the outputs. This is why configuring stream formats is so important. Furthermore, you cannot change the stream format after making the connection – you’ll get an error. So, always configure both stream formats prior to connecting nodes.

Mapping Audio IO in HAL Devices

HAL devices present their IO channels all in one buss. All the audio inputs (in jacks) are presented on a single output buss for the device. All of the audio outputs are presented on a single input buss. Confused? THE TERMINOLOGY OF INPUT vs OUTPUT in a HAL DEVICE is VERY CONFUSING. This took me many days of experimentation to figure out and is the primary motivator for writing this article.

To begin with, all HAL devices are referred to as Output Devices, regardless of whether they do input, output, or both. In the case of the MOTU UltraLite, one device does both jobs, but you could use different devices for input and output. HAL devices are not at all configurable with respect to what audio appears where – so to do any kind of routing, you want to stick a matrix mixer in front of it, then work with that to do signal routing. Thus, your application will most likely have a matrix mixer representing the audio inputs, and a matrix mixer representing the audio outputs.

AudioIO2

Creating the Output Device

First you need to add a node to your AUGraph to represent your HAL device.

AUGraph graph;
OSStatus status=NewAUGraph(&graph);

// Description for HAL Output Device
ComponentDescription halAudioOutputDescription={
kAudioUnitType_Output,
kAudioUnitSubType_HALOutput,
kAudioUnitManufacturer_Apple};

// Create a node to represent the IO device
AUNode outputDeviceNode;
status=AUGraphNewNode(graph, &halAudioOuputDescription, 0, 0, &outputDeviceNode);

// get the component instance so we can initialize the device -
// nothing works until the device is initialized
ComponentInstance instance = 0;
status=AUGraphGetNodeInfo(graph, outputDeviceNode, 0, 0, 0, &instance);

// initialize the device
status=AudioUnitInitialize(instance);

//Get the identifiers of the default audio input and output devices

AudioDeviceID outputDeviceID;
AudioDeviceID inputDeviceID;
UInt32 size=sizeof(AudioDeviceID);

status=AudioHardwareGetProperty ( kAudioHardwarePropertyDefaultOutputDevice, &size, &outputDeviceID );
status=AudioHardwareGetProperty ( kAudioHardwarePropertyDefaultInputDevice, &size, &inputDeviceID );

//Now you must enable the device for audio output.

UInt32 value = 1;
status=AudioUnitSetProperty(instance, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &value, sizeof(value));

If we are using the same device for input, enable it for input too. IMPORTANT! The hardware’s OUTPUT channels appear on BUSS 0. But the INPUT channels are on BUSS 1! Why? What’s the significance? I DON’T KNOW! But keep this in mind as it will come back to bite you when connecting the input mixer.

if(inputDeviceID == outputDeviceID)
{
inputDeviceNode=outputDeviceNode;
status=AudioUnitSetProperty(instance, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &value, sizeof(value));
}
else // signal an error - you can only have one output device in the graph

// Set the AudioDeviceID on the HAL device to map it to the right piece of hardware
status=AudioUnitSetProperty(instance, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &outputDeviceID, sizeof(outputDeviceID));

Creating the Output Mixer

If you were just interested in mapping hardware inputs to outputs, you could get by with a single matrix mixer and set matrix channel volumes to route audio. But it seems more natural to connect nodes to make connections – especially when mixing in Audio Unit Music Devices (virtual instruments). So I create a mixer for each interface, then connect various busses between them like a patch bay. You create the mixer pretty much the same way as the HAL device.

// Description for the matrix mixer
ComponentDescription matrixMixerDescription={kAudioUnitType_Mixer, kAudioUnitSubType_MatrixMixer,kAudioUnitManufacturer_Apple};

// Create a node to represent the mixer
AUNode outputMixerNode;
status=AUGraphNewNode(graph, &matrixMixerDescription, 0, 0, &outputMixerNode);

// get the component instance so we can initialize the device - nothing works until the device is initialized
ComponentInstance instance = 0;
status=AUGraphGetNodeInfo(graph, outputMixerNode, 0, 0, 0, &instance);

// initialize the mixer
status=AudioUnitInitialize(instance);

The output device node’s audio is fed into INPUT BUSS 0 which has one channel in it for each OUTPUT jack on the device. So you only need a single OUTPUT BUSS on the mixer, which you will connect to the INPUT BUSS 0 of the OUTPUT DEVICE. Refer to the picture if you’re getting confused.

UInt32 busCount = 1;
status=AudioUnitSetProperty(instance, kAudioUnitProperty_BusCount, kAudioUnitScope_Output, 0, &busCount, sizeof(busCount));

Prior to connecting the nodes, you want to make sure the number of channels and sample rates match. THIS IS CONFUSING! The stream description for the INPUT bus of the OUTPUT device for the device’s OUTPUTS is gotten by asking for the stream format for the OUTPUT device’s OUTPUT stream format for BUSS 0. Read that a couple times. Because you have to copy that stream description to the INPUT BUSS 0 of the output device and the OUTPUT BUSS 0 of the output device prior to connecting the busses. Here we go.

// get the node instance for the output device
status=AUGraphGetNodeInfo(graph, outputDeviceNode, 0, 0, 0, &instance);

// get the OUTPUT stream description for the OUTPUT device to set on the DEVICE's INPUT BUS 0 and MIXER's OUTPUT BUS 0
AudioStreamBasicDescription streamDescription;
UInt32 size=sizeof(AudioStreamBasicDescription);
status=AudioUnitGetProperty(instance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &streamDescription, &size);

// set the format on the INPUT BUS 0 of the OUTPUT DEVICE
status=AudioUnitSetProperty(instance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &streamDescription, sizeof(streamDescription));

// get the node instance for the output mixer
status=AUGraphGetNodeInfo(graph, outputMixerNode, 0, 0, 0, &instance);

// set the format on the OUTPUT BUS 0 of the MIXER
status=AudioUnitSetProperty(instance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &streamDescription, sizeof(streamDescription));

// connect the busses - OUTPUT BUS 0 of the MIXER to INPUT BUS 0 of the OUTPUT Device - hard to keep straight I think
status=AUGraphConnectNodeInput(graph, outputMixerNode,0,outputDeviceNode,0);

Now you can configure the input side of this mixer anyway you like. For instance, you could create a bunch of stereo pairs and then attach Audio Unit Music Device’s to them. Or some stereo pairs and a few mono inputs. Think of it as one side of your patch bay.

Creating the Input Mixer

This code is very similar – only for reasons that I don’t understand, all of the action on the INPUT side of an OUTPUT device occurs on OUTPUT BUSS 1. First we create the mixer as before.

// Create a node to represent the mixer
AUNode inputMixerNode;
status=AUGraphNewNode(graph, &matrixMixerDescription, 0, 0, &inputMixerNode);

// get the component instance so we can initialize the device - nothing works until the device is initialized
ComponentInstance instance=0;
status=AUGraphGetNodeInfo(graph, inputMixerNode, 0, 0, 0, &instance);

// initialize the mixer
status=AudioUnitInitialize(instance);

The output device used for INPUT has an OUTPUT BUSS 1 buss with one channel in it for each INPUT jack on the device. So you only need a single INPUT BUSS on the mixer, which you will connect to the OUTPUT BUSS 1 of the output device used for input. Refer to the picture if you’re getting confused.

UInt32 busCount = 1;
status=AudioUnitSetProperty(instance, kAudioUnitProperty_BusCount, kAudioUnitScope_Input, 0, &busCount, sizeof(busCount));

Now we need to setup the stream formats for the OUTPUT BUSS 1 of the DEVICE and INPUT BUSS 0 of the MIXER. You get the correct stream format for the OUTPUT BUSS by getting it from the DEVICE INPUT BUSS 1. THIS IS VERY CONFUSING!

// get the INPUT stream description for the OUTPUT device used for INPUT to set on the DEVICE's OUTPUT BUSS 1 and MIXER's INPUT BUSS 0
// REMEMBER that the INPUT description is found on ELEMENT 1

// get the device instance
status=AUGraphGetNodeInfo(graph, inputDeviceNode, 0, 0, 0, &instance);

AudioStreamBasicDescription streamDescription;
UInt32 size=sizeof(AudioStreamBasicDescription);
status=AudioUnitGetProperty(instance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 1, &streamDescription, &size);

// set the format on the OUTPUT BUS 1 of the DEVICE used for INPUT
status=AudioUnitSetProperty(instance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &streamDescription, sizeof(streamDescription));

// get the node instance for the input mixer
status=AUGraphGetNodeInfo(graph, inputMixerNode, 0, 0, 0, &instance);

// set the format on the INPUT BUS 0 of the MIXER
status=AudioUnitSetProperty(instance,kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input,0,&streamDescription,sizeof(streamDescription));

// connect the busses - OUTPUT BUS 1 of the DEVICE to INPUT BUS 0 of the MIXER - THINK HARD!
status=AUGraphConnectNodeInput(graph,inputDeviceNode,1,inputMixerNode,0);

Now you can configure the outputs of the input mixer into any combination of busses and channels you like. To make a connection, just connect an output buss from the input mixer to an input buss on the output mixer.

Hopefully this will help someone else because it took me days to figure this out as CoreAudio’s documentation is really sketchy.

Looking for work again

Monday, March 3rd, 2008

I’ve been doing a lot of PHP lately – shopping cart integration, web service clients, lots of ecommerce stuff. But I’m coming to the end of these projects and am looking for new challenges. Got a project or position that I can do remotely? Drop me a line.