mike hodnick

Point your browser to www.hodnick.com for Mike's latest content.

Notice:

You are viewing Mike's old, archived site. For new content, navigate to hodnick.com

Latest From Twitter...

The Blog

Just a friendly reminder that you should NOT be viewing this RSS feed! :) This site was moved a while ago.

If you are, then re-point your RSS reader to http://feeds.feedburner.com/kindohm

-Mike

Late last night I hooked up my new web site: www.hodnick.com. It's time to move on. You can read more about the switch here: http://hodnick.com/post/234645379/another-beginning

If you are reading this through an RSS reader or feed program, hopefully you are using my Feedburner RSS url: http://feeds.feedburner.com/kindohm. Please double-check your subscription url in your feed reader program and make sure it points to that url.

I'll be keeping kindohm.com up and running for archival purposes, but I will no longer add new blog content to it.

-Mike

 

I've been working on a fluent interface API for producing synthesized audio in Silverlight. Keith Dahlby originally suggested this idea to me, and as I've been testing my own complex signal chains in code I decided it was time to implement the idea. Setting up signal chains using a more conventional syntax was just getting too tedious.

I've been using Charles Petzold's Simple Sequencer as a base and have tweaked and modified the code to include support for frequency modulation, amplitude modulation, and panning.

To set up a simple signal chain with a mixer, here is what the code looks like:

StereoPcmStreamSource source = new StereoPcmStreamSource();

Mixer mixer =
   Oscillator.Create(440)
      .FrequencyModulate(150, 50000000)
      .AmplitudeModulate(77)
      .Pan(short.MinValue)
      .Attenuate(-6)
      .SendToMixer();

   Oscillator.Create(640)
      .FrequencyModulate(130, 51000000)
      .AmplitudeModulate(55)
      .Pan(short.MaxValue)
      .Attenuate(-6)
      .SendToMixer(mixer);

   Oscillator.Create(540)
      .FrequencyModulate(140, 53000000)
      .AmplitudeModulate(45)
      .Pan(short.MinValue)
      .Attenuate(-6)
      .SendToMixer(mixer);

   Oscillator.Create(740)
      .FrequencyModulate(160, 59000000)
      .AmplitudeModulate(41)
      .Pan(short.MaxValue)
      .Attenuate(-6)
      .SendToMixer(mixer);

source.Input = mixer;
this.media.SetSource(source);

The code above generates a "droning" sound with four oscillators under heavy and fast vibrato. Two oscillators are panned hard right and the other two are hard left.

The main idea is to make it easier to set up signal chains. Contrast the first oscillator setup code above with this conventional approach:

Mixer mixer = new Mixer();

Oscillator osc1 = new Oscillator();
osc1.Frequency = 440;
osc1.FrequencyModulator.Amplitude = 150;
osc1.FrequencyModulator.ModulationFrequency = 50000000;
osc1.AmplitudeModulator.ModulationFrequency = 77;
Panner pan = new Panner();
pan.Pan = short.MinValue;
pan.Input = osc1;
Attenuator attenuator = new Attenuator();
attenuator.Attenuation = -6;
attenuator.Input = pan;
mixer.Inputs.Add(attenuator);

Ouch.

The next step is to integrate the fluent interface with UI controls. What good is this code if you can't tweak the parameters on the screen?!