Bitlets (Work in Progress)

Bitlets (Work in Progress)

Table of Contents

overview: what is going on?

setup: code blocks to be evaluated inside of emacs via org-babel.

Part 0: numbers, clock, envelope, oscillator, rever, mul, add: fafa hagoyu fafa pagopa. fafa hayuha yufayu. fafa hadeha fahafa fa.

Part 1: variation on 0: yuyu hagoyu yuyu pagopa. yuyu hayuha yufayu. yuyu hadeha fahafa fa.

Part 2: initial gesture: fafa fathufa hayu fafa pahapa. yuha fayu hayuha fafa hadeha. fahafa fa.

Part 3: gesture continued: fafa fathufa hayu yuhafa. yuyu pahapa faha dehafa. yuyu pahapa faha yuhafa. fayu pahapa faha yuha. fayu hayuha fayu hadeha fa.

Overview

bitlets is an etude series that develops a symbolic language designed to be programmed on the monome grid.

The underlying system is a system called bitrune, which implements a parser capable of reading bitmap "glyphs" 3 bits tall, written on the grid. Each symbol when called, can evaluated a small string of lua code (usually just a single function). These lua functions can then work together to build up sound structures.

To begin, there are no symbols. The process here will involve creating a local set up symbols that can be used together to create etudes. The process will be documented here.

An etude is represented as a set of tiles configured to represent rows of bitglyphs. A graphic representation comes with every etude.

There is also asemic poetry which is procedurally generated (as seen in the table of contents. Some explanation is warranted here.

The poetry is a procedurally generated text-based representation of the bitglyphs on the grid. Each stanza corresponds with a row, and each word corresponds with a glyph. A word is composed of syllables, which outlines the pattern of the glyph itself. Each syllable represents a vertical slice in the glyph. Thus, a bitglyph 4-bits wide will have 4 syllables.

There are a total of 7 syllables: pa, fa, thu, de, yu, go, ha. These syllables are arranged physiologically: the sounds in the front of the mouth, and work backwards.

Setup

For my live coding setup (when this file is an org document).

(chdir "/home/paul/p/tudes/bitlets")
(lil "lua_new lua")
(lil "lua_dofile [grab lua] run.lua")

(define (mac3)
  (display "reloading play.lua")
  (newline)
  (lil "lua_dofile [grab lua] play.lua"))

(define (playtog)
    (lil "hstog [grab hs]"))

I program bitlets primitives from emacs in a pretty silly way.

I leverage org-babel's ability to send things to scheme REPLs. But, I'm mostly programming Lua, because this scheme implementation can't internally evaluate itself too easily. But, I use scheme as a macro language. Core components are wrapped in a small TCL-like called lua.

So, for those keeping score: Scheme evals LIL code, which loads an instance of Lua, and then calls "dofile" to re-evaluate a playground file called "play.lua". This then gets brought back into the core bitlets file.

Part 0: numbers, clock, envelope, oscillator, reverb, mul, add

To begin: numbers.

Numbers will allow some sense of parametric control. At this abstraction layer, supporting any number takes up too much space on the grid.

Instead, a few glyphs will be used to represent some small integer values. These will act less as numbers, and more as switches.

Numbers 1-9 will be implemented. If more are needed, then so be it.

One:

Two:

Three:

Four:

Five:

Six:

Seven:

Eight:

Nine:

Clocks. Clocks are the timing control signal primitive. These can get fed into sequencers and envelope generators. This will take in an integer parameter that will set up what kind of clock there will be.

Envelope. An envelope generator. To be triggered by a clock signal.

Oscillator. This will probably utilize a lot of modes in the future. For now, it is only a steady pitched subtractive sawtooth.

Reverb. Always a good thing to have. Configured to be mono in/out. The default setting will be the big verb I like.

Multiply will be used with the envelope and the oscillator.

Add will be used with the reverb and dry signal.

And finally, an output.

Part 1: variation

Adding some variation to the core nodes.

Clock: make the clock irregular.

Envelope: smaller, more transient.

Oscillator: random frequency.

Reverb: smaller.

Part 2: initial gesture

With some initial test sounds out of the way, my focus now shifts to my previous explorations in Gesture.

I have created a gesture sequencer, which conceptually lies in between a breakpoint line generator, a classic step sequencer and an automation curve editor.

The gesture sequencer works by reading in an external timing signal (known as the conductor), reading a score, and then using the two to synthesize an audio-rate line segment suitable for modulating parameters of other nodes.

Some new mechanisms will be added to our existing library:

A conductor will need to be set up and instantiated. To save space, this will be read by those that need it.

A gesture will be formed in bitrune by declaring a new gesture, creating the score, and then synthesizing the gesture.

The challenge for gesture sequencing is to keep the notation terse yet expressive. Difficult, considering the overall throughput of the Grid.

A decent starting point would be to consider the "page" in bitrune as a unit for containing a single gesture. One can evenly divide up the two tri-strand rows using two 2-width glyphs as bookends (start/end of gesture), and 4 groups of 2 glyph combos, consiting of a 2-width and 3-width glyph.

Another helpful hint would be to consider the notation as not notes, but as "words" or phrases.

So, this is my approach.

Before a gesture can begin, the global conductor must be configured.

Gestures start and end with the following glyphs:

Inside these, gestures can be created. In this case, a test melody.

I've also added some variations to out that mute and quiet.

Mute takes an incoming signal and multiplies it by zero.

Quiet creates a zero signal.

Part 3: gesture continued

The previous etude illustrated a gesture with a completely pre-composed sequence. This will attempt to introduce mechanics with a bit more expressivity, with a sensitivity for brevity.

The approach here will be to construct gesture sequences from smaller pre-composed chunks, whose timing is scaled.

Like before, the conductor is set up (mode 1).

.

Like before, a gesture for pitch is started, with these as bookends:

A new symbol is added, which tells the gesture to create a new phrase 4 beats long.

A pre-defined melodic is placed inside this phrase (melody 2). It fills up the whole phrase:

The phrase is formally closed. This is a new symbol:

Another phrase is created, this time 3 beats long:

The melodic phrase (melody 2) is repeated, and placed inside of this phrase. It has now been compressed to 3 beats instead of 4:

And then the phrase is ended.

One final phrase of is appended to this gesture: melody 3. It is 4 beats long.

This pitch gesture now will feed the oscillator, set to be mode 3. Mode 3 is configured to read the pitch gesture:

The output of the oscillator is fed into a reverb in mode 3. This mode will take in a signal and add the dry and the wet signal together. This saves up valuable screen space:

Finally, the reverberated signal is sent to the speaker:


home | index