Pitching and Yapping
Ranjit Bhatnagar put out a call for works for an installation at QuBit's Machine Music event, calling specifically for 26-beat microworks that could be triggered on a Disklavier by each of the barks coming from the little toy chihuahua to the right.
He stipulated that notes could only occur on the yapped beats (quarter note = 344). Without having to worry about the dimension of rhythm, I thought it would be a perfect opportunity to explore algorithmically generated pitch! First though, some background on the progress I've already made with pitch selection in JALG.
Choosing Pitch Collections
I have made several modules that allow me to create pitch collections to feed into other modules. The simplest is is [jalg_manualchord]. This allows me to either peck out a chord on the onscreen keyboard, or enter notes via MIDI keyboard. Another module, [jalg_randomrange], outputs a random value within a selectable range (0-127, more useful for velocity or control data, though its could be scaled to create a range of pitches).
Being able to input notes is great if I'm improvising at the keyboard, but it could take a long time to enter all the notes I want to use. A bounded range is simple enough, but it would allow for any chromatic series of pitches. And what about storing the pitch collections I like for later use? I decided to tackle these questions early on, with a module called [jalg_chordstore]. Using [jalg_chordstore], I can add multiple chords to a list, and then save it as an indexed collection. This is great if I'm coming up with chords to enter in on the fly via [jalg_manualchord] or something. But it can recall existing chords too!
I went to an old, undeveloped sketch in my notebook that was simply a sequence of 12 chords, deciding to use them to build the pitch material for some yap iterations. It was built in two phrases that were the same except for their last chord:
I entered in the notes in Sibelius, exported the whole sequence as a MIDI file, and ran it through a little utility I made called [jalg_seqtochord] that could take the individual chords and store them in a text file readable by [jalg_chordstore]. An example of how it works is below.
Now for some yapping.
I've loaded the chords into a [jalg_chordstore]. I can feed it a number 0-11 (corresponding to each of the chords), and get the corresponding chord out. Here's an example of the sequence in order, triggered by a [counter] at the tempo specified by the yapping dog (repeated to fill up the entire 26 beats):
I made some velocity adjustments to the notes so the whole thing wouldn't sound so robotic. I like contracting nature of the chords in the original sequence, but nothing is really happening, simply playback. Maybe I can preserve some of that nice, contracting voicing in the original sequence, but add a little chance to it. The [drunk] object is perfect for this! [Drunk] outputs a random number within a "step range." For example, if the initial number is 6 and the step range is 3, the next number [drunk] outputs can either be from 6-9 (±3 steps). The next output is then ±3 from there.
Since I want to preserve voice leading, I'll make sure the module can move only up or down by one step. Setting an initial value randomly, away we go for 26 more yaps:
Whoops! See those big leaps in the second system? It's due to the fact that there is a large leap in the original sequence - the repetition of the phrase. We started on chord 2, but there's a leap from chord 6 to chord 7. This is just a function of the input material though; I could thin down the list so that there were only 7 chords (accounting for the different last chord), instead of duplicates of 5 of them. This is something I'm going to have to keep in mind when inputting sequences into [jalg_chordstorage]. Unless I want repetition, I have to make the source list as lean as possible.
Before the next iteration, I removed duplicate chords from the list - now only 7 chords to choose. Throwing voice-leading out the window, I used an [urn] object to select every chord before repeating any of them.
I randomized velocities of every note to give it a little variety. 26 beats allows for all seven chords 3 times (with 5 extras). Repetition of the sequence, in part or in full, is very likely from such a small number of chords.
Octave Displacement
Every iteration so far has been in the middle of the piano. What if I want to preserve the chords, but distribute them across the keyboard? The Disklavier isn't bound by the limits of the human hand, so why not get a chord going across the whole piano at once? The concept of octave equivalency is natural to our perception and practice of music, so in effect, notes displaced by octaves are really articulating the same harmony. The module [Jalg_octave] exploits this phenomenon to create textural variety.
[Jalg_octave] takes a note in, and adds or subtracts random multiples of 12 to the incoming note: e.g. -12 = 1 octave lower; +24 = 2 octaves higher. The possible multiples added or subtracted can be adjusted by a range slider - up to four octaves above or below. If no range is defined (slider has a difference of 0 between upper and lower bounds), the note will always be transformed by the single amount shown on the slider.
However, these transformations are always kept in between a range defined by an input object such as [jalg_ranger]. If the transformed note is outside of the range, octaves are added and subtracted to the pitch within [jalg_octave] until it falls within the range specified. So the note that ultimately comes out of [jalg_octave] is not necessarily the transformation specified by the "random octave ops." This could be a feature for great control. For example, I could have notes in one module stay within only a few octaves, ensuring that a generated melody stays in an instrument's idiomatic register. But with [jalg_octave], pitches are not restricted to their original register!
An unfortunate limitation of [jalg_octave] so far is that it can only take one note at a time. For this particular chord collection, I'll need to make six parallel versions of it, each taking one pitch output from the [jalg_chordstore]. I'm using [zl scramble] to shuffle the outgoing pitches, and then [cycle] to distribute each member to its own octave module. Each module will be able to output a pitch across the full keyboard (one [jalg_ranger] controls the range for all six). To really hear the effects of octave displacement, I'm going to play the chords in sequence again, like in the first iteration, but now with octave displacement.
Woah. That is some crazy stuff. It seems chaotic, but I can definitely hear the chord progression despite all the wild displacement. I think I might end up with something more palatable if I were to limit the ranges individually.
I got 99 problems and a pitch ain't one
There's a lot more that will go into choosing pitch, let alone beginning to put pitch and rhythm choices together. [jalg_chordstore] and [jalg_octave] won't be the only modules I use to select pitches. But even just with them and a few other simple objects, there'd be more rules I could add to the mix, even for this simple chord progression. Off the top of my head:
-Chord 7 in the unduplicated chord can only be played after chord 6 has been played once. This would shuffle the chords but still end with the differing final chords of the original phrases.
-Chord 1 is never transposed.
-Chord 3 is twice as likely to move to Chord 4 than to any other chord.
If you happen to be in NYC later this week, you can catch some of the results from this blog post along with a few other iterations, and many other micro-pieces by other composers (not to mention many other cool Disklavier things)! Brought to you by a yapping chihuahua and an automated piano.