Faunatone is a tracker-style microtonal MIDI sequencer. Since MIDI does not have any widely-implemented native support for microtonality, Faunatone uses pitch bending to play non-12edo pitches. The tradeoff is that in this model, you cannot generally have more than 15-voice melodic polyphony without experiencing artifacts, although GM 1 only guarantees 16 melodic voices anyway.
Management of individual output MIDI channels by the user is not required; Faunatone operates in terms of virtual channels which it maps dynamically by default.
This guide assumes some basic familiarity with tracker interfaces and MIDI. It attempts to cover the main points of interest but is not a complete tutorial.
Download and extract a build of Faunatone for your platform from the project page if you haven't already.
Since Faunatone does not include any kind of sound generation capabilities, you
will also need a MIDI-based synthesizer (software or hardware) for it to
interface with. Windows has one built-in. One option for Linux users is
FluidSynth. Regardless of platform, anything that supports GM 1 should work.
The default index of the ports Faunatone connects to for MIDI output and input
can be changed in config/settings.csv; you can view port indices using the
commands in the MIDI menu.
If you manage to connect an output to Faunatone after startup, pitches may not be correct until you select MIDI -> Send pitch bend sensitivity RPN.
If you are familiar with tracker interfaces (Renoise, OpenMPT, SunVox, etc), you will probably not have trouble picking up Faunatone. Faunatone does make a few significant departures from "conventional" trackers:
Also, percussion notes are entered by holding the Shift key. The keymap for percussion notes is separate from the keymap for melodic notes.
On the left side of the window are the beat numbers, counting upwards from 1 at the beginning of the song. There are no "rows" or "patterns", just one continuous sequence of events. The song ends when the last event is reached. To leave time for instruments to "fade out" as a song ends, place an additional functional event some distance after the last functional note off in the song. Events are processed in left-to-right order for each tick.
Most trackers use a fixed number of rows per beat; Faunatone allows you to
freely change how many units the interface divides beats into. Events that do
not align with the current division are drawn as transparent; the degree of
transparency is configurable via config/settings.csv.
In Faunatone terminology, a "track" is a vertical sequence of events, and a "channel" is equivalent to the MIDI definition of the term. Any number of tracks can be mapped to the same channel. Channels do not have individual polyphony limits, but only one note can be "on" at a time in each track.
Note that although channels are MIDI-equivalent, they are not mapped one-to-one onto output MIDI channels. The mapping is dynamic and determined at playback/export time; each new note is assigned to the MIDI channel that has least recently had an active note, cutting an existing note off if there are no other options. This design facilitates arbitrary note pitches via pitch bending, which operates on a per-MIDI-channel basis.
As a general rule, commands that affect tracks, events, or the selection itself operate on the entire selection. When inserting most types of events, an identical event is inserted into each track in the selection. For note on events (melodic and percussion), the pitches of an input chord are distributed across the selected tracks. You will need to select multiple tracks in order to play chords, even in keyjazz mode.
Percussion notes using the GM percussion map can be input by holding Shift. The percussion keymap does not change with the melodic keymap, since they serve different functions.
Because there are no "columns" in Faunatone, event parameters are not directly addressable with the cursor like they are in most trackers.
In search-style dialogs (file dialogs, program change, set controller, drum note, and text event), results are filtered by the input string. Results can either match exactly, by prefix, by substring, and by word prefixes, in that order of precedence. Pressing enter with incomplete input will automatically expand the input to the top search result, except in save and export dialogs, where input must be explicitly expanded with the tab key.
Keyboard shortcuts are configurable in config/shortcuts.csv.
New - Replace the working song data with an empty template.
Open... & Save as.. - Load/save a song from/to the saves/ folder.
Export MIDI... - Export a Standard MIDI File (.mid) of the current song to
the exports/ folder.
Quit - Stop the program.
From start - Play the song, starting at the first beat.
From top of screen - Play the song, starting at the top of the current viewport.
From cursor - Play the song, starting at the beginning of the current selection.
Stop - Stop playback, as well as silencing any currently playing notes.
Previous division & Next division - Move the selection up or down by one beat division.
Previous track & Next track - Move the selection left or right by one track.
Note... - Insert a melodic note on event at an interval relative to the root pitch. Keymaps are a more convenient way to insert notes, but this command allows you to use notes outside the current keymap.
Drum note... - Insert a percussion note on event at a specified absolute MIDI "pitch". You can also insert percussion notes without using this dialog, by holding shift and pressing keys from the percussion keymap.
Note off - Insert a note off event.
Pitch bend... - Insert a pitch bend event to an interval from the keymap, relative to the current root pitch. To get gradual pitch transitions, use the Edit -> Interpolate command from one note or pitch bend event to another. The maximum range of a pitch bend is two octaves from the initial pitch, plus or minus the amount of bending required to produce the initial pitch in the first place.
Program change... - Insert a program (instrument/patch) change event, value range 1 to 128. Also sets bank MSB and LSB in GS and XG modes.
Tempo change... - Insert a tempo change meta-event. Tempos are specified in beats per minute. The default is 120. Tempos can also be specified as ratios, in which case they multiply the previous tempo.
Controller change... - Insert a control change event for the current controller (set by Status -> Set controller...), value range 0 to 127. Most controllers default to 0, with the exception of 7 (volume) to 100, 10 (pan) to 64, and 11 (expression) to 127. GS and XG controllers may have other defaults.
Aftertouch... - Insert an aftertouch (channel pressure) event, value range 0 to 127. Aftertouch usually produces a vibrato effect.
Text... - Insert a text meta-event.
Release length... - Insert a release length directive. This tells the channel allocator not to steal MIDI channels from future off notes in this channel until a number of beats after the note off. This directive does not affect notes that have already been turned off.
MIDI channel range... - Insert a MIDI channel range directive. This specifies the minimum and maximum MIDI channel numbers that this virtual channel will use, value range 1 to 16. This will force multiple notes to play on the same MIDI channel if necessary.
MIDI output index... - Insert a MIDI output index directive. This
specifies the zero-based index of the MIDI output device that this virtual
channel will use. Note that this is the index of the device in the list
provided for MidiOutPortNumber in config.settings.csv, not the port
number itself.
MIDI mode... - Insert a directive to change the MIDI mode used by this track's output.
Go to beat... - Scroll to a given beat (integers not required) without changing the selection.
Delete events - Delete all selected events.
Undo & Redo - Undo or redo changes to song data. The size of the undo
buffer is configurable via config/settings.csv.
Cut, Copy, & Paste - The usual.
Mix paste - A variant of Paste that does not delete or overwrite events.
Insert division - Move all events in selected tracks after the start of the selection down by the size of the selected block (minimum one division).
Delete division - Move all events in selected tracks after the start of the selection up by the size of the selected block (minimum one division). Delete any events that would be end up above the starting point.
Transpose... - Transpose selected pitches by an interval in the keymap.
Interpolate... - Insert events that gradually transition between the values of the events at the beginning and end of the selection. Events will only be inserted at beat divisions.
Multiply... - Multiply the last value of each event in the selection by a specified factor.
Vary... - Add random variation to the last value of each event in the selection up to a specified magnitude.
Toggle keyjazz - Off by default. When turned on, disables note entry via keymap. Useful for experimenting without modifying the song data or undo buffer.
Decrease octave & Increase octave - Shift the root pitch up or down by an octave.
Capture root pitch - Set the root pitch to the pitch of the selected note. A key familiar to users of a certain tracker.
Set velocity... - Set the velocity that notes entered via the computer keyboard will have. Notes entered via MIDI input retain their velocities.
Set controller... - Set the controller that inserted controller change events affect, range 0 to 127.
Set division..., Decrease division, Increase division, Halve division, & Double division - Change the number of equal divisions each beat is divided into for cursor/selection purposes.
Toggle song follow - Off by default. When turned on, the view scrolls to center the play position of the song every time the play position changes.
Load... & Save as... - Load/save a keymap from/to the config/keymaps/
folder.
Import Scala scale... - Import a Scala .scl file from the config/keymaps/
folder as a keymap.
Remap key... - Add or change a mapping in the current keymap.
Generate equal division..., Generate rank-2 scale..., & Generate isomorphic layout... - See "Keymaps" for details.
Display as CSV - Display the current keymap as it would be written to a CSV file.
Change key signature... - Set which accidentals are automatically applied to which input pitch classes (before transposition by the root pitch). This does not change the keymap itself. The key signature is lost when loading a new keymap.
Set channel... - Change the virtual channel that the selected tracks control.
Insert - Add one new track per selected track.
Delete - Delete selected tracks.
Move left & Move right - Shift selected tracks left or right.
For export, see File -> Export MIDI....
Display available inputs & Display available outputs - Display lists of available MIDI inputs/outputs by index.
Send pitch bend sensitivity RPN - MIDI outputs connected to Faunatone after startup will need this to interpret pitches correctly.
Send system on - Resets the state of compliant outputs to the GM, GS, XG, or MT-32 defaults. (And then sends the pitch bend sensitivity RPN.) This also resets the virtual channel states.
Cycle mode - Cycle between GM, GS, XG, MT-32, and MPE modes.
See the SDL_Keycode documentation for key names. Multiple shortcuts (or none) can exist for each menu item. If you want to explicitly disable a shortcut that exists in the default config, keep the line but leave the key field blank.
ColorBeat - The color of beat lines, in RGBA.
ColorBg1 - The primary background color, in RGBA.
ColorBg2 - The secondary background color, in RGBA.
ColorFg - The foreground (text) color, in RGBA.
ColorPlayPos - The color of the play position highlight, in RGBA.
ColorSelect - The color of the selection, in RGBA.
DefaultKeymap - The filename of the default melodic keymap. Must be in the
config/keymaps/ folder.
PercussionKeymap - The filename of the percussion keymap. Must be in the
config/keymaps/ folder.
Font - The filename of the font used for drawing. Must be in the assets/
folder.
FontSize - The point size of the font used for drawing.
MessageDuration - How long to display status messages for, in seconds.
MidiInPortNumber - The index of the MIDI input port used. -1 means none.
MidiInputChannels - How to interpret input from different MIDI channels.
ignore means that all input channels are identical. octaves means that
channel 1 is mapped to the base octave, channel 2 is mapped an octave higher,
and so on.
MidiOutPortNumber - The index of the MIDI output port used. -1 means none. Can use multiple port numbers, separated by spaces; in this case, the first port is the default.
OffDivisionAlpha - The alpha value to use for drawing events that don't fall on a current division of the beat, range 0 to 255.
PitchBendSemitones - The maximum depth of pitch bends, in semitones. Change this to match your playback synth if it doesn't support the default range of two octaves.
ShiftScrollMult - Multiplier for scroll wheel distance when a Shift key is held.
UndoBufferSize - The approximate limit on the size of the undo buffer, in bytes.
WindowHeight - The initial height of the window, in pixels.
WindowWidth - The initial width of the window, in pixels.
Faunatone aims to assume as little as possible about what tuning system the musician is using (one caveat to this is that it currently assumes pure octaves in some contexts). To this end, the intervals used, their mapping to keyboard and MIDI input, and the way they are notated are all defined by files called keymaps. If you have no interest in alternative tunings, you can disregard keymaps entirely; the default keymap is 12edo with a standard keyboard mapping and standard notation.
Microtonal music theory is an expansive field, and its details are beyond the scope of this documentation. However, this document does aim to provide cursory explanations of some relevant microtonal concepts in terms comprehensible to musicians without backgrounds in microtonality.
Faunatone supports four kinds of syntax for defining intervals:
7.02 or -3.863/2 or 4/57\12 or -10\31@T or @HNone of the numbers are required to be integers.
Prefixing an interval with an * marks the mapping as an accidental. Instead
of entering notes, accidentals modify selected notes by the indicated amount.
Holding Shift while inputting an accidental modifies the root pitch instead of
the selection.
Keymaps are comma-separated value (CSV) files with three fields per line:
input, notation, and interval. For example, the line R, F-, 4/3 binds the R
key to an interval of 4/3 (an ascending just fourth), and that interval is to
be displayed as F-5 when in octave 5. Lines that start with # are ignored
by the loader. The equivalent MIDI input mapping would be written as m65, F-,
4/3.
The keymap loader is able to "fill in the blanks" in a few ways:
The first field of a line can be left blank to specify notation for an interval interval without mapping it.
For the purposes of keymaps, keyboard input is interpreted by its scancode (and therefore its position on the physical keyboard) rather than its symbolic value. This means that keymaps must always be written for QWERTY keyboards, but should work identically in a different software-level keyboard layout. For key names, see the SCL_Scancode documentation.
Faunatone includes a few example keymaps in the config/keymaps/ folder. Other
keymaps must also be placed in this folder to be loaded via the Keymap menu.
Faunatone .faun save files also include the working keymap along with the song data. You can extract a keymap from a save file by loading the save file and then saving the keymap.
Faunatone is able to automatically generate some specific types of parametric keymaps using commands in the Keymaps menu. These are by no means the only types of framework worth exploring, but facilities for them are included because they are "proven" and simple to generate programmatically. For other historical and experimental approaches, see well temperaments, tetrachords, tonality diamonds, combination product sets, Euler-Fokker genera, rank-3 scales, and the traditional tonal frameworks of various non-Western cultures. Scala may be able to help you with these.
You may wish to generate a keymap, save it, and then edit it as a text file in order to provide different notation, alter its layout, or add accidentals.
Equal division keymaps are formed by splitting an interval into a number of equal steps. The modern standard for Western tuning fits this description, as the octave is split into 12 identical steps. This is called 12edo (12-equal division of the octave) or sometimes 12tet (12-tone equal temperament).
For generated equal division scales of 10 or fewer notes, Faunatone maps one ascending scale to the Q-P row, and one to the Z-/ row an octave lower. For 11 to 19 notes, the Q-P and Z-/ rows alternate with the 2-0 and S-; rows, much like the traditional tracker keyboard layout, but with no gaps between "black keys". For 20 or more notes, pitches ascend on the keys 2W3E... and descend on the keys /;.L.... In all cases, Q is the root, 1 is an ascending octave, and A is a descending octave. In this way, complete scales of up to 38 notes can be played on the computer keyboard. Keys outside the quadrilateral bounded by 1, 0, Z, and / are left unmapped in order to preserve the regularity of the layout and leave room for added accidentals. MIDI pitches are mapped with 60 as the root and no gaps. The generated notation is based on the scale degree.
The "zeta peaks" 5, 7, 12, 19, 22, 31, 41, and 53 are some edos that generally provide close approximations of just intervals relative to their size, although the last two won't fit in a generated layout. Other relatively well-known equal scales include Wendy Carlos's alpha, beta, and gamma scales at approximately 9edf, 11edf, and 20edf (where f means 3/2 fifth), and the Bohlen-Pierce scale at 13edt (where t means 3/1 "tritave").
Rank-2 scales are formed by two intervals called the period (usually an octave or an equal division of one) and the generator. The scale is formed by sorting the results of stacking the generator modulo the period. For example, a diatonic scale in 12edo tuning can be formed by using a period of an octave and a generator of 7\12, and sorting the resulting series [0\12, 7\12, 2\12, 9\12, 4\12, 11\12, 6\12]. The series could be continued infinitely, although in this case it would repeat after 12 notes because of the 12edo tuning.
For every combination of period and generator, there are certain numbers of notes at which the resulting scale is distributionally even, one potentially useful consequence of which is that there are at most two different intervals formed by each number of scale steps. This does not guarantee that the scale is proper, which would mean that a larger number of scale steps never corresponds to a smaller interval.
Rank-2 scales represent a middle ground between the conceptual simplicity of equal divisions (which are rank-1 scales) and the harmonic precision of just intonation. Using the right combination of period and generator, you can get better-tuned intervals than in an edo with the same number of notes. The tradeoff is that not every represented interval will be accessible from every note in the scale.
Rank-2 scales are usually discussed in terms of temperaments, which effectively reduce the number of dimensions in a JI space by eliminating the differences between specific intervals. Some relatively well-known temperaments include meantone, schismatic/Helmholtz, miracle, magic, porcupine, pajara, and superpyth.
With regard to keyboard layout and notation, Faunatone uses the same rules for rank-2 scales as it does for equal divisions.
Isomorphic keymaps have the property that every shape on the keyboard corresponds to the same interval. For two intervals A and B, a generated isomorphic keymap will fill the quadrilateral bounded by the 1, 0, Z, and / keys such that the G key is the root, one step to the right of any key is interval A, and one step up and to the right is interval B. The generated notation is based on the vector from the root pitch.
One example of an isomorphic keymap is the Wicki-Hayden note layout for concertinas, formed by the intervals 2\12 and 7\12. A 5-limit JI lattice can be formed by the intervals 3/2 and 5/4 (among other pairs). Additional primes require additional dimensions, which can be accessed via accidentals.
Faunatone can load files in .scl
format from the
config/keymaps/ folder using the same layout and notation rules as for
generated equal divisions. You can then save the resulting keymap if you wish
to edit it as a Faunatone keymap rather than a Scala scale.
Scala .kbm files are not currently supported.
Faunatone save files (*.faun) are zlib-compressed JSON.