Wednesday, December 13, 2006

How can I create my own custom language to generate timed events? ( Part II )

In Part I I've shown how to define a simple custom language. Now I'll show how actions can be taken controlled by the custom instructions in the language.

Generating an Action

The Action component is used to generate an action when a certain parsing rule is matched.The following schematic shows how to generate a Midi NoteOn event for each of the lines in the parsed text.

The rule defined to the right of the Action component is matched twice for the example text of:

N60,2,1N64,1,3

Because the rule is matched twice, the Action component will send an event through the 3rd output also twice. Those two events will flow to a Midi event component which will generate two midi events. The inputs to the component are set to generate a NoteOn midi message with velocity 127 for the Midi note with the integer number parsed by the parsing components and delayed into the future by the number of seconds specified by the first parsed real number. The 2nd real number is ignored for now.

Basically:N60,2,1 = generate NoteOn message for note 60 at current time + 2 secondsN64,1,3 = generate NoteOn message for note 64 at current time + 1 second

We also want to generate NoteOff messages. We can use the second parsed real to define the duration of the note. We can also actually connect the Midi events to a very simple sine wave generator to hear the result as in the following schematic:

Now the meaning becomes:N60,2,1 = generate NoteOn message for note 60 at current time + 2 seconds and a corresponding NoteOff message 1 second laterN64,1,3 = generate NoteOn message for note 64 at current time + 1 second and a corresponding NoteOff message 3 seconds later

We can use our custom language to define a group of midi notes or even a melody, chords etc. It's not the easiest way to edit a song but then again it is a very simple language that can easily be extended to include instructions to control parameters in a synth, like pan, cutoff, to generate triggers for visual animated events, to generate chords from custom chord instructions etc

Here is a more complicated example that demonstrates sequencing several synth parameters with a custom parser.