What is this?
Oops, that's a wall of text!There exists a "guy" known as LCOLONQ. From that guy, there is a stream. On that stream, there is a redeem: Bells of Bezelea. With it, you can submit music to be played on the computer. This is how that happens.
In the times before, the Bells were powered by an Emacs Lisp module called muzak.el. It worked by converting the input music notation to a big FFmpeg aevalsrc expression and passing it as a command-line argument. This is a very cool approach, and did prove viable for use on stream, but more advanced usage exposed some practical limitations: Layered notes were very prone to clipping, poor performance meant possibly waiting over a minute before it would start playing on stream, and to try and mitigate these issues, there were limits on what a score could contain.
When I came along and took an interest in the bells, I made a few arrangements by hand, but that quickly became impractical. There were already tools to convert from MIDI, but I wanted to make something more suited to working with MuseScore. This program, which later became muzak compile, was a major boon to my workflow, but made muzak.el's shortcomings more obvious.
Unsatisfied with the status quo, I was taken by a fey mood. The fruit of my labor, muzak-rs, is a command-line suite featuring:
- muzak play: A port of muzak.el to Rust (powered by rodio), fast enough to play music in real time and with reduced clipping.
- muzak compile: A tool to convert MusicXML (a sheet music format for which many music programs have import/export support) to the format used by Muzak.
- muzak submit: A basic way to submit a score directly to LCOLONQ's stream from the command line. If you're already invoking muzak compile, then pasting into the men:u is probably a much bigger hassle than just piping the output into muzak submit.
muzak play also has several enhancements over muzak.el, expanding the musical possibilities while (hopefully) retaining the spirit of the original project:
-
A score can have:
- More than 60 seconds of music
- More than 500 notes
- More than 3 tracks
- More than 4 notes in a chord
- Dynamics, so backing chords can avoid drowning out the main musical voice
- Notes can be flat: no more converting to the equivalent sharp/natural
-
Each track can specify its instrument, rather than being stuck with one "beep" and two "keys"
- The "bells" and "waterphone" instruments, which were unused in muzak.el, are now available.
- At the time of writing, there is also one brand new instrument: the "snare".
Usage
All of the examples below are playable and editable! Click any glowing text to copy it.
The demo on this page uses a WebAssembly build of muzak-rs, so it should produce the exact same audio as command-line muzak play or LCOLONQ's Bells of Bezelea redeem.
If command-line output sounds a bit crunchy, try lowering the --volume. You can increase your system volume to compensate. I don't fully understand the nature of this problem; help is welcome.
Basics
Notes
Each letter up to G is a note. Uppercase for octave 4, lowercase for octave 5. Whitespace is generally ignored.
CDEFGAB cdefgab
Tempo
A number at the very start of the score specifies the BPM of the entire score. The default is 75 BPM, and the basic unit is a quarter-beat.
60 CCCC DDDD EEEE FFFF
Octaves
A number after a note specifies the octave. If octave is specified, then uppercase/lowercase is ignored.
C2 C3 c4 C5 c6
Semitones
A ♯ or # symbol after a note makes a sharp. A ♭ symbol makes a flat.
You can also use ♮ for an explicit natural, if you want to for some reason.
125
gBeBgBeBgBeBgBeB
gc♯ec♯gc♯ec♯gc♯ec♯gc♯ec♯
c6eaec6eaec6eaec6eae
adf♯dadf♯dadf♯dadf♯d
Longer Notes
Adding ~ symbols to a note will extend it by one time unit.
160 E~ F♯~ G~ A~ F♯~~~ D~ E~~~~~
Rests
A / plays no sound for one time unit.
150
e♭~/ f~/ B♭~/ c~/ A♭~ F~
d♭~/ A♭~ / e♭~ / A♭~ / G~ E♭~
Chords
Multiple notes inside a pair of [] will play together. All notes in a chord will use the duration of the longest member note.
69
[G♯d♯g♯~~] c♯~~ d♯~
[D♯B~~~~~] E~
[C♯c♯~~] f♯~~ G♯~
[B3B~] c♯~ [A♯3d♯~~~]
Advanced Notation
Parts (a.k.a. Tracks)
The | symbol will split a score into multiple parts that all play together. Parts share a common tempo, but are otherwise independent.
37
A2C♯3A3B3C♯B3A3E3 D3F♯3C♯EC♯A3~~
A2C♯3A3B3C♯B3A3E3 D3F♯3C♯EC♯A3
|
G♯~~~~~ A~F♯~~~~~
EF♯G♯~~~~~
B c♯~ F♯~~~
Dynamics
A valid combination of the 𝓹, 𝓶, and 𝓯 symbols between notes changes that part's dynamic from that point onward. The valid range is from pianissimo (𝓹𝓹) to fortissimo (𝓯𝓯). The default is mezzo forte (𝓶𝓯), and each step has a gain ratio of (subject to change if someone has a better idea).
90
𝓶𝓹 C3 E♭3 G3 C E♭ G~~~~~~~~~~
𝓹𝓹 [C3C~] [E♭3E♭~] [C3C~] [G3G~] [E♭3E♭~~~] G3~ C~
𝓶𝓹 [B♭2C] D3~~ D G~~~~~~~~~~
[D3D~~~~~~~~~~~] 𝓹𝓹 [G3G] [D3D] [B♭2B♭3] [D3D]
𝓶𝓹 A2 C♯3~~ E3 E~~~~~~~~~~
𝓹𝓹 [E♭3E♭~~~~~~~] 𝓹 [C♯3C♯~] [E♭3E♭] [C♯3C♯~~] [E♭3E♭] [C♯3C♯]
𝓶𝓹 G2 B♭2 D3 G3 B♭3 D~~~~ 𝓹𝓹 [D3D~] [B♭2B♭3~] [G2G3~]
𝓶𝓹 [G2G3] [B♭2B♭3] [D3D~~~] [G3G] [B♭3B♭~~] [Dd~~~~~]
Long Rests
A 🛏️ or 🛏 symbol (i.e., U+1F6CF BED, with or without U+FE0F VARIANT SELECTOR), followed by a number, is equivalent to that many / symbols. This is useful for parts that only participate in certain sections of the score, as a compact way of writing the extended lack of activity.
A 🛏️32 B
Instruments
An instrument symbol at the start of a part will set that part's instrument. By default, the first track will use "beep", and all others will use "keys".
All of the instruments are relatively simple derivations of primitive waveforms. Their source code may be straightforward enough to make sense of.
For all instruments other than the snare, the renderer applies a 1000 Hz low-pass filter to the track as a whole. This filter can make some things sound a bit muffled; I may play around with adding some flexibility here in the future.
∿Beep
A pure sine wave with amplitude 0.8 (at 𝓶𝓯).
This is the default instrument for the first track.
138∿
G♯/G♯/G♯/A♯~~~B~~~~~
c♯~~~~~BA♯B~~~A♯~F♯~
A♯/F♯/F♯~A♯~~~B~~~~~
c♯~~~~~𝓶𝓹[Bb][A♯a♯][G♯g♯~~~][Gg~][D♯d♯~]
105∿
B3DEF♯ABde
f♯~~~~~~~~~~~~~~~~~~~~~~~~~~~
e~b~e~~~~~~~~~~~~~~~~~~~g~~~
f♯~g~f♯~A~~~~~e~B~~~d♯~f♯~baf♯d♯cA
B~~~F♯~~~~~~~G~A~
140∿
B3C♯F♯ABc♯~B/B/e~~c♯~
~F♯~G♯/AG♯/EC♯~~~~//
B3C♯F♯ABc♯~B/B/e~~f♯~
~g♯/e/f♯~~~~//////
🎹Keys
A square wave with starting amplitude 0.5 that decays linearly to 0.25 over the note's duration.
This is the default instrument for all tracks other than the first.
111🎹
//G/G/G/G~D~~~//
G~~~D~G~~~B♭~d~~~
//c/c/c/c~A~~~//
c~~~A~E~~~F~G~~~
|🎹
[G1G2~~~][G3B♭3~][G1G2~][G1G2~~~][G3B♭3~][A1A2~]
[B♭1B♭2~~~][B♭3D~][A1A2~][B♭1B♭2~~~][B♭3D~~~]
[F1F2~~~][F3A3C~][F1F2~][F1F2~~~][F3A3C~][G1G2~]
[A1A2~~~][E3A3C~~~][D1D2~~~][D3F3A3~~~]
160🎹
//𝓯c/G/B♭/A//F//G/
//c/G/B♭/A//F//G/
//c/G/B♭/A//F//G/
A♭//[FB♭]//[E♭c]/[Dd]//[E♭e♭]//d/
|🎹
[CGc~~~]////////////
[E♭B♭e♭~~~]////////////
[Fcf~~~]////////////
|∿🛏48
[A♭2A♭3~~][B♭2B♭3~~][C3C~][B♭2B♭3~~~~~~~]
140🎹
A♯2F3A♯3C♯F♯C♯A♯3F3A♯2F3A♯3C♯F♯C♯A♯3F3
G♯2F3G♯3CFCG♯3F3G♯2F3G♯3CFCG♯3F3
G♯2D♯3G♯3B3FB3G♯3D♯3G♯2D♯3G♯3B3FB3G♯3D♯3
G2D3G3DGDG3D3G2D3G3DGDG3D3
|∿
c♯~~~~~~~c♯~~~d♯~~~
f~~~~~~~d♯~~~~~~~
d♯~~~~~~~d~~d♯~~d~
c~~~~~~~A♯~~~~~~~
1080🎹 𝓯
D3~~~~~~~~ E♭3~~ E3~~ G3~~ B♭3~~~~~ B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ G3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ G3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ G3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //////////////////////// C3~~~~~~~~ E♭3~~ E3~~ F3~~ A♭3~~ A3~~
A3~~~~~ B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ B3~~~~~ A3~~~~~ G3~~~~~ F3~~~~~
B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~ A3~~~~~~~~~~~~~~~~~ B3~~~~~~~~~~~~~~~~~ A3~~~~~~~~~~~~~~~~~ B3~~~~~~~~~~~~~~~~~ A3~~~~~~~~~~~ B3~~~~~~~~~~~ A3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//////////////////////// A3~~~~~~~~~~~~~~~~~~~~~~~ B3~~~~~~~~~~~~~~~~~~~~~~~ A3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//////////////////////// G3~~~~~~~~~~~~~~~~~~~~~~~ A3~~~~~~~~~~~~~~~~~~~~~~~ G3~~~~~~~~~~~~~~~~~~~~~~~ F3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ E3~~~~~~~ F3~~~~~~~ E♭3~~~~~~~ D3~~~~~~~~~~~~~~~~~~~~~~~
|🔔 𝓹𝓹
[E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
[E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
[E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
[E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
[E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
[E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
[E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
[E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [G3B3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] [E3E~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~]
🔔Bells
A square wave with starting amplitude 0.4 that decays exponentially according to . It takes about 4 seconds to become inaudible (and the code explicitly cuts it off at 4 seconds). As such, note duration is basically* ignored for this instrument, and notes can overlap.
This instrument existed in the original muzak.el codebase, but was not exposed for use on stream.
* At the time of writing, there's a bug where short bell notes at the end of a score will be cut off prematurely, because they don't extend the score duration to let them play to completion.
111🔔
//[Gg~~][Gg~~][Gg~~][Gg~~][Dd~~~~~]
///[Gg~~]///[Dd~~]
[Gg~~~]//[B♭b♭~~][dd6~~]////
/////////////
105🔔
G3~~A3~~C~~D~~E~~G~~A~~B~~d~e~
e~~d~~B~~d~~A~~B~~G~~A~~E~G~
|🎹 𝓹𝓹
[C3C~][C3C~][C3C~][C3C~]//[C3C~]//[C3C~]//[C3C~][C3C~]//[C3C~]//
[C3B3~][C3B3~][C3B3~][C3B3~]//[C3B3~]//[C3B3~]//[C3B3~][C3B3~]//[C3B3~]//
111🔔
E♭~~~G~~~GB♭~~G~~~
//G~~~G~B♭e♭~~B♭~~~
D~~~F~~~FA~~F~~~
//F~~~F~D~~~C~~~
[Dd~~~][Gg~~~][Gg][B♭b♭~~][Gg~~~]
//[Gg~~~][Gg~][B♭b♭][dd6~~][B♭b♭~~~]
[Dd~~~][Ff~~~][Ff][B♭b♭~~][Ff~~~]
//[Ff~~~][Ff~][Dd~~~][Cc~~~]
|∿
[E♭2B♭2~][B♭2E♭3~]E♭2~[B♭2E♭3~]E♭2~[B♭2E♭3~]E♭2~[B♭2E♭3~]
[E♭2B♭2~][B♭2E♭3~]E♭2~[B♭2E♭3~]E♭2~[B♭2E♭3~][E♭2F3~][B♭2E♭3~]
[D2D3~][A2D3~]D2~[A2D3~]D2~[A2D3~]D2~[A2D3~]
[D2D3~][A2D3~]D2~[A2D3~]D2~[A2D3~]F2~[A2D3~]
G2~[D3G3~]G2~[D3G3~]G2~[D3G3~]G2~[D3G3~]
G2~[D3G3~]G2~[D3G3~]G2~[D3G3~]A2~[E3A3~]
B♭2~[D3F3~]B♭2~[D3F3~]B♭2~[D3F3~]B♭2~[D3F3~]
B♭2~[D3F3~]B♭2~[D3F3~]B♭2~[D3F3~]B♭2~[D3F3~]
🌊Waterphone
A triangle wave that is initially silent, but ramps up linearly to 1.0 over the note's duration.
This instrument existed in the original muzak.el codebase, but was not exposed for use on stream.
45🌊 𝓯𝓯
E3G3B3G3CG3B3G3
D3G3B3G3B3EB3A
[C♯3C♯]G3B3G3B3EB3G♯
[C3C]G3B3G3B2G3F♯3G3
105🌊
D3E3G3A3B3DEG D3E3G3A3B3DEG D3E3G3A3B3DEG D3E3G3A3
D3E3G3A3[B3B][Dd][Ee][Gg] [D3D][E3E][G3G][A3A][B3B][Dd][Ee][Gg][D3D] [E3E][G3G][A3A][B3B][Dd][Ee][Gg] //
85🌊
A3CGDCDCDGDCD
A3CGDCDCDGDCD
F3CGDCDCDGDCD
A3CGDCE3DEBEDE
15🌊
[ce♭g~][d♭g♭b♭~][cfa~][c♭e♭a♭~]
[ce♭g~][d♭g♭b♭~][c♭fa~][c♭ac♭6][d♭ad♭6]
|🌊
[CE♭G~][D♭G♭B♭~][CFA~][C♭E♭A♭~]
[CE♭G~][D♭G♭B♭~][C♭FA~][C♭Ac♭][D♭Ad♭]
85🌊 𝓯𝓯
D3~F3A3~F~~E~
C~~G3~A3~~//
A3~~B♭3CB♭3~~A3~
G3~~F3~E♭3~~F3~
A3~~~~~~~~~
|∿ 𝓹
FEFGAFEFGA
FEFGAFEFGA
E♭DE♭FGE♭DE♭FG
E♭DE♭FGE♭DE♭FG
🛏10
|∿ 𝓹
D3A3DEFDCD3G3A3
D3A3DEFDCD3G3A3
C3G3CDE♭CB♭3C3F3G3
C3G3CDE♭CB♭3C3F3G3
D3A3DEFDCD3G3A3
🥁Snare
White noise with starting amplitude 0.3 that decays linearly to silence over a fixed duration of 0.15 seconds. This instrument ignores both pitch and duration, but I recommend sticking to the E note for forward compatibility, in case I decide to add other drums to this instrument mappped to other notes.
160🥁
𝓶𝓹E~~~//E~E~~~E~~~
𝓶𝓹E~~~//E~E~~~E~~~
𝓶𝓹E~~~//E~E~~~E~~~
E~E~E~E~E~E~EEEE
|🎹
f~d~A~d~f~d~A~d~
f~c~A~c~f~c~A~c~
e~c♯~A~c♯~e~c♯~A~c♯~
e~c♯~A~c♯~e~c♯~a~~~
|🎹
[D3F3A3~~~~~~~~~~~~~~~]
[F3A3C~~~~~~~~~~~~~~~]
[A3C♯E~~~~~~~~~~~~~~~]
🛏16
138🥁
////E~EE////E~~~
////E~EE////E~~~
////E~EE////EEE~
////E~E~EE~EE~EE
|∿ 𝓶𝓯
G♯3/G♯3/G♯3/A♯3~~~B3~~~~~
C♯~~~~~B3A♯3B3~~~A♯3~F♯3~
G♯3/G♯3/G♯3/A♯3~~~B3~~~~~
C♯~~~~~B3A♯3B3~~~A♯3~F♯3~
|🎹 𝓶𝓹 [G♯d♯~~~][G♯d♯~][G♯d♯][G♯d♯~][G♯d♯][G♯d♯~~~][G♯d♯][G♯c♯]
[G♯e~~~][G♯e~][G♯e][G♯e~][G♯e][G♯e~~~][G♯e][G♯d]
[G♯d♯~~~][G♯d♯~][G♯d♯][G♯d♯~][G♯d♯][G♯d♯~~~][G♯d♯][G♯c♯]
[G♯e~~~][G♯e~][G♯e][G♯e~][G♯e][G♯e~][c♯f♯~~~]
|🎹 𝓹𝓹
G♯2/G♯3D♯3G♯2/G♯3D♯3G♯2/G♯3D♯3G♯2/G♯3D♯3
E2/E3B2E2/E3B2E2/E3B2E2/E3B2
G♯2/G♯3D♯3G♯2/G♯3D♯3G♯2/G♯3D♯3G♯2/G♯3D♯3
E2/E3B2E2/E3B2E2/E3B2E2/E3B2