Language for a Reusable Piece
On this page you turn a drum part into code you can reuse. You name values, write a function, keep a phrase in an object, and move a helper into another file.
Before you start
Section titled “Before you start”Finish Live Coding Workflow.
Open your project’s src/main.non. Evaluate RESET; on its own, then remove it from the file.
You should have an empty, silent session. Select and evaluate each block below in order.
Name the part
Section titled “Name the part”use "std/instruments" { Sampler, Kit };
let level = -9;let rhythm = [bd _ sd _, hh*8];let drums = AudioTrack("drums");drums.set_instrument(Sampler(Kit("CR-78")));drums.volume << level;drums << rhythm;
PLAY;let gives a value a name. Here the values are a number, a pattern, and a track.
A semicolon finishes a statement; // starts a comment. << sends a value to a track or
parameter. It differs from =, which changes a variable:
level = -12;print(level);drums.volume << level;The Output panel prints -12 and the drums get quieter. Assigning level alone would not turn
the fader: you send the new value with the last line.
Write a function
Section titled “Write a function”A function names a set of steps. Define one at the top level of the file, outside other blocks:
fn drum_part(name, pattern, level = -9) { let track = AudioTrack(name); track.set_instrument(Sampler(Kit("CR-78"))); track.volume << level; track << pattern; return track;}
let hats = drum_part("hats", [hh*8], -18);drums << [bd _ sd _];You now hear the hats on their own quieter track. name, pattern and level are parameters:
values passed into the function. The local track name exists only inside it. return gives the
track back to the caller, who keeps it in hats. The default level = -9 lets you omit the last
argument.
Try drum_part("hats", [hh*4], -15); on its own. It updates the same named track.
Return two things
Section titled “Return two things”A tuple groups values; a destructuring let unpacks them into names:
fn parts() { return ([bd _ sd _], [hh*8]);}
let (beat, ticking) = parts();drums << beat;hats << ticking;The beat returns to its earlier shape. You will use the same (drums, verb) return and
let (drums, verb) unpacking in Your First Mix.
Keep a phrase in a class
Section titled “Keep a phrase in a class”A class groups stored values (fields) and functions that use them (methods). Write this definition below your functions:
class Phrase { let pattern; let level;
fn new(pattern, level = -9) { this.pattern = pattern; this.level = level; }
fn play_on(track) { track.volume << this.level; track << this.pattern; }}
let fill = Phrase([sd*8], -12);fill.play_on(drums);Phrase(...) creates an instance and calls new. this is that instance. You hear a snare roll,
with the hats still playing. Change a field, then call the method again:
fill.pattern = [bd _ sd _];fill.play_on(drums);The kick and snare return. Editing the field stores a new pattern; calling play_on sends it.
Move a helper into a module
Section titled “Move a helper into a module”Create src/drum_parts.non. Copy only the drum_part function definition into it, with its
import, and save:
use "std/instruments" { Sampler, Kit };
fn drum_part(name, pattern, level = -9) { let track = AudioTrack(name); track.set_instrument(Sampler(Kit("CR-78"))); track.volume << level; track << pattern; return track;}A .non file imported with use is a module. Its top-level functions are available to the
importing file. Replace src/main.non with this smaller piece, save, then evaluate it:
use "./drum_parts" as drum_parts;
let drums = drum_parts.drum_part("drums", [bd _ sd _]);let hats = drum_parts.drum_part("hats", [hh*8], -18);
PLAY;./drum_parts is relative to src/main.non; the .non extension is optional.
as drum_parts names the module, and drum_parts.drum_part calls its function. The two existing tracks
keep playing with the new settings.
Change the default level in drum_parts.non to -12, save it, and reevaluate main.non.
The drums get quieter; the hats keep their explicit -18. You have one helper to edit for all
parts that use it. Finish by evaluating STOP; on its own.
Next steps
Section titled “Next steps”- Pattern Basics — develop the phrases you send to tracks
- Your First Mix — build a mixer layout with a function
- Functions, Classes and Modules — look up the syntax as you need it