{"id":2009,"date":"2016-02-11T16:00:51","date_gmt":"2016-02-11T16:00:51","guid":{"rendered":"https:\/\/www.reenigne.org\/blog\/?p=2009"},"modified":"2016-02-10T16:20:50","modified_gmt":"2016-02-10T16:20:50","slug":"the-mut-music-tool","status":"publish","type":"post","link":"https:\/\/www.reenigne.org\/blog\/the-mut-music-tool\/","title":{"rendered":"The MuT music tool"},"content":{"rendered":"<p><a href=\"https:\/\/www.reenigne.org\/blog\/8088-pc-speaker-mod-player-how-its-done\/\">For 8088 MPH<\/a> I wrote a tool to convert Amiga MOD (module) files to the format required for playback with the 4.77MHz 8088 PC speaker 4 channel playback routine. The MOD file solution never felt quite ideal to me because the playback routine has some possibilities (like SID-style ring modulation) which can&#8217;t be expressed in a MOD file and there are also a lot of things you can do in a MOD that won&#8217;t really work with my player, so if I make it easy to try arbitrary MODs with the player, people are likely to try MODs that don&#8217;t come out very well and conclude that the player is rubbish.<\/p>\n<p>What I really wanted was to write my own tracker designed specifically for the player routines I had written (and some variants that I might want to write). But writing a whole tracker is a big project &#8211; particularly the GUI (GUIs take ages and aren&#8217;t the most interesting things to program).<\/p>\n<p>So I started thinking: what&#8217;s the simplest piece of software I could write that a musician could use to compose music for this player? What about a command line tool &#8211; a sort of compiler which accepts text files as input and generates binary music data in the appropriate format (or indeed various formats) as output? This isn&#8217;t entirely unprecedented &#8211; there have been various tools for processing text files into music such as Grigasoft&#8217;s &#8220;Polyphonic Music&#8221; and John Worley&#8217;s &#8220;Clockwork Pianola&#8221;.<\/p>\n<p>This is the design I came up with &#8211; I&#8217;m calling it &#8220;MuT&#8221; (&#8220;music tool&#8221;, pronounced &#8220;mute&#8221;) for now &#8211; it can&#8217;t seem to decide if it&#8217;s a tracker, a musical instrument or a programming language.<\/p>\n<p>Inside the text files we would probably want to have something similar to a more traditional tracker&#8217;s pattern grid, with different channels arranged horizontally and time going vertically. Rather than using semantically-significant spaces and newlines (which cause all sorts of trouble) I think a nice way to do it would be for the musician to lay out the grid using the &#8220;&#038;&#8221; character to separate voices (think &#8220;C &#038; E&#8221; means a C and an E playing at the same time) and the &#8220;|&#8221; character to indicate a new time division (think &#8220;bar is a measure of time&#8221; though the &#8220;|&#8221; interval would usually be shorter than a musical bar, obviously). So an empty grid would look something like:<\/p>\n<pre>\r\noutput =\r\n     &     &     &     |\r\n     &     &     &     |\r\n     &     &     &     |\r\n     &     &     &     ;\r\n<\/pre>\n<p>The spaces could then be filled in with notes:<\/p>\n<pre>\r\noutput = sine@(\r\n C4 & E4 & G4 & C5  |\r\n C4 & E4 & A4 & C5  |\r\n C4 & F4 & A4 & C5  |\r\n D4 & F4 & A4 & D5  |\r\n D4 & F4 & B4 & D5  |\r\n D4 & G4 & B4 & D5  |\r\n E4 & G4 & B4 & E5  |\r\n E4 & G4 & C5 & E5  );\r\n<\/pre>\n<p>Leaving a space blank causes the note in the same voice in the previous division to continue, so this could also be written:<\/p>\n<pre>\r\noutput = sine@(\r\n C4 & E4 & G4 & C5  |\r\n    &    & A4 &     |\r\n    & F4 &    &     |\r\n D4 &    &    & D5  |\r\n    &    & B4 &     |\r\n    & G4 &    &     |\r\n E4 &    &    & E5  |\r\n    &    & C5 &     );\r\n<\/pre>\n<p>If you want to silence a voice, put a 0 in there instead of a blank:<\/p>\n<pre>\r\noutput = sine@(\r\n C4 & E4 & G4 & C5  |\r\n 0  & 0  & A4 & 0   |\r\n    & F4 & 0  &     |\r\n D4 & 0  &    & D5  |\r\n 0  &    & B4 & 0   |\r\n    & G4 & 0  &     |\r\n E4 & 0  &    & E5  |\r\n 0  &    & C5 & 0   );\r\n<\/pre>\n<p>One can also put different instruments into the grid:<\/p>\n<pre>\r\noutput =\r\n sine@C4 & square@E4 & triangle@G4 & bell@C5  |\r\n sine@C4 & square@E4 & triangle@A4 & bell@C5  |\r\n sine@C4 & square@F4 & triangle@A4 & bell@C5  |\r\n sine@D4 & square@F4 & triangle@A4 & bell@D5  |\r\n sine@D4 & square@F4 & triangle@B4 & bell@D5  |\r\n sine@D4 & square@G4 & triangle@B4 & bell@D5  |\r\n sine@E4 & square@G4 & triangle@B4 & bell@E5  |\r\n sine@E4 & square@G4 & triangle@C5 & bell@E5  ;\r\n<\/pre>\n<p>Instrument names are resolved per voice, and &#8220;.&#8221; is (by convention) a sort of default instrument name, so this can also be written:<\/p>\n<pre>\r\noutput =\r\n { . = sine; } .@C4 &\r\n      { . = square; } .@E4 &\r\n           { . = triangle; } .@G4 &\r\n                      { . = bell; } .@C5  |\r\n               .@C4 & .@E4 & .@A4 & .@C5  |\r\n               .@C4 & .@F4 & .@A4 & .@C5  |\r\n               .@D4 & .@F4 & .@A4 & .@D5  |\r\n               .@D4 & .@F4 & .@B4 & .@D5  |\r\n               .@D4 & .@G4 & .@B4 & .@D5  |\r\n               .@E4 & .@G4 & .@B4 & .@E5  |\r\n               .@E4 & .@G4 & .@C5 & .@E5  ;\r\n<\/pre>\n<p>One can make instruments in all sorts of ways. A few simple (chiptune-esque) waveforms are built into the program, or you can load them from a file:<\/p>\n<pre>\r\nbell = load(\"BELL.WAV\")@s\/440;\r\n<\/pre>\n<p>The MuT syntax is extremely flexible and rich enough to do just about any kind of audio processing, and hopefully it&#8217;s also intuitive enough that it&#8217;s not too difficult to figure out how to do just that.<\/p>\n<p>What follows is a more technical and in-depth explanation, so if you&#8217;re not a programmer or mathematician you might want to stop reading here.<\/p>\n<p>Basically most MuT objects are functions from the real numbers to the complex numbers. Both the range and domain of these functions have units (some integer power of seconds &#8211; <code>s<\/code>) which are tracked by MuT so that it can distinguish between time-domain functions like <code>sine@C4<\/code> and pure functions like <code>sine<\/code>.<\/p>\n<p>There are various operators for acting on MuT objects:<\/p>\n<p><b><code>+<\/code> &#8211; pointwise addition<\/b>: <code>output = sine@C4 + square@E4;<\/code> sounds the same as <code>output = sine@C4 & square@E4;<\/code> but it has some different behavior in other ways &#8211; you can&#8217;t do the &#8220;empty space means continue playing the same instrument in that voice&#8221; trick if you use <code>+<\/code> instead of <code>&<\/code> in your grid, and you can&#8217;t use <code>a + b<\/code> as an l-value.<\/p>\n<p><b><code>-<\/code> &#8211; pointwise subtraction:<\/b> same as <code>+<\/code> but the function on the right has its phase inverted.<\/p>\n<p><b><code>*<\/code> &#8211; pointwise multiplication<\/b> (aka modulation). Also useful for volume envelopes.<\/p>\n<p><b><code>\/<\/code> and <code>^<\/code> &#8211; pointwise division and power<\/b> respectively. Mostly for completeness sake, though they do have some uses especially for scalars.<\/p>\n<p><b><code>[]<\/code> indexes into a function<\/b>, just like an array in C or Pascal. So <code>sine[1] = 0.841...<\/code>. When you put a function instead of a scalar inside the brackets, you (naturally) get function composition. So <code>a[b][x] = a[b[x]]<\/code>.<\/p>\n<p><b><code>{}<\/code> allows execution of statements during the evaluation of an expression<\/b>. This is handy for redefining instruments while inside the grid (see example above), or changing the tempo, amongst other things. The tempo (i.e. the amount of time covered by one &#8220;|&#8221; is set by the special variable <code>division<\/code>. So if MuT sees <code>{ division \/= 2; }<\/code> inside an expression, the following grid rows will be played at twice the speed (only durations are affected, not frequencies). The scope of any changes inside <code>{}<\/code> is the remainder of the statement in which it occurs.<\/p>\n<p><b><code>@<\/code> &#8211; basis scale<\/b>. This is where it gets really interesting. This is an operator only applicable to functions, not scalars (so unlike <code>+<\/code>, <code>-<\/code>, <code>*<\/code>, <code>\/<\/code> and <code>^<\/code> it isn&#8217;t found on calculators). Suppose you have a function <code>f<\/code> and a scalar <code>x<\/code>. Then <code>(f@k)[x] = f[k*x]<\/code>. So if <code>f<\/code> is a waveform then <code>f@2<\/code> is the same waveform played twice as fast (and an octave higher). The <code>@<\/code> operator also adjusts domain units if the right-hand side has a value which is not dimensionless. So, if <code>f<\/code> has a dimensionless domain (e.g. <code>sine<\/code>) then <code>f@110*Hz<\/code> (or <code>f@110\/s<\/code>) will be a normal time-indexed waveform (i.e. a sine wave with a frequency of 110Hz). As I&#8217;m sure you can see this is a very useful operator for an audio program!<\/p>\n<p>It gets better, though. Suppose we have a complex unit <code>i = sqrt(-1);<\/code> and we make <code>f@i<\/code> compute the Fourier transform of <code>f<\/code>. Surprisingly, I discovered (after defining it that way) that the mathematics of doing so work out very neatly &#8211; time scaling and Fourier transformations are closely related, mathematically &#8211; they are both <a href=\"http:\/\/en.wikipedia.org\/wiki\/Linear_canonical_transformation\">Linear Canonical Transformations<\/a>, and there&#8217;s a nice mapping from complex numbers to LCTs which gives an (efficiently computable) meaning to <code>f@z<\/code> for any complex number <code>z<\/code>. Using <code>f@i<\/code> in combination with <code>*<\/code> allows us to do convolutions and therefore any linear filters you care to describe (high-pass, low-pass, band-pass, notch, echos, resonances, you name it). Using other complex numbers on the right-hand side of <code>@<\/code> gives us inverse Fourier transforms and fractional Fourier transforms (the musical utility of which I know not, but I&#8217;m sure inventive musicians will find some interesting uses for it).<\/p>\n<p>One can also use a function on the right-hand side of <code>@<\/code>, which will result in a different basis scaling for each sample in the output &#8211; i.e. for scalar <code>x<\/code> and functions <code>f<\/code> and <code>w<\/code>, <code>(f@w)[x] = (f@(w[x]))[x]<\/code>. That&#8217;s how the first non-trivial example above works.<\/p>\n<p><b><code>&<\/code> &#8211; next voice operator.<\/b> This just puts moves to the next voice, as we&#8217;ve seen above. It can also be used on the left-hand side of an assignment: <code>(a & b) = (c & d);<\/code> does the same thing as <code>a = c; b = d;<\/code>. This is useful for grouping values together into a compound object.<\/p>\n<p><b><code>|<\/code> &#8211; time sequence operator.<\/b> <code>c = a | b<\/code> yields a for <code>division<\/code> followed by <code>b<\/code> for <code>division<\/code>. Functions in MuT repeat once they are complete, so if you evaluate <code>c<\/code> in a time sequence with a sufficiently long <code>division<\/code>, it&#8217;ll sound like <code>a | b | a | b | ...<\/code>. Similarly you can loop a <code>division<\/code>-long section of just one function by doing <code>c = a | ;<\/code>.<\/p>\n<p>As with <code>&<\/code>, <code>|<\/code> can be used on the left-hand side of an assignment: <code>(a | b) = c;<\/code> assigns the part of <code>c<\/code> between <code>0<\/code> and <code>division<\/code> to <code>a<\/code> and the part of <code>c<\/code> from <code>division<\/code> to <code>division*2<\/code> to <code>b<\/code>. So by using just assignment, the special <code>division<\/code> variable and the <code>|<\/code> operator you can make whatever edits to a waveform you like.<\/p>\n<p><b>The comparison operators <code>==<\/code>, <code>!=<\/code>, <code>&lt;<\/code>, <code>&lt;=<\/code>, <code>&gt;<\/code>, <code>&gt;=<\/code><\/b> work the same way as their C equivalents, yielding (in general) a function whose values are boolean (<code>true<\/code>, <code>false<\/code>) elements rather than numbers. These can be used with the <b><code>?:<\/code><\/b> operator to combine two functions via a predicate.<\/p>\n<p><b>The <code>%<\/code> operator<\/b> has a couple of uses (which I might change to use different characters). On its own it gives the output from the previous voice in a voice set, which is useful for ring-modulation style effects (such as those that can be done by the SID chip and by my MOD player routine). If it comes immediately after a sequence, it yields a function which is the time-to-index mapping of that sequence. So <code>(a|b|c)%<\/code> is a function that is <code>0<\/code> from <code>0<\/code> to <code>division<\/code>, <code>1<\/code> from <code>division<\/code> to <code>division*2<\/code> and <code>2<\/code> from <code>division*2<\/code> to <code>division*3<\/code>. You can also change the time-to-index mapping of an l-value by assigning to this function. If the time-to-index mapping function takes a non-integral value at any point then the corresponding two elements of the sequence are mixed, so you can create fades and glissandos. Time-scaling the time-to-index mapping function will speed up or slow down the playing of that sequence without affecting the frequencies.<\/p>\n<p>If you combine (via multiplication or basis-scaling) two functions which don&#8217;t have the same domain units you end up with a compound object. When this compound object is basis-scaled, it&#8217;ll move the dimensions of the compound object closer and leave other elements unchanged. So you can create an instrument by combining a waveform (dimensionless domain) and a volume envelope (time domain), and when this is time-scaled the scaling will change the frequency of the waveform part without speeding up or slowing down the volume envelope.<\/p>\n<p>I&#8217;m contemplating a built-in function that will convert a waveform into a sequence so that it can be time-scaled without changing the pitch (or vice-versa) in the manner of a phase vocoder, but I haven&#8217;t quite got all the details ironed out yet.<\/p>\n<p>Arbitrary functions can be defined: e.g. <code>major(x) = x + x@5\/4 + x@3\/2;<\/code> will turn any waveform or function into a major chord using its input as the base note. If we allow functions to be recursive, then (by the Church-Turing thesis) MuT becomes a Turing-complete programming language (for better or for worse).<\/p>\n<p>It&#8217;s handy to be able to have libraries of predefined functions, instruments, values (note frequencies, intervals) etc. Executing an <code>include<\/code> statement will read in a file and insert its contents into the program at that point (much like C&#8217;s <code>#include<\/code> directive). Conventionally, a MuT input file will start with <code>include \"standard.mut\";<\/code> to include the predefined variables which come with the program, or <code>include \"pc_speaker.mut\";<\/code> which does the same but also sets up special variables for the PC speaker output mode.<\/p>\n<p>There&#8217;s some more design documents (which are somewhat out of date but cover a few more dark corners) and the beginnings of an implementation on <a href=\"https:\/\/github.com\/reenigne\/reenigne\/tree\/master\/8088\/audio\/mut\">my github<\/a>. Being a command-line tool, it&#8217;s not terribly user-friendly but it probably wouldn&#8217;t be hard for someone more GUI-oriented than me to slap a user interface on top of it. One fairly simple user-interface for this might just be a special text editor, which plays whatever object is under the cursor whenever a particular key combination is pressed (and which highlights the parts of the MuT program which are being used to compute the currently-playing notes). An interesting enhancement would be a little knob that appears whenever the mouse hovers over a numeric value; dragging this knob changes that numeric value in real-time, changing the currently playing sound if that value is involved in it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For 8088 MPH I wrote a tool to convert Amiga MOD (module) files to the format required for playback with the 4.77MHz 8088 PC speaker 4 channel playback routine. The MOD file solution never felt quite ideal to me because the playback routine has some possibilities (like SID-style ring modulation) which can&#8217;t be expressed in [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,27,9],"tags":[],"class_list":["post-2009","post","type-post","status-publish","format-standard","hentry","category-computer","category-language","category-music"],"_links":{"self":[{"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/posts\/2009","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/comments?post=2009"}],"version-history":[{"count":11,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/posts\/2009\/revisions"}],"predecessor-version":[{"id":2011,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/posts\/2009\/revisions\/2011"}],"wp:attachment":[{"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/media?parent=2009"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/categories?post=2009"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/tags?post=2009"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}