Ziffers - Numbered musical notation

Just added new syntax support for note lengths and note names. Ended up adding fractions as one option to define note lengths. Degree notation can now be parsed from note names using zpreparse:

print zpreparse "1/4 cdefg - cab", :c
# Prints 1/4 12345 - 167"

This notation can also be played with zplay when using parsekey parameter. These examples all play the same melody:

# Original ziffers degree notation 
zplay("|:q1231:|:q34h5:|@:e5654q31:|:q1-5+h1:@|", key: :e, scale: :major)

# Same melody using fractions as note length / sleep
zplay("|:1/4 1231:|:34 2/4 5:|@:1/8 5654 1/4 31:|:1 -5+ 2/4 1:@|", key: :e, scale: :major)

# Same melody with note names in c, transposed to e
zplay("|:1/4 cdec:|:ef 2/4 g:|@:1/8 gagf 1/4 ec:|:c -g+ 2/4 c:@|", parsekey: :c, key: :e)

# Same melody using Z escape char and float
zplay("|:Z0.25 cdec:|:ef Z0.5 g:|@:Z0.125 gagf Z0.25 ec:|:c -g+ Z0.5 c:@|", parsekey: :c, key: :e)

You can add as many spaces as you want to make it more pretty and spaces are also important when “escaping” value from Z or fraction. So options options options, but it all parses to nice hash array to play with.

1 Like

Helm’s cool. There’s a bunch of LV2 plugins which work on Raspbian through MODEP. Though it doesn’t have a full UI in this context, TAL Noisemaker is among my favourites.
Almost makes me want to go back to my Ubuntu MATE laptop. Got two Linux DAWs (Bitwig and Tracktion Waveform). Only one is Raspbian-friendly (Tracktion Waveform).

Here’s new experimental ziffers util that maps keyboards white keys to degrees and prints ziffers notation after you play some notes. Big thanks to @robin.newman for his posts about midi stuff.

You can use this code to play sort of “always on key & scale” instrument and record ziffers notation on the fly. Still pretty experimental and no support for octave changes. Tested it only with VMPK but planning to buy some fancy micro synth like QuNexus.

1 Like

G is for arpeggios. Just added some support for chord arpeggios using subset of ziffers notation. For example when using G1 before chord i, it would then play first note from the chord array. Here are some examples:

zplay “G1232 |: i^7 :4|: %-1 iv^dim :4|”
zplay “Gq12e+3212 |: i^7 :4||: %-1 iv^dim7 :4|”, key: :d4, scale: :mixolydian

Custom chords can also be used like: G123 i {1,3,5} v

1 Like

Played more with the arpeggios and added support for more octaves and random generation of integer sequences. I had to remove some less used functions like random key because the buffer limit is causing issues.

Random arpeggio sequences can be generated using:

(1,3,3) = any random 3 numbers between 1 and 3.
(1…3) = suffle numbers between 1 and 3.
(1…7,3) = suffle numbers between 1 and 7 and pick 3.

This sample plays 6 random notes for i v and vi chords. N2 is used to set number of octaves in a chord:

zplay “N2 G(1,6,6) i 0 v 0 vi”

Same as before but ensures that each note is unique:

zplay “N2 G(1…6) i 0 v 0 vi”

This syntax can also be used in combination with […]-choose from array syntax to produce more interesting semirandom melodies:

live_loop :arpeggios do
zplay "N3 G[1324,e32q123,(3…7,4)] %-1 ii^m9 v^add13 %2 i^maj9 %-2 vi^m9 ", key: :f3


I wanted to reopen this topic because this is really a great language for playing with Sonic-Pi. I was well aware of various numerical notation systems because of my musical background (from J.J. Rousseau to set-theory) but this one really shines for electronic music composition. Obviously it’s difficult to learn because of its concision (and precision! ) but I really want to spend some time learning the syntax.

I’m really curious to know how you developped the syntax. Did you started from the basic knowledge of numerical music notation or are you using it on a daily basis in your musical practice? I think that your language could be a great teaching tool, even outside of Sonic-Pi. It could also be used for musical analysis and other related fields of research. I wonder if there is a music notation software that can handle this kind of notation. It would dramatically decrease the time needed to input notes and write down ideas.

Have you any plans for extending and adding new functionalities to the language? It may not be the first thing you are willing to work on, but I feel that an alternative version of this language just to work on rhythms could be a thing too.

I’m really impressed to see that such a dense musical notation can handle both melodic notation, harmony, structure and rhythm. I’ll work with it in the next few days and I’ll post some code if I come up with something good.

Thanks for your Ziffers notation system!


Hi! Thanks for your kind feedback. I havent had much time to work on this projects lately. I’v been using it time to time as a way to produce some melody lines for generative trance tracks.

I developed ziffers trough series of experiments. I only knew some kind of degree notation used to teach xylophone melodies to kids (Note to self: Electronic xylophone with OSC support would be a kickass project). I was more familiar with the standard notation and abcnotation. When I started to use Sonic Pi I didnt know MIDI at all so I found it easier to imagine melodies as simple integer arrays and later started to parse melodies from strings with the note length characters. At first it was just a parser for integers [1-7], octave changes[-,+] and note lengths, but soon realized that degree based notation could also be used for random and generative melodies. So it just gradually got more complex from different experiments. :slight_smile:

I havent found any other “computable” degree based notations. There are some similarities with the lydown and abcnotation which also include the rendering aspects of the standard notation. It should be fairly easy to do a script that would transform ziffers to abcnotation or lilypond which are already supported in some software like Musescore. Personally I find ziffers more suitable for trying out musical ideas as changes in intervals and rhythms written in multiple threads with the Sonic Pi language, which goes far beyond the features of ziffers. Nevertheless, I think that there is a lot of research potential in this sort of “semi” computable, calculable and generative notation.

There’s some unimplemented ideas in the issues page like the custom notation for samples. Do you mean something like that? Feel comment or add new ideas. Also, if you write any songs using ziffers those are more than welcome to the examples section.

There’s also some other undocumented features in utils like zdrum which plays melody with “drum like sound” or zbin as binaurally. There’s also some undocumented features like inverting melodies and other stuff that can be used to create harmonies. I think that in the end ziffers just got too big of a mess to manage with the limit to the buffers size and all … maybe at some point it would be a good idea to rewrite ziffers in ruby as an extension to the Sonic Pi language.

1 Like

It could be one way of doing it indeed. It would definitely be fun. One letter for one sample and the regular rhythm messages. Basically, what I really like about Ziffers is that it is really really concise, and by using it, I can skip writing a bunch of stuff that I’m normally obliged to write for playing melodies and rhythms. For instance: sleep(ring 0.5, [0.25, 0.75].choose, 0.5, 0.25, 1).look is really long for a one loop sample rhythm generator. Ziffers can handle both the sample and the sleep time in two characters.

I don’t know if this solves the problem of buffer size, but I’m using Ziffers by declaring it in my init.rb file. I added two require "~/.../ziffers.rb", one for each file, and a custom function called ziffers_guide that I use to post a very concise documentation help in the Sonic-Pi logs. This way, I don’t even have to copy and paste anything, Ziffers is already available when Sonic-Pi starts. One time install.

I don’t know anything about Ruby, but I think that Petal, another Sonic-Pi extension package that I really love, is using pure ruby for some parts. Maybe this can give you an hint about how to build big extension projects.

That’s basically why I am so excited about it. Real-time text-based composition/notation tool. It’s really good when you have to search ideas, and even to notate or to keep a track of improvised performances, etc… I can definitely imagine creating a repo of different Ziffers snippets ready to fire when I need them.

I wonder if using some kind of ziffer notation with real musicians improvising along could work. There is definitely a learning curve to the language. But one can imagine traditional musical score markings, annotations, symbols, etc… added to the notation.

Right now I can already use the MIDI Out functionality to do some basic sequencing for modular synthesizers, DAWs, Max/MSP or other things like that, but something like a platform-neutral Ziffers sequencer could be awesome. I really want to learn Ruby now so I can decipher your code and work onto something inspired by your approach.

Well, to sum up, I think that different flavors of Ziffers could be great. I can’t do anything to help right now (I haven’t been able to break the wall between me and real programming yet), but if you decide to work again on Ziffers, I think that a lot of people could appreciate your work.

I may have some suggestions that I can post on the Github page. It could be easier to keep track of suggestions and commentaries.

EDIT: Ziffer used for sequencing both Sonic-Pi synths and digital modular-synths (Audulus)

Link to a soundfile: Sonic-Pi + Ziffer + Audulus.

Cool. Just tried to use Atom’s Sonic Pi plugin to develop the code. It’s still a bummer that i have to restart the Sonic Pi every time i make changes to the required code. It seems that Sonic Pi is caching and only restarting the application will load the new version. Anyway, just added some new features for creating random sequences, variable assignation and generation specific rules for lsystems. Tried to generate some brownian motion using regular expression with the lsystem:

zplay " 1 1 1 ", rules: {/(?<= ([1-9]) ([1-9]) )/=>"0.6%=<?=(-3,3)>' $1+?' '$2+?' "}, gen: 12

Still failing at it but getting there. Those zeroes are bugging me … i’v been thinking that i need some switch that makes the degrees go from 0 to 9 instead of 1-9 with 0 being rest :slight_smile:

It surely requires some relearning … but i dont think that the basics are much more complicated than for example the Nashville system. Maybe some simpler variant of the language could be used in live music minus the generative syntax which is kinda hard to compute by human brains.

Thanks … and Audalus looks nice. I’v been playing with sunvox and helm. Cool MIDI out songs are also welcome to the examples section with some kind of comment about the type of synth used.

I think that it could be a general improvement to the system, just to be in tune with the other traditional numerical notation systems.

It is also difficult to read and compose this way, but it may be what’s so interesting in this approach. I’ve never really tried to play with the generative aspect of Ziffers. The thing I like the most, definitely, is when a notation symbol is completely exhaustive, when one symbol is representing a very simple musical operation on pitch, time, expression, etc…

I might do something about that if you want some midi tunes to illustrate the system. I’ve spread the word about the system to other live-coders online too.

EDIT: Have you still planned to work on some kind of sample notation system ? (Like “X O X O”, etc…)

Dunno, which system uses 0-9? Zero as musical rest is used at least in chinese practice.

The 0 doesnt really matter until you start to use generative syntax, sequences etc. So it could be just a flag for those cases (eg. startFromZero). Anyway, generic or not 0 could then be ‘r’ like in lilypond.

Wheels on the bus (current syntax):

zplay "q14e44q46 8640 5310 8641 q4e44q46 8640 h5q.1e1h.4", key: :f

Would change to:

zplay "q03e33q35 753r 420r 7530 q3e33q35 753r h4q.0e0h.3", key: :f, startFromZero: true 

For me the most appealing thing is the relative exactness that allows retuning and reshifting of the melody by calculating.

Not yet, but will start on it next. I think it also need some new char to denote “sleep until sample is over”. For example: ‘b’. So it would be something like:

zplay  "b X X e XX h O O", samples: {"O"=>:drum_heavy_kick, "X"=>:drum_snare_hard}

It could be also possible to combine degrees to samples in a sequantial or simultanious fashion. Like with the chords “i 1234 iv 3422”. But in order that to work there would have to be different sleep notation for the samples … and I think that X is currently reserved for chord sleep but i havent used that much, usually i use generic parameter for all chords like chordSleep: 0.5.

EDIT: I think i found a better way to do this, and I totally forgot that there was a special note length ‘z’ for zero length. In some cases it may lead to “out of sync” if timing is not reseted afterwards, but in this case it works. The numerous sample options could also be passed via separate object so that you can set multiple options to a single character, like:

zplay " z B q M M M M", samples: {"M": :bd_tek, "B": {sample: :ambi_choir,opts:{hpf: 100, beat_stretch: 2}}}

Sample specific sleep could also be assigned to the opts for the sample_duration case that overrides the normal note length characters (q,w,e, etc.).

zplay "q 123 B B B", samples: {"B": {sample: :ambi_choir,opts:{rate: 0.2, sleep: (sample_duration :ambi_choir) }}}

Wow, that’s great. I think that using r for rest is a clever choice. I know that 0 is used in some systems but in my opinion, I think it’s important not to use numbers for things that aren’t notes, degrees, etc… 0 is confusing because some people might think that 0 is the foundation, the root note, etc… The distinction between numbers and letters is very clear and without confusion. I’m not really neutral when I think about that, but I think that using numbers in the same fashion than set-theory is a good way to find some kind of musicological standard.

I’ll try to play with the sample notation as soon as I can, to see what I can come up with. I love it so far.

zplay " z B q M M M M", samples: {"M": :bd_tek, "B": {sample: :ambi_choir,opts:{hpf: 100, beat_stretch: 2}}}

This syntax is cool, a bit tricky to approach at first, but I think that it’s just a matter of getting used to it.

1 Like

Ok, there’s a new version that can play samples with custom character assignation. Sequential and simultanious samples plays together quite nicely.


Tried to understand how set theory has anything to do with the numbered notation and was suprised that there is such a thing as musical set theory :sweat_smile:

EDIT: Had a quick read about the musical set theory and it seems to be more about chromatic scales and atonality, where as numbered notation is about tonality and use of degrees in certain scales. Am i right? Some ideas from it might be applicaple to tonal melodies as well. However, im still bending towards the 0…9 notation as it solves the problem. Created issue about it. Sadly it will break all of the written melodies, but those are quite easy to fix.

I didn’t had much time to play with Ziffers recently but things will be better in the next few days. I want to try to make at least a complete improvisation / composition using it. I tried the sample notation and it works really well. It’s also very easy to keep track of the parameters of each sample by formatting the text just a bit.

I’m now using it both as a way to sequence things in Sonic-Pi itself and to communicate with my other synthesizers by using midi. This is really the most advanced sub-language I know of in Sonic-Pi and I think that it’s possible to really go far using it. I especially love using it with a modular synthesizer, launching sequence and slowling mutating them.

Yes, it’s confusing at first but I almost forgot that there was a non-musical set theory after a while, ahah.

You’re both right and wrong. It’s not about chromaticism but the basic analytic tool is indeed the pitch-classes, a circular space of notes from C to C, but abstracted from any notion of pitch (it could be C2, C4, C7, we don’t care). It’s a very abstract way of seing music. The most useful and exciting tool there is in set-theory is maybe the pitch-class sets, the possible combinations of different pitch-classes. (Actually, it’s like an array of X pitch-classes).

You’re right about the fact that this theory was mostly used to describe, talk and compose atonal and contemporan music. But there is nothing in that theory that forces you to only care about atonal materials. Some people used this as a way to find new modal flavors, or new ways to escape their improvisational / compositional routine.

But if you look closely, some pitch-class sets are just the major / minor triad, things like that.

I think that’s cool. My suggestion was just to use 0 as a way to represent the first note of every given thing in Ziffers; maybe as an option like you were suggesting in another post. This way you can accomodate both people willing to follow some derivative of the chinese system, and people willing to use some kind of computational generative / set-theory infused notation.

EDIT: Having fun transcribing some Johnny Cash tunes right now.

Thanks for pointing these out. I think these ideas will be really useful for developing the ziffers language. I see pitch-class sets as quite similar to what sequences generate in the ziffers language. I think i will work on the sequence syntax next as well as the zero-based integer syntax. Interval vector is also a nice idea which could be used to control the generation of random sequences.

It’s easier to add the option for set-theory notation, like “Ziffers.setZeroBased true”, and it doesnt break existing melodies. However, the ‘0’ to ‘r’ isnt such a big change so im changing it as default … and actually then the calculations work nicely in both notations. When using degree based (1-9) notation 0 wont do anything.

Sounds great. It would be great to have such songs in the examples when ready. Nice thing about testing is to just listen to some examples to confirm that those still do sound the same.


… Aaand new version is out. Changed the rest character and added support for zero-based numbering as well as refactored sequence randomization syntax a bit.

Degree vs. set-theory influenced notation can be used like this:

zplay "q321r q321r e11112222 q321r"

Ziffers.setZeroBased true

zplay "q210r q210r e00001111 q210r"

zplay "0123456789TE", scale: :chromatic

Ziffers.setZeroBased false

This is soooo dope (as the young people say :slight_smile: ).

Thanks so much for sharing-- can’t wait to give it a go!


@amiika I think I’m doing something wrong; this code is outputting major chords, rather than the expected minor chords:

require “~/src/ziffers/ziffers.rb”
zplay “i iv v”, chordSleep: 1, scale: :minor, key: :c

Can you help me out?


Hi @bcgreen24

Chords are not using the scale-parameter, as one would expect. There is no in-built mechanism in Sonic Pi to create chords like chord( :i, :mixolydian) etc. Currently chords are built using the chord names as defined in the Sonic Pi help in “chord” section, or you can print out the chord names using:

print chord_names

Default chord name is major so it was playing that instead of minor. Chord names can be changed using this syntax:

zplay "i^min i^maj ii^m7+5-9"

I also added chordName as a parameter so if you reload the project you can now use:

require "~/src/ziffers/ziffers.rb"
zplay "i iv v", chordSleep: 1, chordName: :minor, key: :c 

Fantastic-- thank you so much!