yaymukund’s weblog

Scoring an animation with Orca

In this post, I’ll demonstrate how to score an animation using Orca.

What is Orca?

Orca is an esoteric programming language for composing music. An Orca program is somewhere between a circuit diagram and an ASCII roguelike. But you don’t need to know either of those things to get started— in an interview with its creator Devine Lu Linvega of the programming duo Hundred Rabbits:

I was always kind of aiming, I guess, at children. I was like, if you can just open the page and put that in front of a kid, could they figure it out? It wouldn’t take that many keystrokes until they figure out which… like [the operator] E will start moving, and through the act of playing they’ll find their way without having to read the documentation.

— from Devine’s interview on the Future of Coding podcast

Some resources to get started:

The final score

The completed score, consisting of all the techniques described in this post.

Although it might seem complicated— especially if you’re not familiar with Orca— this program is actually the result of building on a few core ideas. As you read this, I hope it will feel like a natural progression to go from one step to the next.

Ok, now let’s start at the beginning.

What is a score?

Scoring an animation requires timing sounds to events on screen. For example, when a piece of glass shatters in the animation, there should be a crash sound. Let’s say this happens on frame 21. Using Orca, how do you play a sound on the 21st frame and then never again?

The answer to this was not obvious to me. Most Orca compositions, at the time of writing this, consisted of loops. I could not find any examples that did what I wanted. But since we have access to the clock frame using the C operator, this feels like it should be possible.

Here’s one way to do it:

Learning how to wait

Note: Throughout this post, I will refer to hexadecimal numbers using the prefix 0x. For example, 0x10 is decimal 16.

Note 2: I will refer to the last digit in a hexadecimal number as the “ones’ digit” and the second-to-last digit as the “sixteens’ digit.” For example, 0x10‘s ones’ digit is 0 and its sixteens’ digit is 1.

Ok, let’s begin.

First, use a pair of hexadecimal clocks Cf and fCf:

  • The frame count is at the bottom right, a monotonically increasing number.
  • Cf mods the frame count by 0xf, or 16, to output the ones’ digit, a number from 0x0 to 0xe.
  • fCf also divides the frame count by 0xf, or 16, to output the sixteens’ digit.

Next, check the outputs using F. The F operator will output a bang (*) if their inputs on either side are equal.

Finally, AND the outputs of both the Fs into a single *:

  • Y, the ‘yumper’ operator, just copies the input horizontally.
  • f here is a lowercase F that only operates on a bang.

On frame 0x15, the f outputs a bang.

Note: If the f were uppercase, it would incorrectly output a bang when both inputs are empty (i.e. when neither ones’ nor sixteens’ digits matched.)

At this point, I posted my timer to the Orca thread on lines, asking the community if there was a simpler way to do this. Devine responded, suggesting this condensed version that uses one fewer operator.

Limitations

Here, it is important to note that this timer does not actually “bang once and then never again” as originally promised. Since the timer only checks the ones’ and sixteens’ digits of the frame number, it will bang at 0x015, 0x115, 0x215, …— every 0x100 or 256 frames. This ends up being about 25 seconds at 120 bpm.

My animation happens to be 15s long, so this was not a problem for me. If anyone finds an elegant solution to the original problem as stated, I’d love to see it.

Wiring up sounds

Now, the fun part. Use this timer to schedule different sounds.

Playing a note

This can be used to play a single midi note.

Toggling a loop

First, consider a simple drum loop.

Then, use an X to set the note’s velocity, effectively turning the loop on or off. Here, it sets the velocity to 0x7.

It’s a bit silly to use X to set a constant value like this, but it should make sense in the next step.

Finally, automate this using timers:

  • The drum loop begins muted, its velocity 0x0.
  • The first timer at frame 0x15 turns on the drum loop by setting its velocity to 0xa.
  • The second timer at frame 0x28 turns it off again by setting the velocity to 0x0.

Timing a sequence of notes

Play a sequence of notes by combining operators Z and T:

  • The Z counts up from 1 to 5, exactly once.
  • This determines the note output by T.
  • The output of T is fed to :, the midi operator.

Use a timer to control when the sequence plays:

  • Z starts at 5, unlike the previous example, so it doesn’t immediately play.
  • The timer fires at frame 0x15 to activate x.
  • x sets the Z back to 0 and causes it to play.

Timers in practice

At this point, if you go back to the beginning and see the final composition, you may notice some differences from the examples. I omitted details to keep the examples small and easy to understand:

Conclusion

Here’s the completed looping animation:

A hand reaches to water a plant but drops the cup, which shatters. The plant droops, the mug pieces rise and hover in the air above the plant, before falling into the pot which we now see contains a worm. The worm is sliced in half by a piece of mug, its worm blood spreading around the dirt, before gathering and traveling up the stalk of the plant. Zooming in, we see a new stem emerge. Its bud sprouts, revealing it has grown pieces of the same mug fragments. Zooming out all the way, we see the plant is standing up once again. It has an extra stem, which the hand plucks. A worm squirms out of the pot and offscreen, and the entire animation loops.

(If you want to see more of my art, please follow my instagram.)

This is only a small taste of what Orca’s capable of doing, but I hope it’s a fun read. If you notice any mistakes in this article or want to share feedback, please reach out. I’d like to do more of these in the future.