BoxyLady user manual

Macros can be called as subroutines in sample mode using \SLOT.

Managing slots and samples

There are several commands available in sample mode to load and save samples.

Loading samples from disc: read(@SLOT file(FILENAME) type(SAMPLE_TYPE_LIST). Loads the RIFF WAV file FILENAME into SLOT.

SAMPLE_TYPE_LIST can contain several extra flags and options in addition to the sample type itself. See Introduction for more details. For WAV files, the sample rate is determined automatically, but this can be overriden in type(...).

loop is optional: if set, the corresponding flag is set in the instrument, intending its use as a looping instrument sample. "Instrument" patches are designed to be short, and are looped while producing a longer note, as opposed to longer, unlooped patches whose note length is limited by the length of the patch.

loop_start is optional: for looping samples, sets the timepoint where the sample should start playing from (in seconds), after the first iteration. This allows for samples containing gating effects, etc.

start_anywhere is optional: if set, a flag is set indicating that the sample, when used as an instrument, can be started at any point, so each note is individual.

Copying samples in memory: copy(SLOT NEWSLOT1 NEWSLOT2 ...) makes a duplicate of SLOT as NEWSLOT1. Slot names must be unique. Multiple destinations can be specified as NEWSLOT2 etc.

Saving to disc: write(@SLOT format=TYPE file(FILENAME) metadata=META) saves SLOT to a the file FILENAME in one of several file formats. If TYPE is "wav" then a standard RIFF WAV file is generated. If TYPE is "boxy" then additional data are included in an extra "boxy" chunk which can be used by BoxyLady on reloading. If TYPE is "mp3" then a standard WAV file is saved as a temporary, and if an external program is available to do the conversion, conversion is made to MP3 format. If META is TRUE, then metadata are saved with (non-temporary) WAV files in a "LIST INFO" chunk. Metadata are always included with MP3 files.

Renaming slots: rename(SLOT NEWSLOT).

Deleting slots: delete(LIST OF SLOTS). Multiple slot names can be specified. delete(*) deletes all slots.

Protecting and unprotecting slots: access(SLOT1=ACCESS1 SLOT2=ACCESS2 ...) sets the access level of slots to either locked or unlocked. A higher level of protection is afforded by system but this cannot be set by the user. Locked and system slots are marked by L and S in output generated by list(). Locked or system slots cannot be deleted or renamed, e.g. accidentally.

metadata(@SLOT title=TITLE album=ALBUM track=TRACK artist=ARTIST year=YEAR genre=GENRE echo) associates metadata with SLOT, for later use if the slot is saved to a WAV or MP3 file. If echo is specified the metadata table will be output to the console.

Manipulating music data

Creating a new silent voice in a slot: create(@SLOT type(FORMAT_TYPE_LIST) channels=CHANNELS len(T-TIME P-TIME)). FORMAT, T-TIME and P-TIME (seconds) are explained earlier. CHANNELS should be 1 for mono and 2 for stereo. T-TIME can be omitted, in which case it is assumed equal to P_TIME.

Creating a new silent voice in slot automatically named "instrument": instrument(type(FORMAT_TYPE_LIST) channels=CHANNELS len(T-TIME P-TIME)). This command is used for on-demand synthesis of instruments (see explanation later). The slot "instrument" is deleted if it already exists. Length is allocated automatically to produce a sound of the correct length, unless this is overriden by specifying a length. Again, T-TIME is optional.

See also for Karplus-Strong string synthesis and other algorithms that produce new samples or operate on them..

Resizing slots: resize(@SLOT mode=TYPE len(T-TIME P-TIME)). TYPE can be absolute or relative (additions) to the current times, in seconds. Again, T-TIME is optional.

resize(@SLOT mode=auto threshold=X). Automatically crops the start and end of SLOT until sound of absolute amplitude X is encountered.

Cutting part of a samples: cut(@SLOT start=START end=END). The start and end points are given in seconds. Both are optional (to use by default the start or end of the sample - omitting both cuts the entire sample giving zero length). Out-of-range time values are truncated.

Pasting part of sample: paste(@SLOT source=SRC start=START end=END). Again, both ends points are optional. The SRC slot is unaffected, but the copied section is pasted as a new sample SLOT, which must not already exist.

Combining mono samples: combine(@SLOT l=LEFT r=RIGHT). LEFT and RIGHT must be equivalent, and are merged into a single stereo sample. Any metadata are copied from the left channel, which is also the case for mix.

General mixing of similar samples: mix(@SLOT a_name=A b_bame=B stereo_a(X Y) stereo_b(U V) channels=C). The two source tracks are combined into a single track called SLOT with C channels. The two source tracks must be the same sample rate and length.

Splitting stereo samples: split(@SLOT l=LEFT r=RIGHT). LEFT and RIGHT must be unused.

Changing number of channels of samples: rechannel(@SLOT channels=N). Acts to combine or duplicate channels as necessary to produce a sample with N channels.


The majority of the above functions can have an additional option shh!=VERBOSITY. This sets the priority of any messages for this function. More verbose values are suppressed by lower settings of the --messages option. In the case of copy and delete, this must not be first in the parameter list.

flags(@SLOT type(SAMPLE_TYPE_LIST)): Amends the flags and settings for SLOT.

A range of music functions can be applied to a voice in memory in a slot, from sample mode.

Volume functions

amp(@SLOT mode=vol a(A)): multiply the volume of SLOT by factor A (can be 0, <0, <1, or >1). This is the default behaviour of amp when mode is missing.

amp(@SLOT mode=stereo a(STEREO)): as above, but using the multiplication factors in STEREO on a stereo channel. Here and below, STEREO should be a pair of the form (L R).

amp(@SLOT mode=cross a(STEREO) x(STEREO-R)): Multi-purpose function using two STEREO parameter blocks. The channels are not only multiplied by STEREO, but in addition have added the signal with the channels swapped and multiplied by STEREO-R. Can be used to invert stereo, widen stereo, cancel central signal, and so on.

amp(@SLOT mode=delay a(STEREO) x(STEREO-R) delay=D): More sophisticated version of the above: the swapped-channel signal is additionally delayed by time interval D.

amp(@SLOT mode=inverse): invert the signal for SLOT.

amp(@SLOT mode=inverse_lr): swap the left and right signal.

fade(@SLOT mode=OP): OP can be one of the following: fade_in, fade_out, linear_fade_in, linear_fade_out, pan_swap, pan_centre, pan_edge, manual. fade_in and _out perform logarithmic fading. In all cases, fading occurs over the whole sample. pan_swap, pan_centre, and pan_edge do not fade as such, but attempt to change the perceived stereo position.

fade(@SLOT mode=manual start_a(STEREO) end_a(STEREO) start_x(STEREO) end_x(STEREO) linear log): Performs a time-varying equivalent to amp(@SLOT mode=stereo ...) where start_a and start_x specify the initial multiplication factors, and end_a and end_x are those to be reached by the end of the sample. Either linear or log can be specified.

crossfade(@NEWSLOT start=SLOT1 end=SLOT2): Fades out a copy of SLOT1, fades in a copy of SLOT2, and puts the superimposed result in NEWSLOT.

envelope(@SLOT e(ENVELOPE)): Applies a sound envelope to SLOT. The format of ENVELOPE is explained earlier. Such an envelope is permanently a feature of the slot and will not remain fixed in duration across different pitches.

bias(@SLOT level=LEVEL): Adds a constant bias level to SLOT of amplitude LEVEL. Can be used to offset synthesised samples so as to allow a larger amplitude without clipping at one extremum. Also equivalent to adding a cosine wave with zero frequency.

debias(@SLOT type=T): Removes a constant bias for each channel on the basis of T. T can be start, end, or mean.

histogram(@SLOT plot scale clip=CLIP): Examines the dynamic range of SLOT. If plot is present, the cumulative histogram of each channel is output. If scale is present, SLOT is expanded in amplitude to fill the dynamic range of -1 to +1, while allowing a maximum proportion CLIP (defaulting to zero if absent) of one channel SLOT to be clipped.


Available in sample mode

tremolo(@SLOT wave=(FREQ AMP OFFSET)): performs a tremolo (amplitude modulation) on the voice given by SLOT using the parameters in WAVE. Strength of tremolo (0-1) is given by the wave amplitude AMP.

ringmod(@SLOT wave(FREQ AMP OFFSET)): performs ring (amplitude) modulation on SLOT using the parameters in WAVE. Can also be used to give a tremolo effect.

ringmod(@SLOT with(X) a=AMP bias=BIAS): performs ring modulation by multiplying the sample by sample X*AMP+BIAS.

modulator(@SLOT mode=am synth(...) a=AMP bias=BIAS env(ENV)): general function for performing amplitude modulation. The instructions within the synth(...) block are applied to a nameless temporary sample XXX the same length as SLOT and a single channel. SLOT is then multiplied by XXX*AMP+BIAS. In all modulator() modes, BIAS and A default to 0 and 1 if not specified.

modulator(@SLOT mode=fm synth(...) a=AMP bias=BIAS env(ENV)): general function for performing frequency modulation. The instructions within the synth(...) block are applied to a nameless temporary sample XXX the same length as SLOT and a single channel. An envelope ENV is then applied to XXX. Then a frequency modulation on SLOT is carried out where the frequency multiplier at time t is defined by XXX[t]*AMP+BIAS. See scratch() in notes mode for further information.
This is the default behaviour of modulator(...) if no mode=MODE is specified.

distort(@SLOT power=POWER): adds distortion to the voice by raising all unsigned values to the power POWER.

modulator(@SLOT mode=dm synth(...) a=AMP bias=BIAS env(ENV)): general function for distortion modulation. As above. Distortion is carried out as for distort() where the power is given by XXX[t]*AMP+BIAS.

bitcrusher(@SLOT bits=BITS): distorts the voice by downsampling to BITS bits. The signal remains 16-bit, internally.

clip(@SLOT a=AMP): clips the signal to within +/- AMP.

clip(@SLOT min=MIN max=MAX): Alternatively, parameters min and max can be set individually.

abs(@SLOT a=AMP): rectifies the signal, converting negative values to positive. The multiplier AMP is optional and defaults to 1.

fold(@SLOT a=AMP): multiplies the signal by AMP, and repeatedly folds any signal in excess of +1 or -1 by reflecting it at these boundaries until the signal lies entirely within the range +1 to -1.

fourier_shift(@SLOT f=FREQ): uses Fourier analysis to shift all frequencies from SLOT additively by FREQ Hz. On its own, this does not achieve successful pitch shifting for a large sample.

fourier_scale(@SLOT f=FACTOR): uses Fourier analysis to shift all frequencies from SLOT multiplicatively by a factor FACTOR. On its own, this does not achieve successful pitch shifting for a large sample.

fourier_power(@SLOT power=POWER): uses Fourier analysis to scale all frequencies according to a power POWER. For POWER > 0 this acts as a high-pass filter, and for POWER < 0 this acts as a low-pass filter. Can be used to scale white noise to produce other noise types.

The filter(...) block

The following filters are available inside filter(...) blocks as found with reverb(), repeat(), and synth() blocks, in which case @SLOT is not needed.

lowpass(@SLOT r=X wrap): performs a low-pass filter using the parameter X. The wrap flag is also optional. If set, the filter is applied to three repeats of the sample, to help alleviate edge effects. This is likely to be appropriate only in instrument samples, not chunks of music.

highpass(@SLOT r=X wrap): as above.

bandpass(@SLOT f=F width=W gain=G wrap): performs a band-pass filter for a given frequency, width (in octaves) and gain (specified as an amplitude in the normal manner). Gain can be negative or positive. wrap acts as above.

fourier_bandpass(@SLOT f=F width=W gain=G comb): performs a band-pass filter in a similar manner to bandpass(), based on Fourier analysis. If comb is included, a comb filter is used, at all multiples of F.

fourier_gain(@SLOT low=LOW high=HIGH low_gain=LOW_GAIN high_gain=HIGH GAIN): implements a high or low pass filter, based on Fourier analysis. Below frequency LOW, gain is adjusted by LOW_GAIN. Above frequency HIGH, gain is adjusted by HIGH_GAIN. Inbetween, geometric interpolation is performed on the gain.

fourier_clean(@SLOT a=GAIN): removes any frequencies from SLOT where the amplitude of the frequency band is below GAIN, scaling by the root mean square amplitude. This tends to act as a type of low-pass filter.

fourier_cleanpass(@SLOT a=GAIN): removes a proportion of frequencies from SLOT where the amplitude of the frequency band is above GAIN, scaling by the root mean square amplitude. This tends to act as a type of high-pass filter.

fourier_limiter(@SLOT a=GAIN): reduces the amplitude of any frequencies from SLOT where the amplitude of the frequency band is above GAIN to GAIN, scaling by the root mean square amplitude. This tends to act as a type of low-pass filter.

pitch_scale(@SLOT f=FACTOR): pitch scales SLOT by multplication factor FACTOR. The current algorithm works poorly outside of a few semitones.

The following basic functions are also available:

amp(AMP): as above, simply changes the amplitude.

distort(POWER): as above.

filter(...) blocks only

In the same filter(...) blocks, the following filters are also available. However they are not available in normal Sample mode.

ks:blend(P): inverts the sign of the sample amplitude stochastically with probability 1-P. Thus P=1 never inverts, P=0 always.

narrow_stereo(AMP): narrows stereo by cross mixing (1-AMP)*0.5 of each stereo channel with AMP*0.5 of the opposite channel.

inverse_lr: switches the left and right channels.

Special effects

chorus(@SLOT n=NUM offset=OFFSET stereo vib(WAVE)): creates a chorus effect of NUM voices, within an approximate time interval of OFFSET (s). The stereo flag is optional, if set, the chorus effect is applied to each channel individually. The sample is converted to stereo first if necessary. vib() is optional. If set, the chorus effect vibrato is applied in the range 1*FREQ to 2*FREQ with amplitude AMP. Otherwise, this defaults to vib(5 0.01).

flange(@SLOT f=FREQ a=AMP): adds a flanging effect with two voices, one subject to vibrato at frequency FREQ and amplitude AMP.

reverb(@SLOT n=NUM delay=DELAY a=AMP resize filter(LIST OF FILTERS)) adds NUM echoes to SLOT, offset each in turn by time DELAY (s) and of downward volume step of AMP (0 to 1). NUM is assumed to be 1 if missing. The FILTERS block is optional, but if present, it is reapplied repeatedly to each echo, in order. If resize is specified, the P-TIME of the slot is extended to allow room for the echoes.

repeat(@SLOT n=COUNT filter(LIST OF FILTERS)) replicates SLOT COUNT times, spaced T-LENGTH apart, where COUNT is an integer. The FILTERS block is optional, but if present, it is reapplied repeatedly to each repeat, in order.

reverse(@SLOT) reverses (i.e. so it plays backwards) the sample.

offset(@SLOT l=L r=R wrap) moves the left and right channels back or forwards in time within SLOT, offset by delays L and R (s). If the flag wrap is set then music offset from one end of the slot is appended to the other end. Can be used to add simulate stereo due to delayed arrival at ear.

filter_sweep(@SLOT start(START) stop(STOP) windows(N)) applies a moving filter across windowed parts of SLOT. N triangular windows are used, plus 2 half triangles for the ends. The filter is interpolated between START and STOP which can be any of the filter-block filters listed above. The type of the filter must be the same for both START and STOP.

octave(@SLOT p=PROP): applies an octave effect, by changing the sign of the signal every alternate zero cross. A proportion PROP of this new signal is mixed with 1-PROP of the old signal.

integrate(@SLOT f=F leak=LEAK c=C): Performs leaky integration on SLOT with multiplier F, leak rate LEAK (reduction *LEAK over a period of 1s) and initial value C.