Source Code | Tickets | Trello | Twitter | Patreon | © Michael DeHaan, 2020

User Interface

Starting The Web Server 

The Warp UI is a local web application (it runs completely on your computer, with no internet access required). This same computer should be connected to all of your MIDI devices.

To start the program, first see Installation, and then, from a source checkout:

PYTHONPATH=. bin/warp

Then open your web browser to

Tutorial Video 

This video shows most of the basic Warp concepts. If you are curious about more details on topics in the video, they are described further below.

Basic Concepts 

The left side of the screen contains categories of objects. These are, top to bottom: Song, Scenes, Tracks, Devices, Instruments, Scales, Patterns, Transforms, and Data Pools.

These are heavily described in the API Docs but at a different level of depth. For this guide, we'll explain how you would use them but in a bit more conversational way, as you would use them when writing a new song.


Click on "Devices" in the left most panel and see what MIDI devices show up to the right of that panel. Here, you should see any virtual MIDI devices (such as an Apple IAC Bus or a Windows LoopMIDI Device), as well as any hardware devices you have such as a USB MIDI interface. If you see no devices here, you won't be able to hear any music from Warp until you add or connect something. If you connect any new devices, devices will be rediscovered only when you restart the server process ("warp") - closing the browser isn't sufficient.


After verifying device discovery, the next thing to do is define some instruments. Instruments combine a MIDI device and a MIDI channel. In basic song configurations, you will only have one instrument assigned to each Track, but that's not all Warp can do. Warp can also send notes to multiple instruments from one track, even rotating notes between different instruments. This includes spread chords out between multiple monosynths or playing unison patches with multiple instruments.

When defining a new instrument, it's required that you pick a Device and a MIDI Channel. Here, you can also set a Base Octave which will be added to the pitch of all notes when that instrument is used.

There are also some extra fields here like Min Octave and Max Octave, Default Velocity and Muted. If a calculated note falls outside of the set octave range, it will be set to the min or max octave, as appropriate. It is worth noting the low octave in Warp is numbered "0", and middle C is note "C5". Some other DAW programs have negative -1 or -2 as the lowest octave, but this really doesn't matter and is just a user interface convention.

There are also options for defining up to 8 pairs of notes/octaves for use in drum machine triggers. This is only used in percussive patterns, but it saves remembering that a kick drum is note C3 or C4 and so on. Accessing the drum grid will be discussed in the Patterns section.

  Warp is an "AJAXY" web interface, so any edits are applied immediately. There are no apply buttons on any page. We'll talk about saving files a bit later.


Warp songs can use any number of scales, but to use them, we must create them and give them names. A Scale has a Root note and either a scale Type or a list of Degrees. Scales are fundamental to Warp can be set on a Clip, Scene, or Track.

  Warp does not use "force to scale" mechanics and instead enters notes by scale degree, allowing full access to accidentals outside the scale while also allowing instanteous scale changes without any possible mapping errors. We strongly encourage using scales heavily throughout Warp, especially using modal changes between scenes.

The built-in scale types right now are:

   major              = [ 1, 2, 3, 4, 5, 6, 7 ],
   pentatonic         = [ 1, 2, 3, 5, 6 ],
   pentatonic_minor   = [ 1, 3, 4, 5, 7 ],
   natural_minor      = [ 1, 2, 'b3', 4, 5, 'b6', 'b7' ],
   blues              = [ 1, 'b3', 4, 'b5', 5, 'b7' ],
   dorian             = [ 1, 2, 'b3', 4, 5, 6, 'b7' ],
   chromatic          = [ 1, 'b2', 2, 'b3', 3, 4, 'b5', 5, 'b6', 6, 'b7', 7 ],
   harmonic_major     = [ 1, 2, 3, 4, 5, 'b6', 7 ],
   harmonic_minor     = [ 1, 2, 3, 4, 5, 'b6', 7 ],
   locrian            = [ 1, 'b2', 'b3', 4, 'b5', 'b6', 'b7' ],
   lydian             = [ 1, 2, 3, 'b5', 5, 6, 7 ],
   major_pentatonic   = [ 1, 2, 3, 5, 6 ],
   melodic_minor_asc  = [ 1, 2, 'b3', 4, 5, 'b7', 'b8', 8 ],
   melodic_minor_desc = [ 1, 2, 'b3', 4, 5, 'b6', 'b7', 8 ],
   minor_pentatonic   = [ 1, 'b3', 4, 5, 'b7' ],
   mixolydian         = [ 1, 2, 3, 4, 5, 6, 'b7' ],
   phrygian           = [ 1, 'b2', 'b3', 4, 5, 'b6', 'b7' ],
   japanese           = [ 1, 2, 4, 5, 6 ],
   akebono            = [ 1, 2, 'b3', 5, 6 ]

If you want to define your own scale, you can select from the Degrees multi-select to build your own. We will likely expand the built-in list over time. User-scales can have any number of notes!

Now that scales are defined, you can then use them later by assigning them to a Clip, Pattern, or Song (as a global default).


Patterns have the most involved editing experience in Warp. Patterns are sections of notes (of any length) that can be spliced together inside of Clips. First, we'll explain the top-level properties and then we'll explain the clip grid. This really makes the most sense by watching the video.

Rather than storing notes directly in a Clip, Warp stores sequences of notes in Patterns. This allows multiple clips to reuse patterns (computer science folks may think of these as "symlinks"), or repeat patterns in a "A/B/A/B" or arbitrary sequences. Changing a Pattern in one place affects anywhere the pattern is used. This makes it easy to edit a repeating theme throughout a composition without editing dozens of different clips, increasing potential for experimentation.

A pattern has an Octave Shift which is added to the base pitch of the Instrument. It also has as Rate. If the Rate is 1, notes by default will be interpreted as 16th notes compared to the song tempo. If the rate is 2, they will be 32nd notes, and 0.5 means 8th notes, and 0.25 would be quarter notes. Any positive floating point value is allowed.

The pattern may assign a Scale. If specified, this does not force notes to a scale, but rather references how the scale degrees in the pattern are converted to actual notes. Warp does not use a piano roll, but rather patterns are entered in terms of numeric scale degree. As mentioned earlier, by avoiding the "force to scale" mechanic, it is possible to access accidentals outside the scale at any step.

The pattern Direction determines the order in which the notes of the pattern are evaluated. Patterns can run in forward, reverse, and a variety of random directions. Some pattern expressions may also change the pattern direction (and are explained a bit further down in this chapter).

The pattern may also specify a "drum config" which is a reference to an Instrument that has defined MIDI mappings for percussion. If this is set and the Pattern Type is changed to percussion, the Pattern steps will no longer show notes but will be tailored from drum entry. In this mode, if the value in a grid step is "1", the note will fire on that pattern step. If it is, for example 0.8, the note will have an 80% chance of firing.

Finally in terms of basic properties, the pattern can choose an Instrument to be auditioned with. The idea here is that patterns are not specific to one instrument or track, but can be reused and revisited throughout the composition. We make it easy to try out a pattern with all of the instruments while editing it. You can experiment with multiple instruments or patches on different tracks to decide what sounds best.

Patterns - Step Editor 

Below the pattern properties in the user interface, there is a spreadsheet-like grid where the pattern steps are to be entered. The Grid has numerous columns so the columns, rather than being shown on one screen, are split into tabbed categories (Main, Pitch, Time, Mod, Vars, and Control). Fully complete songs can be made with just the Main tab, but it's useful to understand all of the fun options that are available as there are some fun options on the other tabs.

Just to the left of the pseudo-tabs are is audition button that will play the current pattern with the selected Audition instrument. Warp allows for live editing, so it's fine to keep the loop playing as you edit it.

In each grid cell, you can generally type in a value, which is most often a number. Chord types take a string.

Typing in a number like "0:4" defines a range - this means, "randomly select any number between 0 and 4"

Typing in a value like "0,0,3,4" means randomly pick one of the values from a list. Values are allowed to repeat, and each item in the list has equal probability.

Columns marked with an asterisk ("*") are boolean columns - they represent true or false values, except probabilities can be used. A value of 0 will never be true, a value of 1 and higher is always true, and a value of 0.5 is true 50% of the time.

Most of these options also are repeated in Transforms (explained a bit later), which are how we construct MIDI effects such as Arpeggiators or Octave Transpositions.

  At the current point in Warp development, if you enter in a "bad" value for a cell, like a scale degree of "narf!", the system will assume a default value without visual feedback. This is easy to avoid if you remember all cells except one or two want numbers. Visual feedback will be added in the near future. Inputing some things like a chord type for a monophonic instrument are not the responsibility of Warp though, and are not errors per se - it's just that the MIDI device on the other end doesn't know what to do with the input. That can also be true with some instruments where notes repeat too quickly to have audible attack changes, or too quickly to be audible due to slow attacks. When in doubt, you can always record the MIDI Warp is emitting in your DAW to see what it is producing.

Pattern & Transforms: Main Options 

Here is an explanation of the various columns in the pattern grid editor. Each row represents a different note that will play in order, and a totally blank row is a rest:

Degree - (integer) indicates the scale degree relative to the currently selected scale. If no scale is set, a default scale of C Major will be used. Enter "1" for the tonic, or any value higher or lower. "-1" references a note one lower than the tonic, and "0" will also get you the tonic. A value like "1,3,5" will randomly select the 1st, 3rd, or 5th degree of the current scale, and a value of "1:4" will select a note in the first four scale degrees. To get the sixth note of a scale, just enter "6". If you audition the pattern, try changing the scale dropdown in real time and see how the pattern changes.

Length - (float) if set, multiplies the normal length of the note on this particular step. 0.5 would cut the note length in half, and 2 would double it. Values larger than 1 may result in overlapping notes depending on what is next in the pattern.

Repeat - (integer) if set, the note will repeat ("ratchet") this many additional times within the space alloted, effectively stuttering the note. A value of "1" will repeat the note twice, and a value of "3" means the note will play 4 times. This will be more noticeable with slower tempos and can be used as an alternative form of accent. A value of "0:1" would repeat the note once 50% of the time.

Chord Type - (string) if set, turns the note into a chord. The valid chord types are listed below. For randomly choosing a chord type, seperate valid chord type names with a comma, like "major,minor,minor" for a 2/3 change of a minor chord and 1/3 chance of a major chord.

  Available chord types:
  • minor
  • major
  • dim
  • aug
  • sus4
  • sus2
  • fourth
  • power
  • fifth
  • M6
  • m6
  • dom7
  • M7
  • m7
  • aug7
  • dim7
  • mM7

Octave +/i - (integer) adds or subtracts from the current octave. A value of "-2" would lower the octave by two. A value of "1" will increase the octave by 1. A value like "-1,0,1" would either add, subtract, or not modify the current octave with equal probability.

Velocity - (integer) assigns a numeric MIDI velocity value between 0 and 127. Velocity can be easily humanized with range expressions like "80:90" or choice expressions like "95,96,97,98". If not specified, a default velocity value is taken from the Instrument configuration.

Pattern & Transforms: Pitch Options 

Pitch includes some options from the "Main" tab and adds a few more:

Sharp (#) - (boolean) add a "1" here to turn the note sharp. For a 33% chance of making a note sharp, type "0.33". This can (desirably) result in notes outside the current scale, depending on the chosen scale degree.

Flat (b) - (boolean) add a "1" here to turn the note flat. If both sharp and flat are true, they will cancel out.

Inversion - (integer) if "1" or "2" or "3", selects the 1st or 2nd or 3rd inversion of a chord. To select from all inversions randomly use "0,1,2,3" or "0:3"

Degree +/- - (integer) this amount is added to the scale degree. It is most useful in transforms and can be negative.

Pattern & Transforms: Time Options 

Time options correspond to note length and whether the note should fire at all. Some options were already included in "Main" options. Here are the additional ones.

Tie - (boolean) to add a tie to lengthen a note, leave the Degree blank and fill in a "1" in the tie column one one row after the note you want to tie. Probabilities apply as with all boolean columns, so for a 40% chance of a tie, you can type in 0.4. This will hold the previous note for one additional step. A similar parameter is Length but Tie may be more intuitive in most cases.

Rest - (boolean) if 1, converts the note with certainty to a rest, silencing the note or chord. This is immediately useful in transforms, though in a regular pattern, is more interesting if a probabily like "0.4", indicating a chance the note will not play. If you want a rest with absolute certainty, you can also just leave a blank space for the scale degree in the Pitch tab.

Delay - (float) if positive, the the note is delayed by this fraction of the sixteenth note duration. For example, "0.05" would start the note 5% later than normal. If negative, the note would be computed to start 5% earlier. This can be used to implement swing, and is potentially interesting when used in Transforms

Pattern & Transforms: Mod Options 

MIDI CCs - The first value in each pair is the integer channel number. These may not be randomized with ranges or choices (":" or ","). After the CC in the adjacent column, enter an integer value between 0 and 127. These may be randomized. For instance, "100:127" picks a value between 100 and 127. MIDI CC values will be set until they are rewritten, and each step can assign up to three different MIDI CC values to three different MIDI CC numbers.

Pattern & Transforms: Vars Options 

Here, much like under Mod Options the values come in pairs. Except now, instead of MIDI CC controller messages, we are setting string variable names and values.

Assigning a pair of values like "X" and "42" means that in the pattern grid (later on), if we type "$X" we will get the value 42. The variables can also contain string values, like chord types.

Each slot can set up to three variable values. Variables are in a global namespace and can be used in other patterns as well as in transforms.

Pattern & Transforms: Control Options 

Control options do things to the pattern that are a bit more aggressive than simply changing a pitch or length.

Track grab - (string). If a name of a track is written here, the note specified in Degrees is ignored and the note value that is currently playing on the named track will be used instead. If the track name is mispelled, the system will not capture the playing note. Randomization may be used, for instance "track1,track2" could choose to capture the note value from "track1" or "track2" with an equal chance.

Shuffle - (boolean). If true, the pattern will shuffle randomly until reset or restarted. This is best used with probability values less than one, such as "0.1" for a 10% chance of reshuffling.

Reverse - (boolean). If true, this will reverse the pattern direction. If the pattern direction was already set to a random direction or "back and forth", this might not be noticeable.

Reset - (boolean). If true, the pattern will jump back to the start.

Skip - (integer). If non-zero the system will skip the current note and possibly more additional notes. This can be used with probability effectively using patterns like "0,0,0,2" which would indicate a 1/4 chance of skipping ahead 2 notes.

Pattern & Transforms: Other Buttons 

We've now concluded explaining items in the Pattern and Transform editor grids, but haven't explained a few additional navigation buttons above those grids.

+1, +4, +8 - this adds a row (or 4 rows, or 8 rows) to the pattern.

Delete Selected - this deletes the selected rows from the pattern. This cannot be undone.


Transforms are the mechanism that we build "MIDI Effects" in Warp. These could include arpeggiators, simple octave shifts, or expressions that turn simple notes into complex basslines. They are like patterns that modify patterns, and are very open ended. In the near future we will add a guide or video describing basic arpeggiator and effect construction.

Each transform has a grid with parameters almost exactly like patterns do, and each step applies to each slot in a pattern in turn. They don't have to be the same length.

Above the grid, the following parameters control how the pattern operates:

Arpeggiate - controls whether or not the transform is an arpeggiator, which means that it should break up chords into strummed notes played in order. If arpeggiate is off, notes in a chord will be kept together.

Divide - a positive integer value. If 1, each step of the transform leaves each note as is. If greater than 1, multiple steps of the transform will be applied to the note and played within the timespace that the note would have originally occupied. As such, this may be thought of as a kind of "speed", but as divide also means multiple steps of the transform will be applied to each note sequentially, this setting has more effect than if it were simply a speed setting.

Applies To - this can be "chords", "notes", or "both". If "chords", individual notes will be played verbatim and not affected by the transform. This could be used to construct a chord strummer on monophonic synths that does not alter normal notes. If "notes", chords are kept intact, but notes are modified by the transform steps. "Both" affects, as expected, both.

Direction - just as with patterns, transforms can run in forward, reverse, bi-directional, or various random orderings.

Auto Reset - a boolean value, that, if true, restarts the pattern at the beginning when the pattern using the transform restarts.

Note that using the same transform in two simultaneously playing clips will cause each step of the transform to advance for each note in the clip. You may wish to copy the transform, or this could be musically interesting.

Transforms do not have to be the same length of the patterns they modify, and in fact that can produce added musical interestingness.

Data Pools 

Earlier, when discussing special values like "1:4" and "1,2,3,5" and "$X" that can be used in patterns and transforms, we intentionally skipped over a fourth special way to enter in information.

Data pools are like patterns and can have Directions, but do not produce notes. In any cell, to pull the next value from a data pool (which may be thought of as a queue of sorts), assuming the data pool is named "d1", you can type the name of the data pool like this: "@d1"

Data pools have a grid editor, where each value entered is verbatim value, and they can have any type (integer, floating point, string, etc).

Data pools are especially useful for writing simple patterns that have a certain note of a step pull the scale degree from a data pool, slowly evolving just a few selected notes in a musical phrase as the patterns loop around. Data pools are reset to the beginning of their cycle each time a scene advances if the property Auto Reset is set.

Song: Properties 

The song page contains the most important panel in Warp, the clip launcher. However, before we get there the song has some basic features that need to be mentioned.

Tempo - this sets the default tempo. Any Rate set on a Clip or Pattern will be multiplied against this value.

Filename - this filename is used when saving (downloading) the song. Because Warp is a web application, saves appear as file downloads in your Downloads folder.

Scale - this sets a default scale for the song if not overridden elsewhere, such as in a Scene or Clip.

To save the song, click "Save Song", and similarly, to load a new song into warp, use "Open Song" to upload a file from your computer.

"Init Song" will reset the song state to the empty default configuration, clearing any configurations, patterns, or settings if not already saved.

Song: Editing Clips 

Clips contain a list of patterns you have previously created that play in order. For each pattern in the list, a set of transforms can also modify the notes in the pattern, and the scale from the scene or clip can be overridden.

When ready to create a clip, visit the Clip Grid on the Song page. Clicking any "+" sign will make a new clip for a given scene and track combination.

  While on the Song page, we can also reorder Scenes by dragging them up and down, and can also choose to open any existing Scene, Track, or Clip by clicking on their names.

After clicking on a "+" or an existing Clip Name, we are taken to the Clip Editor. Clips have the following properties:

Rate - a floating point rate that is multiplied against the scene tempo to determine how fast the notes should play in this clip. There is also a rate setting on the pattern, and both settings are used together.

Cycle Limit - this controls how many times the clip should play in a loop. If this value is "0" the clip will play infinitely until it is advanced by pressing play next to a new scene or track. If 2, the clip would play two times.

Advance Scene - this boolean flag controls whether, when a given clip finishes, the entire scene will move on to the next scene. This should usually be enabled for only one of many clips in a scene. For instance, a drum clip could be set to loop infinitely (cycle limit = 0), and a musical pattern could be set to Advance the Scene after 4 repeats.

  In addition to playing all patterns a fixed number of times (which can be of odd lengths!), a measure/bar limit may be added as an option to complete the Clip early - sometime in a future release.

In the Clip editor grid, the following columns are available:

Pattern - this widget provides a place to type names of patterns. One cycle of a playing clip will play all of these listed patterns in order. Pattern names can be repeated, such as to get a "A, B, A, B, C" type repetition effect.

Transforms 1-3 - this widget provides a place to add a list of transforms which are applied to each pattern in series. Up to three transforms can be applied to each pattern in the list.

Scale - this assigns a scale to each pattern in the list. If not assigned, the scale will be read from the scene or song default, in that order.

As with Patterns and Transforms, clips can be auditioned without leaving the Clips page.

  If you type in a pattern, transform, or scale name and it disappears, this indicates there was no object available with that name. Type in pattern names in the pattern cell first, as every step must have a pattern to be valid.

Song: Launching Clips 

Scenes full of clips, or just individual clips, can be launched by clicking the associated play buttons on the Song page.

  At this point, Warp does not wait until the end of a global bar length to launch the next clip. Any human-introduced changes are immediate. Alternatives will be provided in the near future.

What's Next? 

Experiment and have fun! Some more thorough explanations of these topics - though not entirely surfaced to the user in the same way or syntax, are included in the API documentation. If you have questions or ideas, email Michael any time.