Music Programming Studio Manual
This is the demo release version of Music Programming Studio, a "live coding" editor for composing music or any audio. The app runs in your browser for Chrome and Firefox. The app will soon be available now for Mac, Windows, Linux.
The app has refined features and is ultra stable. It is designed for real-time live performance, and for endless session editing. The main ways to play sounds are with your own samples, hundreds of open source instruments, and MIDI (for instance system MIDI through channels like IAC for Mac to send notes to GarageBand).
Core Concepts
The fundamental innovation is a purely symbolic and functional methodlogy for writing musical phrases with precise, relative intervals using arrays, objects, and variables. Samples and notes are assigned variables by the system. Lets look at some code.
let bpm = 60 // beats per minute
let interval = 1 // length in beats of top level array elements
let bars = [$1, $3, $2, $3] // plays loop of imported samples ($1, $2, $3)
let phrase = P(bpm, interval, bars)
// the function P() is equivalent to:
phrase = new Phrase(bpm, interval, bars)
The dollar-sign variables are references to imported samples. The UI provides a button to import any audio as sample variables.
Working With Notes
Use standard notes symbols and send them to any of the 100s of included instruments:
let melody = P(bpm, interval, [C, Gb, D, B#])
melody.send(井1) // 井1 = 'GrandPiano' one of hundreds of included instruments
melody.send(midi1) // send notes as MIDI events to control other apps (Garage Band, Ableton, etc)
Octaves & Intervals
By default, note symbols map to a base octave. You can specify precise octaves directly on the note
symbol (e.g., C4, G5).
You can also modify the duration (interval) of a specific note inline using the x
multiplier syntax. For example, C4x4 means play a C in the 4th octave, and multiply its
base interval by 4 (holding it 4 times as long as a standard note in that array).
// Plays C4 for 1 interval, G4 for 1 interval, and A5 for 2 intervals
let lead = P(bpm, interval, [C4, G4, A5x2])
Polyrhythms & Chords
Use objects to play multiple notes or samples simultaneously on the same beat:
let cmaj = {C, E, G} // notes are predefined symbols
let cmaj_hat = {$2, C, E, G} // mix notes and sample variables
P(bpm, interval, [ cmaj, cmaj_hat ]).send(井1).send(midi1)
Nest arrays for precise and arbitrary subintervals. Arrays may be nested to any depth. The length of intervals in a subarray is equal the length of the level above divided by the number of elements in the subarray.
let interval = 1/4 // top level array elements are 1/4 beat intervals
P(bpm, interval, [$1, [$4, $4, $4, $4] ]) // one quarter, and four sixteenth intervals (1/4/4)
Regular numerals represent silent or empty intervals. Zero is an empty interval, and any number
greater than zero is that many intervals of silence, so 0 = 1.
P(bpm, 1, [0, 1, C, 2]) // same as [0, 0, C, 0, 0]
You are programming in regular javascript. Wait, what about that pound sign?
The editor replaces illegal U+266F (#) with legal U+4E95 (井).
Other features, tips, and tricks
- Code is compiled with
shift-enter,cmd-enter, orctrl-enter(on windowsalt-enter). - Unless specified, the recompiled code is synchronized to the master clock, so that live edits do not miss a beat.
- To record, simply add
record()to your code, and compile. To stop recording, compile again calling the samerecord()function. The track will appear in the sidebar for exporting. - To reset all phrases and the master clock, call
reset()in your code. - The simplest way to pause is to put a
returnstatement above all other code, preventing code below that statement from executing. - The UI has a button to upload samples, which then appear by their variable in the sidebar.
- The instruments, courtesy of open source project SMPLR, are also shown by their variable.
- Any MIDI channels found will also appear in the sidebar as midi1, midi2, etc.
Studio Interface Reference
The Studio layout is divided into three main columns, providing quick access to all tools without window-switching.
1. Left Sidebar (Resources & Accordions)
- ▶ Run Code: Manually compiles and executes the currently active editor tab.
- Upload Audio / Samples: Opens a file dialog to import local audio (`.wav`, `.mp3`). Uploaded files automatically receive variables (e.g. `$0`, `$1`).
- Samples Accordion: Lists all imported audio files alongside their assigned variables.
- Instruments Accordion: Browse hundreds of built-in virtual instruments powered
by SMPLR. Note the 井-number variable for each (e.g.
井1). - MIDI Channels: Any active MIDI devices connected to your system will appear
here automatically assigned to variables like
midi1. - Recordings: When you use
record()in your code, the resulting audio renders will appear here with a download link. - Code Tabs: Quickly jump between open files.
2. Middle Column (Code Editor)
- Tabs Bar: Manage your code files. Click
+to create new files, double-click a tab to rename it, and clickxto close it. - Text Editor: A fast, syntax-highlighted IDE supporting custom themes.
- Compilation Shortcuts: Press
Shift-EnterorCmd/Ctrl-Enteranywhere inside the editor to hot-reload your code without breaking the beat.
3. Right Sidebar (AI Prompting)
- Context Selector: Determines what code the AI sees before writing:
- Current Tab: Only sends the code in your active editor.
- All Tabs: Sends the code from every open file to help the AI understand global patterns.
- Prompt Only: Gives the AI a blank slate, ideal for establishing the first drum loop or melody.
- AI Power Level: Choose your Gemini model. Flash variants are cheaper and faster; Pro models are highly capable pattern orchestrators.
- Prompt Area: Describe your musical idea in plain English (e.g., "Build a fast TR-909 drum kit loop" or "Write a melancholy piano progression").
- Generate 🚀: Consumes credits to dispatch your prompt and code context. When finished, a new text tab containing the AI's generated JavaScript will automatically open.