## sc/utilities [ Modules ]

NAME

utilitiesFile: utilities.lsp Class Hierarchy: none: no classes defined Version: 1.1.0 Project: slippery chicken (algorithmic composition) Purpose: Various helper functions of a general nature. Author: Michael Edwards: m@michael-edwards.org Creation date: June 24th 2002 $$ Last modified: 16:16:48 Thu Mar 21 2024 CET

## utilities/a-weighting [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Implementation of A-weighting loudness compensation. Formula taken from http://en.wikipedia.org/wiki/A-weighting. This doesn't take 1000Hz loudness into account, rather it implements the 40-phon Fletcher-Munson curve only.

ARGUMENTS

The frequency in Hertz for which to find the loudness weighting.

OPTIONAL ARGUMENTS

keyword aguments: - :expt. A power (exponent) to raise the result to in order to tame/exaggerate the curve (make the db weightings less/more extreme). This only really makes sense if :linear t though will work with db values also of course. Values < 1 result in linear values closer to 1 (less extreme). Values > 1 are further from 1. Default = NIL i.e. no exponential function. - :linear. If T return amplitude values as linear scalers rather than logarithmic decibel values. NB If this is NIL then returned values are likely to be negative (db) values. Default = T. - :invert. As the weighting routine tries to tell us what relative loudness we'll perceive given constant amplitudes, low and high frequencies will return negative values as we perceive them Xdb less than our most sensitive frequency area. If :invert t, just flip this negatives to positives so that if :linear T you get a scaler to make lower/higher frequences equally loud as the most sensitive frequencies.

RETURN VALUE

The linear or db weighting value for the given frequency.

EXAMPLE

;;; Decibels: (a-weighting50 :invert nil :linear nil) => -30.274979 (a-weighting50 :invert t :linear nil) => 30.274979 ;;; Linear amplitude scalers: (a-weighting50) => 32.639904 (a-weighting50 :invert nil) => 0.030637344 ;;; Exaggeration: (a-weighting50 :expt 1.1) => 46.251286 ;;; Smoothing: (a-weighting50 :expt .5) => 5.7131343 ;;; Looping through the MIDI note range by tritones returning decibel values: (loop for midi from 0 to 127 by 6 for freq = (midi-to-freq midi) collect (list (midi-to-note midi) (a-weightingfreq :linear nil :invert nil))) => ((C-1 -76.85258) (FS-1 -65.94491) (C0 -55.819363) (FS0 -46.71565) (C1 -38.714867) (FS1 -31.724197) (C2 -25.598646) (FS2 -20.247103) (C3 -15.622625) (FS3 -11.657975) (C4 -8.258142) (FS4 -5.358156) (C5 -2.9644737) (FS5 -1.1277018) (C6 0.13445985) (FS6 0.8842882) (C7 1.226917) (FS7 1.2351798) (C8 0.89729404) (FS8 0.09495151) (C9 -1.3861179) (FS9 -3.7814288)) ;;; Similar but returning linear amplitude scalers: (loop for midi from 0 to 127 by 6 for freq = (midi-to-freq midi) collect (list (midi-to-note midi) (a-weightingfreq))) => ((C-1 6960.316) (FS-1 1982.6475) (C0 617.9711) (FS0 216.6619) (C1 86.246864) (FS1 38.56647) (C2 19.051636) (FS2 10.288571) (C3 6.041312) (FS3 3.827355) (C4 2.5876594) (FS4 1.8531382) (C5 1.4067719) (FS5 1.1386365) (C6 0.9846389) (FS6 0.9032034) (C7 0.8682687) (FS7 0.86744314) (C8 0.9018521) (FS8 0.9891278) (C9 1.1730213) (FS9 1.5455086))

SYNOPSIS

(defuna-weighting(f &key expt (linear t) (invert t))

## utilities/agnostic-directory-pathname [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Leon Focker: leon@leonfocker.de

DATE

March 17th 2024.

DESCRIPTION

A replacement for directory-namestring, as that function does not return device names when used on windows.

ARGUMENTS

a string representing a pathname.

RETURN VALUE

a pathname - to a directory without filename and type

SYNOPSIS

(defunagnostic-directory-pathname(namestring)

## utilities/all-members [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Find out whether the members of the list given as the second argument are all present in the list given as the first argument.

ARGUMENTS

- A list in which the members of the second argument will be sought. - A list whose members will be sought in the first argument. OPTIONAL ARGUMENT - A comparison function.

RETURN VALUE

T or NIL.

EXAMPLE

(all-members'(1 2 3 4 5 6 7) '(1 2 3 7)) => T

SYNOPSIS

(defunall-members(list test-list &optional (test #'equal))

## utilities/almost-flatten [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

September 4th 2013

DESCRIPTION

Similar to flatten but allows one level of nesting

ARGUMENTS

A list with an arbitrary level of nesting.

RETURN VALUE

A list with a maximum of one level of nesting

EXAMPLE

(almost-flatten'((1 (2 3 4) (5 (6 7) (8 9 10 (11) 12)) 13) 14 15 (16 17))) => (1 (2 3 4) 5 (6 7) 8 9 10 (11) (12) (13) 14 15 (16 17))

SYNOPSIS

(defunalmost-flatten(nested-list)

## utilities/almost-zero [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Return T if a given decimal is within 0.000001 of 0.0.

ARGUMENTS

- A number.

OPTIONAL ARGUMENTS

- A number that is a user-specified difference for the comparison test.

RETURN VALUE

T if the number is within the tolerance difference to zero, otherwise NIL.

EXAMPLE

(almost-zero0.0000007) => T

SYNOPSIS

(defunalmost-zero(num &optional (tolerance 0.000001))

## utilities/amp2db [ Methods ]

[ Top ] [ utilities ] [ Methods ]

DESCRIPTION

Convert a standard digital amplitude value (>0.0 to 1.0) to a corresponding decibel value.

ARGUMENTS

- A decimal number between >0.0 and 1.0.

RETURN VALUE

A decimal number that is a value in decibel.

EXAMPLE

(amp2db0.3) => -10.457575

SYNOPSIS

(defmacroamp2db(amp)

## utilities/amplitude-to-dynamic [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Convert a specified digital amplitude between 0.0 and 1.0 to a corresponding dynamic between niente and ffff.

ARGUMENTS

- A decimal number between 0.0 and 1.0.

OPTIONAL ARGUMENTS

- T or NIL to indicate whether to print a warning if the specified amplitude is <0.0 or >1.0. T = warn. Default = T.

RETURN VALUE

A symbol that is a dynamic level.

EXAMPLE

(amplitude-to-dynamic0.3) => PP

SYNOPSIS

(defunamplitude-to-dynamic(amp &optional (warn t))

## utilities/auto-scale-env [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

August 29th 2013

DESCRIPTION

Automatically scale both the x and y values of an envelope to fit within the given ranges. Normally we'll assume that the minimum and maximum Y values are present in the original envelope and so the automatically scaled envelope will represent these with the new minimum and maximum values. However sometimes an envelope doesn't range over the possible extremes, for example (0 .3 100 .6) where the y range is from 0 to 1. If this is the case and you need a scaled envelope to take this into account, then how is the original envelopes minimum and maximum values to the keyword argument :orig-y-range.

ARGUMENTS

- The envelope: a list of x y pairs

OPTIONAL ARGUMENTS

keyword arguments: - :x-min: The new minimum (starting) x value - :x-max: The new maximum (last) x value - :y-min: The new minimum (not necessarily starting!) y value - :y-max: The new maximum (not necessarily starting!) y value - :orig-y-range: a two-element list specifying the original envelope's minimum and maximum values (see above).

RETURN VALUE

The new envelope (list).

EXAMPLE

(auto-scale-env'(0 0 10 1)) => (0.0 0.0 100.0 10.0) (auto-scale-env'(-1 0 .3 -3 1 1) :y-min 5 :y-max 6 :x-min 2) => (2.0 5.75 65.7 5.0 100.0 6.0)) (auto-scale-env'(0 1 5 1.5 7 0 10 1) :y-min -15 :y-max -4) => (0.0 -7.6666665 50.0 -4.0 70.0 -15.0 100.0 -7.6666665)) (auto-scale-env'(0 .5 100 .5) :y-min 1 :y-max 2) => (0.0 1.0 100.0 1.0) (auto-scale-env'(0 .5 100 .5) :y-min 1 :y-max 2 :orig-y-range '(0 1)) => (0.0 1.5 100.0 1.5)

SYNOPSIS

(defunauto-scale-env(env &key (x-min 0.0) (x-max 100.0) (y-min 0.0) (y-max 10.0) orig-y-range)

## utilities/average [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Get theaveragevalue of a list of numbers.

ARGUMENTS

- the list of numbers

RETURN VALUE

theaverageof the list, as a float

SYNOPSIS

(defunaverage(num-list)

## utilities/between [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Return a random numberbetweentwo specified numbers. If the two numbers are integers, the random selection is inclusive. If either are floating-point (decimal) numbers, the result will be a floatbetweenthe first (inclusive) and just less than the second (i.e. exclusive).

ARGUMENTS

- A first, lower, number. - A second, higher, number. NB: The first number must always be lower than the second.

OPTIONAL ARGUMENTS

- T or NIL to indicate whether the random seed should be fixed. - T or NIL to indicate whether, when fixed-random is set to T, we should reset the random number generator (to guarantee the same random sequences). This would generally only be called once, perhaps at the start of a generation procedure.

RETURN VALUE

An integer if both numbers are integers, or a float if one or both are decimal numbers.

EXAMPLE

;;; Using the defaults. This will produce a different result each time. (loop repeat 10 collect (between1 100)) => (43 63 26 47 28 2 99 93 66 23) ;;; Setting fixed-random to T and using zerop to reset the random when i is 0 (loop repeat 5 collect (loop for i from 0 to 9 collect (between1 100 t (zerop i)))) => ((93 2 38 81 43 19 70 18 44 26) (93 2 38 81 43 19 70 18 44 26) (93 2 38 81 43 19 70 18 44 26) (93 2 38 81 43 19 70 18 44 26) (93 2 38 81 43 19 70 18 44 26))

SYNOPSIS

(defunbetween(low high &optional fixed-random restart)

## utilities/between-extremes [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

April 23rd 2016, Edinburgh

DESCRIPTION

Given a <progress> value of between 0 and 1, we'll return whatever that proportion is of the difference between <min> and <max> added to min. NB No randomness here.

ARGUMENTS

- the minimum value (returned when <progress> is 0.0) - the maximum value (returned when <progress> is 1.0) - a value between

RETURN VALUE

a number between min and max

EXAMPLE

(BETWEEN-EXTREMES 0.5 1 0.5) ==> 0.75 (BETWEEN-EXTREMES 0.5 1 0.9) ==> 0.95

SYNOPSIS

(defunbetween-extremes(min max progress)

## utilities/cartesian-to-polar [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Leon Focker: leon@leonfocker.de

DESCRIPTION

Convert a point in a 3D coordinate space from the cartesian system to polar coordinates. This differs from the normal definition of this conversion, in that the elevation is the angle from true horizontal, not vertical...

ARGUMENTS

- The x-coordinate - The y-coordinate - The z-coordinate

RETURN VALUE

A list that holds the angle (azimuth), elevation and distance of the point.

EXAMPLE

(cartesian-to-polar0 0 1) => (0 90 1)

SYNOPSIS

(defuncartesian-to-polar(x y z)

## utilities/centre-list [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

March 9th 2021, Heidhausen

DESCRIPTION

Take a list of numbers and scale them so that they are symmetrical(ish) around either the mid-point (exactly) or the middle element (in terms of value).

ARGUMENTS

- a list of numbers

OPTIONAL ARGUMENTS

T or NIL to indicate whether the middle element should the zero point from which the other elements are offset or (if NIL) to use the calculated middle point. So if T, we won't centre around 0 but if NIL we will (i.e. if NIL we'll go equally as far in the negative direction as positive). In each case however, the returned list will by necessity range from negative to positive values.

RETURN VALUE

A list of numbers.

EXAMPLE

(centre-list'(1 2 3 4 5 6) t) -> (-3 -2 -1 0 1 2) (centre-list'(1 2 3 4 5 6) NIL) -> (-2.5 -1.5 -0.5 0.5 1.5 2.5) (centre-list'(12.2 -11 7 13 14 15 16 -2) nil) -> '(9.7 -13.5 4.5 10.5 11.5 12.5 13.5 -4.5)

SYNOPSIS

(defuncentre-list(list &optional zero)

## utilities/combine-into-symbol [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Combine a sequence of elements of any combination of type string, number, or symbol into a symbol.

ARGUMENTS

- A sequence of elements.

RETURN VALUE

A symbol as the primary value, with the length of that symbol as a secondary value.

EXAMPLE

(combine-into-symbol"test" 1 'a) => TEST1A, 6

SYNOPSIS

(defuncombine-into-symbol(&rest params)

## utilities/convert-polar-envelopes [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Leon Focker: leon@leonfocker.de

DESCRIPTION

Convert a set of an angle-env and elevation-env into an envelope for the x, y and z coordinates. Distance is assumed to be 1, if no additional distance-env is given. The x axis represents left (-1) and right (+1). The y axis is front (+1) to back (-1), z goes up (+1) to head-level (0).

ARGUMENTS

- An angle-env - An elevation-env

OPTIONAL ARGUMENTS

keyword arguments: :distance-env. A distance-env... :minimum-samples. A number - minimal amount of points between first and last point of the envelopes at which to convert. If nil, only the original points of the envelopes are used, this however doesn't always fully represent the envelopes... Going from 0° to 180° is something else than going from y = 1 to y = -1.

RETURN VALUE

A list that holds the three envelopes for x, y and z

EXAMPLE

(convert-polar-envelopes'(0 0 1 180) '(0 30 .5 0 1 45) :minimum-samples 5) => (0.0 0.0 25 0.68301266 50.0 1.0 75 0.65328145 100.0 8.6595606e-17) => (0.0 0.8660254 25 0.68301266 50.0 6.123234e-17 75 -0.65328145 100.0 -0.70710677) => (0.0 0.5 25 0.25881904 50.0 0.0 75 0.38268343 100.0 0.70710677)

SYNOPSIS

(defunconvert-polar-envelopes(angle-env elevation-env &key (distance-env '(0 1 1 1)) minimum-samples)

## utilities/db2amp [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Convert a decibel value to a standard digital amplitude value (>0.0 to 1.0), whereby 0dB = 1.0.

ARGUMENTS

- A number that is a value in decibel.

RETURN VALUE

A decimal number between >0.0 and 1.0.

EXAMPLE

(db2amp-3) => 0.70794576

SYNOPSIS

(defmacrodb2amp(db)

## utilities/decider [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Leon Focker: leon@leonfocker.de

DATE

February 23rd 2023

DESCRIPTION

Return an index, which can be used to select an element from a sequence, when provided with a list of weights (see the example). It does that by scaling the selector argument relative to the sum of all weights, using rescale. Then it goes through all the weights and as soon as the selector is smaller than the sum of the weights so far, the index of the current weight is returned. So when given a list of weights '(2 1), the following selectors will return: 0 => 0 1/3 => 0 19/30 => 0 2/3 => 1 1 => 1 This process is thus deterministic. By providing a random number as a selector, you can make random choices etc.

ARGUMENTS

- A number between 0 and 1 - A list of numbers, representing weights

RETURN VALUE

index of chosen element

EXAMPLE

;;; simple example, choosing from a list: (let* ((ls '(c4 d4 e4 f4 g4 a4 b4)) (weights '(1 1 2 2 3 1 2))) (nth (decider0.1 weights) ls)) => d4 ;;; making a simple melody, following a sine wave: (let* ((ls '(c4 d4 e4 f4 g4 a4 b4)) (weights '(1 1 2 2 3 1 2))) (loop for i from 0 to pi by 0.25 collect (nth (decider(abs (sin i)) weights) ls))) => (C4 E4 F4 G4 B4 B4 B4 B4 B4 A4 G4 F4 D4) ;;; make a random melody with 10 pitches: (let* ((ls '(c4 d4 e4 f4 g4 a4 b4)) (weights '(1 1 2 2 3 1 2))) (loop repeat 10 collect (nth (decider(random 1.0) weights) ls)))

SYNOPSIS

(defundecider(selector weights)

## utilities/decimal-places [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

19-Mar-2012

DESCRIPTION

Round the given number to the specified number of decimal places.

ARGUMENTS

- A number. - An integer that is the number of decimal places to which to round the given number.

RETURN VALUE

A decimal number.

EXAMPLE

(decimal-places1.1478349092347 2) => 1.15

SYNOPSIS

(defundecimal-places(num places)

## utilities/decimate-env [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Reduce the number of x,y pairs in an envelope. In every case the envelope is first stretched along the x-axis to fit the new number of points required. Then we proceed by one of three methods: 1) average: for every new output x value, interpolate 100 times from -0.5 to +0.5 around the point, then average the y value. This will catch clustering but round out spikes caused by them 2) points: also an averaging method but only using the existing points in the original envelope (unless none is present for a new x value, whereupon interpolation is used): Take an average of the (several) points nearest the new output point. This might not recreate the extremes of the original envelope but clustering is captured, albeit averaged. 3) interpolate: for each new output point, interpolate the new y value from the original envelope. This will leave out details in the case of clustering, but accurately catch peaks if there are enough output points. In each case we create an even spread of x values, rather than clustering where clusters exist in the original.

ARGUMENTS

- the original envelope (list of x,y values on any scales). - the number of points required in the output list.

OPTIONAL ARGUMENTS

- the method to be applied (symbol): 'points, 'average, 'interpolate. Default = 'points.

RETURN VALUE

A list representing the x,y values of the new envelope

EXAMPLE

(decimate-env'(0 0 4 4 5 5 5.1 5.1 5.3 1 5.6 5.6 6 6 10 10) 6) => (0.0 0.0 1 2.0 2 4.5 3 4.425 4 8.0 5.0 10.0)

SYNOPSIS

(defundecimate-env(env num-points &optional (method 'points))

## utilities/degree-to-radian [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Leon Focker: leon@leonfocker.de

DESCRIPTION

Convert an angle in degrees to its equivalent in radians

ARGUMENTS

- The number in degrees

RETURN VALUE

The number in radians

EXAMPLE

(degree-to-radian180) => 3.141592653589793d0

SYNOPSIS

(defundegree-to-radian(degree)

## utilities/down-up [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

May 8th 2016

DESCRIPTION

This is a routine used in morphing maps but may be useful elsewhere. It interpolates between two numbers over a given number of steps before returning back to the first number.

ARGUMENTS

- the number of steps over which the procedure should interpolate

OPTIONAL ARGUMENTS

keyword arguments: - :down. T or NIL: whether to first descend before ascending. Default = T - :up. T or NIL: whether to ascend after descending. Default = T - :start. The number to start at. Default = 1.0 - :target. The number to interpolate towards. Default = 0.0. - :cons. Whether to return :start as the first number in the result list. - :butlast. Whether to omit the :start when ascending. Default = T.

RETURN VALUE

A list of numbers.

EXAMPLE

(mapcar #'(lambda (x) (decimal-places x 2)) (down-up20)) --> (0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0.0 0.09 0.18 0.27 0.36 0.45 0.55 0.64 0.73 0.82 0.91) (mapcar #'(lambda (x) (decimal-places x 2)) (down-up20 :cons t)) --> (1.0 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9) (mapcar #'(lambda (x) (decimal-places x 2)) (down-up20 :butlast nil)) --> (0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0)

SYNOPSIS

(defundown-up(steps &key (down t) (up t) (start 1.0d0) (target 0.0d0) (cons nil) (butlast t))

## utilities/dynamic-to-amplitude [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Convert a symbol that is a dynamic level between niente and ffff to a corresponding digital amplitude value between 0.0 and 1.0.

ARGUMENTS

- A symbol that is a dynamic level between niente and fff.

OPTIONAL ARGUMENTS

- T or NIL to indicate whether to print a warning when the symbol specified is not recognized as a dynamic. T = warn. Default = T.

RETURN VALUE

A decimal number between 0.0 and 1.0.

EXAMPLE

(dynamic-to-amplitude'fff) => 0.9

SYNOPSIS

(defundynamic-to-amplitude(dynamic &optional (warn t))

## utilities/econs [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Add a specified element to the end of an existing list.

ARGUMENTS

- A list. - An element to add to the end of the list.

RETURN VALUE

A new list.

EXAMPLE

(econs'(1 2 3 4) 5) => '(1 2 3 4 5)

SYNOPSIS

(defunecons(list new-back)

## utilities/edit-file [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Leon Focker: leon@leonfocker.de

DATE

April 30th 2023.

DESCRIPTION

a simple wrapper to open a file as a string and save it into a lexical variable. This variable is then set to the return values of the expressions within the body ofedit-file. Eventually the new value of the variable is written into the original file. This was originally designed to be used with the editing functions in reaper.lsp (set-track-channels etc.).

ARGUMENTS

- A string that is the path to a file (directory and filename) - A name for the lexical variable - this can be used within body (without quote)

RETURN VALUE

whatever was written into the file

EXAMPLE

;;; set all faders of project.rpp to 0.5 and use "anything" as lexical variable (edit-file"/E/project.rpp" anything (set-all-faders anything .5)) |# #| ;;; more complex: insert a plugin on 3 tracks in two ways (edit-file"/E/project.rpp" project (insert-plugin project *iem-stereo-encoder* 1) (insert-plugin project *iem-stereo-encoder* 2) (insert-plugin project *iem-stereo-encoder* 3)) ;;; alternatively: (edit-file"/E/project.rpp" project (loop for i from 1 to 3 with temp-var = project do (setf temp-var (insert-plugin temp-var *iem-stereo-encoder* i)) finally (return temp-var)))

SYNOPSIS

(defmacroedit-file(file var &body body)

## utilities/env-plus [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Increase all y values of a given list of break-point pairs by a specified amount.

ARGUMENTS

- An envelope in the form of a list of break-point pairs. - A number that is the amount by which all y values of the given envelope are to be increased.

RETURN VALUE

A list of break-point pairs.

EXAMPLE

(env-plus'(0 0 25 11 50 13 75 19 100 23) 7.1) => (0 7.1 25 18.1 50 20.1 75 26.1 100 30.1)

SYNOPSIS

(defunenv-plus(env add)

## utilities/env-symmetrical [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Create a new list of break-point pairs that is symmetrical to the original around a specified center. If no center is specified, the center value defaults to 0.5

ARGUMENTS

- An envelope in the form of a list of break-point pairs.

OPTIONAL ARGUMENTS

- A number that is the center value around which the values of the new list are to be symmetrical. - A number that is to be the minimum value for the y values returned. - A number that is to be the maximum value for the y values returned.

RETURN VALUE

An envelope in the form of a list of break-point pairs.

EXAMPLE

;;; Default center is 0.5 (env-symmetrical'(0 0 25 11 50 13 75 19 100 23)) => (0 1.0 25 -10.0 50 -12.0 75 -18.0 100 -22.0) ;; Specifying a center of 0 (env-symmetrical'(0 0 25 11 50 13 75 19 100 23) 0) => (0 0.0 25 -11.0 50 -13.0 75 -19.0 100 -23.0) ;;; Specifying minimum and maximum y values for the envelope returned (env-symmetrical'(0 0 25 11 50 13 75 19 100 23) 0 -20 -7) => (0 -7 25 -11.0 50 -13.0 75 -19.0 100 -20)

SYNOPSIS

(defunenv-symmetrical(env &optional (centre .5) (min most-negative-double-float) (max most-positive-double-float))

## utilities/env2gnuplot [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

24th December 2013

DESCRIPTION

Write a data file of x,y envelope values for use with gnuplit. Once called start gnuplot and issue commands such as: gnuplot> set terminal postscript default gnuplot> set output '/tmp/env.ps' gnuplot> plot '/tmp/env.txt' with lines.

ARGUMENTS

- The envelope as the usual list of x y pairs

OPTIONAL ARGUMENTS

- The pathname of the data file to write. Default = "/tmp/env.txt".

RETURN VALUE

Always T

SYNOPSIS

(defunenv2gnuplot(env &optional (file "/tmp/env.txt"))

## utilities/envelope-boundaries [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Find sharp changes in envelope values. These are defined as when a y value rises or falls over 30% (by default) of it's overall range within 5% (again, by default) of its overall x axis range.

ARGUMENTS

The envelope (a list of x y pairs).

OPTIONAL ARGUMENTS

- jump-threshold: the minimum percentage change in y value that is deemed a sharp change. - steepness-min: the maximum percentage of the overall x axis that constitutes a 'quick' change.

RETURN VALUE

A list of x values at which boundaries are deemed to lie.

EXAMPLE

(ENVELOPE-BOUNDARIES '(0 10 20 10 21 3 25 4 26 9 50 7 51 1 55 2 56 7 70 10 100 10)) --> (21 26 51 56)

SYNOPSIS

(defunenvelope-boundaries(envelope &optional (jump-threshold 30) (steepness-min 5))

## utilities/equal-within-tolerance [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Test whether the difference between two decimal numbers falls within a specified tolerance. This test is designed to compensate for calculation discrepancies caused by floating-point errors (such as 2.0 vs. 1.9999997), in which the equations should yield equal numbers. It is intended to be used in place of = in such circumstances.

ARGUMENTS

- A first number. - A second number.

OPTIONAL ARGUMENTS

- A decimal value that is the maximum difference allowed between the two numbers that will still return T. Default = 0.000001d0.

RETURN VALUE

T if the two tested numbers are equal within the specified tolerance, otherwise NIL.

EXAMPLE

;; An example of floating-point error (loop for i from 0.0 below 1.1 by 0.1 collect i) => (0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.70000005 0.8000001 0.9000001 1.0000001) ;; Using = (loop for i from 0.0 below 1.1 by 0.1 for j in '(0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0) collect (= i j)) => (T T T T T T T NIL NIL NIL NIL) ;; Usingequal-within-tolerance(loop for i from 0.0 below 1.1 by 0.1 for j in '(0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0) collect (equal-within-tolerancei j)) => (T T T T T T T T T T T)

SYNOPSIS

(defunequal-within-tolerance(a b &optional (tolerance 0.000001d0))

## utilities/exaggerate-env [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Makes the y values in an envelope more radically pushed towards its extremes. Y values below the mid-point will be pushed downwards; those above will be pushed upwards. The opposite can be accomplished by making the exponent argument > 1 (see below).

ARGUMENTS

- the envelope: a list of numbers representing an envelope: x y pairs - the exponent: this determines the amount of exaggeration. Counterintuitively perhaps, the lower values are than 1 the more exaggeration takes place. Values > 1 will mean the opposite: understated y values, if you will.

OPTIONAL ARGUMENTS

- easy-expt: because of the counterintuitive nature of the exponent, you can pass values between -10 and +10 if this third argument is T. This will be scaled to useful though not over-extreme exponents of 1.9 (-10) to .1 (+10) with 0 equating to an exponent of 1, i.e. no change.

RETURN VALUE

The new exaggerated envelope (a list).

EXAMPLE

(exaggerate-env'(0 0 50 .8 100 1) 1.9) --> (0 0.0 50 0.6894338 100 1.0) (exaggerate-env'(0 0 50 .8 100 1) .1) --> (0 0.0 50 0.9751001 100 1.0) (exaggerate-env'(0 0 50 .8 100 1) -10) --> (0 0.0 50 83.19083 100 1.0) (exaggerate-env'(0 0 50 .8 100 1) -10 t) --> (0 0.0 50 0.6894338 100 1.0) (exaggerate-env'(0 0 50 .8 100 1) 0 t) --> (0 0.0 50 0.8 100 1.0) (exaggerate-env'(0 0 50 .8 100 1) 10 t) --> (0 0.0 50 0.9751001 100 1.0)

SYNOPSIS

(defunexaggerate-env(env expt &optional easy-expt)

## utilities/factor [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Boolean test to check if a specified number is a multiple of a second specified number.

ARGUMENTS

- A number that will be tested to see if it is a multiple of the second number. - A second number that is the base number for thefactortest.

RETURN VALUE

T if the first number is a multiple of the second number, otherwise NIL.

EXAMPLE

(factor14 7) => T

SYNOPSIS

(defunfactor(num fac)

## utilities/filter-parameters [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

July 1st 2021, Heidhausen

DESCRIPTION

Though generally applicable, a reaper marker specifically could look like this: ("MARKER" (67 709.726 "b364 F1 molto pesante" 0 0 1 B)) Allow therefore searching of the results from (get-parameters ...) for specific strings, returning whole parameter lists or specific elements thereof. NB The strings are case-insensitive.

ARGUMENTS

- a list of parameters, where each element is a 2-element list: the parameter name and a list of associated data. I.e. this implies e.g. calling get-parameters with the optional to-line-end set to T - the string to search for in the data lists

OPTIONAL ARGUMENTS

- a number to specify the nth element that will be returned from the data lists

RETURN VALUE

a list of matching data lists

EXAMPLE

(filter-parameters(get-parameters "markers.RPP" '("MARKER") #\ t) "harmonic" 1) --> 85 parameters read (322.7273 527.37866 542.9216 686.73846 944.6802 952.6701) ;;; or without the nth option: (filter-parameters(get-parameters "markers.RPP" '("MARKER") #\ t) "harmonic") --> ((29 322.7273 "c harmonic resonance" 0 0 1 B {8F7A97DD-F0B6-4E4D-9F67-27635F109E05}) (55 527.37866 "nice resonant harmonic pizz" 0 0 1 B {E380FEF5-FE44-3B47-9C43-2BA80A3D0FAC}) (57 542.9216 "nice harmonic S trem" 0 0 1 B {04BB89FE-8FB8-5B4A-AB5F-EDE1F9C921CC}) (65 686.73846 "b347 E7 nice single harmonic repeat" 0 0 1 B {586CDD49-BE23-F149-AABC-A98EDD6C6EEE}) (79 944.6802 "b483: nice spe and harmonics" 0 0 1 B {11E361AD-22C8-0D42-AB91-ECCBCAAEA075}) (80 952.6701 "b491 muted harmonics" 0 0 1 B {097D7A4D-E9F0-FE4B-8BE6-E7BC85E2969B}))

SYNOPSIS

(defunfilter-parameters(parameters string &optional get-nth)

## utilities/flatten [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Return a list of nested lists of any depth as a flat list.

ARGUMENTS

- A list of nested lists.

RETURN VALUE

A flat list.

EXAMPLE

(flatten'((1 (2 3 4) (5 (6 7) (8 9 10 (11) 12)) 13) 14 15 (16 17))) => (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17)

SYNOPSIS

(defunflatten(nested-list)

## utilities/force-length [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

03-FEB-2011

DESCRIPTION

Create a new a list of a specified new length by adding or removing items at regular intervals from the original list. If adding items and the list contains numbers, linear interpolation will be used, but only between two adjacent items; i.e. not with a partial increment. NB: The function can only create new lists that have a length between 1 and 1 less than double the length of the original list.

ARGUMENTS

- A flat list. - A number that is the new length of the new list to be derived from the original list. This number must be a value between 1 and 1 less than double the length of the original list.

RETURN VALUE

EXAMPLE

;;; Shortening a list (force-length(loop for i from 1 to 100 collect i) 17) => (1 7 13 20 26 32 39 45 51 57 63 70 76 82 89 95 100) ;;; Lengthening a list (force-length(loop for i from 1 to 100 collect i) 199) => (1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7 7.5 8 8.5 9 9.5 10 10.5 11 11.5 12 12.5 13 13.5 14 14.5 15 15.5 16 16.5 17 17.5 18 18.5 19 19.5 20 20.5 21 21.5 22 22.5 23 23.5 24 24.5 25 25.5 26 26.5 27 27.5 28 28.5 29 29.5 30 30.5 31 31.5 32 32.5 33 33.5 34 34.5 35 35.5 36 36.5 37 37.5 38 38.5 39 39.5 40 40.5 41 41.5 42 42.5 43 43.5 44 44.5 45 45.5 46 46.5 47 47.5 48 48.5 49 49.5 50 50.5 51 51.5 52 52.5 53 53.5 54 54.5 55 55.5 56 56.5 57 57.5 58 58.5 59 59.5 60 60.5 61 61.5 62 62.5 63 63.5 64 64.5 65 65.5 66 66.5 67 67.5 68 68.5 69 69.5 70 70.5 71 71.5 72 72.5 73 73.5 74 74.5 75 75.5 76 76.5 77 77.5 78 78.5 79 79.5 80 80.5 81 81.5 82 82.5 83 83.5 84 84.5 85 85.5 86 86.5 87 87.5 88 88.5 89 89.5 90 90.5 91 91.5 92 92.5 93 93.5 94 94.5 95 95.5 96 96.5 97 97.5 98 98.5 99 99.5 100)

SYNOPSIS

(defunforce-length(list new-len)

## utilities/force-symmetrical-and-normalise [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

February 8th 2022

DESCRIPTION

Take a list of numbers (usually samples but any of course) and, using the average sample value, offset them to be symmetrical around 0.0 (usually). This is not the same as but is related to removing DC offset: here we're offsetting numbers individually rather than using the high-pass filter approach in the DSP time domain. Note that to make the samples symmetrical we offset by the average of the existing samples so any occasional outliers will still spike in one direction or another, thus making a waveform view seem to be still offset. Optionally also normalise to within -1.0 and 1.0 (or other values: see below). If either :min or :max are nil then normalisation won't be applied.

ARGUMENTS

a list of floats (double precision)

OPTIONAL ARGUMENTS

keyword arguments: :min. The new minimum value to map to. Default = -1.0 :max. The new minimum value to map to. Default = 1.0 :verbose. Print some stats. Default = NIL.

RETURN VALUE

the list of new samples

SYNOPSIS

(defunforce-symmetrical-and-normalise(samples &key (min -1.0) (max 1.0) verbose)

## utilities/get-clusters [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Takes a list with (ascending) numbers and creates sublists of those numbers within <threshold> of each other.

ARGUMENTS

A list of (ascending) numbers. NB Though the numbers don't have to be in ascending order, the design application of the function makes most sense if they are.

OPTIONAL ARGUMENTS

The maximum distance between two numbers in order for them to be considered as part of the same cluster.

RETURN VALUE

A list with clusters in sublists.

EXAMPLE

(get-clusters'(24 55 58 59 60 81 97 102 106 116 118 119 145 149 151 200 210 211 214 217 226 233 235 236 237 238 239 383 411 415 419)) --> (24 (55 58 59 60) 81 (97 102 106) (116 118 119) (145 149 151) 200 (210 211 214 217) 226 (233 235 236 237 238 239) 383 (411 415 419)) (get-clusters'(0 .1 .3 .7 1.5 1.55 2 4.3 6.3 6.4) 1) --> ((0 0.1 0.3 0.7 1.5 1.55 2) 4.3 (6.3 6.4)) (get-clusters'(0 .1 .3 .7 1.5 1.55 2 4.3 6.3 6.4) 0.5) --> ((0 0.1 0.3 0.7) (1.5 1.55 2) 4.3 (6.3 6.4))

SYNOPSIS

(defunget-clusters(list &optional (threshold 5))

## utilities/get-harmonics [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Return a list of the harmonic partial frequencies in Hertz from a specified (usually fundamental) frequency.

ARGUMENTS

- A number that is the fundamental or starting frequency in Hertz.

OPTIONAL ARGUMENTS

keyword arguments - :start-partial. An integer that is the number of the first harmonic partial to return. Default = 1. - :min-freq. A number that is the lowest frequency in Hertz to return. Default = 20. - :max-freq. A number that is the highest frequency in Hertz to return. Default = 20000. - :start-freq-is-partial. Rather than treating the first argument as the fundamental, treat it as the partial number indicated by this argument. Default = 1. - :max-results. The maximum number of harmonics to return. Default = most-positive-fixnum - :skip. The increment for the harmonics. If 1, then we ascend the harmonics series one partial at a time; 2 would mean skipping every other Default = 1. - :pitches. Return a list of pitch objects instead of frequencies. Default = NIL. - :notes. Return a list of 2-element sublists: note symbols in the chromatics scale, with cent deviations

RETURN VALUE

A list of numbers that are the frequencies in Hertz of harmonic partials above the same fundamental frequency, or with the respective keyword, as pitch objects or note symbols

EXAMPLE

;;; Get the first 15 harmonic partials above a fundamental pitch of 64 Hertz, ;;; starting with partial 2, and specifying an upper cut-off of 1010 Hz. (get-harmonics63 :start-partial 2 :max-freq 1010) => (126 189 252 315 378 441 504 567 630 693 756 819 882 945 1008)

SYNOPSIS

(defunget-harmonics(start-freq &key (start-partial 1) (min-freq 20) (start-freq-is-partial 1) (max-freq 20000) (skip 1) pitches notes (max-results most-positive-fixnum))

## utilities/get-parameters [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

January 29th 2021

DESCRIPTION

A general routine for searching text files for parameters and their values. Here we search a file line by line, matching parameters and returning them in a list of parameter-value pairs. This is limited, however, to one parameter per line, and values of one word (i.e. numbers, strings, etc. not containing space), unless optional argument to-line-end is T (see below)

ARGUMENTS

- the text file to search - either a single string or list thereof to search for (case-sensitive) - the separator character which divides the parameter name from its value

OPTIONAL ARGUMENTS

- the parameter-value separator (character) - T or NIL to indicate whether all tokens after a recognised parameter should be returned in a list. Default = NIL = get just one parameter.

RETURN VALUE

A list of parameter-value pairs

EXAMPLE

;;; search a reaper file, where parameters are followed simply by space rather ;;; than = or : E.g. a current reaper file has lines like: SNAPOFFS 0 LENGTH 0.36292517006803 LOOP 1 ALLTAKES 0 FADEIN 2 0 0 2 0 1 1 FADEOUT 2 0 0 2 0 -1 -1 MUTE 0 0 MIXFLAG 1 BEAT 2 SEL 1 IGUID {3B79D8DF-AC08-EC4F-B93C-CAFE24FA1CBB} IID 3 NAME sunni-mosque.wav VOLPAN 1 0 1 -1 SOFFS 0.67933106575964 PLAYRATE 1 1 0 -1 0 0.0025 ;;; hence: (get-parameters"~/projects/sndfilenet/reaper/sunni-mosque-split.RPP" '("SOFFS" "LENGTH") #\ ) --> 362 parameters read (("LENGTH" 0.36292517) ("SOFFS" 0.67933106) ("LENGTH" 0.38848072) ("SOFFS" 1.0422562) ("LENGTH" 1.4923356) ("SOFFS" 1.430737) ("LENGTH" 1.9968253) ("SOFFS" 2.9230726) ("LENGTH" 0.5023356) ("SOFFS" 4.919898) ("LENGTH" 0.4907483) ("SOFFS" 5.4222336) ("LENGTH" 0.17068027) ("SOFFS" 5.912982) ("LENGTH" 3.6765532) ...

SYNOPSIS

(defunget-parameters(file parameters &optional (separator #\=) to-line-end)

## utilities/get-primes [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

July 6th 2022, Werden

DESCRIPTION

Get all the prime numbers between minimum and maximum values

ARGUMENTS

- the minimum (start point). Doesn't have to be a prime number. - the maximum (end point). Doesn't have to be a prime number.

OPTIONAL ARGUMENTS

- an integer to specify the maximum number of primes to return. If NIL (default) then we'll stop at max

RETURN VALUE

a list of prime numbers

EXAMPLE

(get-primes5 19) -> (5 7 11 13 17 19) (get-primes5 19 3) -> (5 7 11)

SYNOPSIS

(defunget-primes(min max &optional num)

## utilities/get-sublist-indices [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Get the starting position of sublists within a list as though the complete set of items were a flat list.

ARGUMENTS

- A list of lists.

RETURN VALUE

A list of integers that are the indices of the sublists.

EXAMPLE

(get-sublist-indices'((1 2) (3 4 5 6) (7 8 9) (10 11 12 13 14) (15))) => (0 2 6 9 14)

SYNOPSIS

(defunget-sublist-indices(list)

## utilities/get-sublist-lengths [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Get the lengths of all sublists in a given list.

ARGUMENTS

- A list of lists.

OPTIONAL ARGUMENTS

- T or NIL to indicate whether to first remove zeros caused by empty sublists from the result.

RETURN VALUE

A list of integers.

EXAMPLE

;; Straightforward usage allows zeros in the result (get-sublist-lengths'((1 2) (3 4 5 6) (7 8 9) (10 11 12 13 14) ())) => (2 4 3 5 0) ;; Setting the optional argument to T removes zeros from the result (get-sublist-lengths'((1 2) (3 4 5 6) (7 8 9) (10 11 12 13 14) ()) t) => (2 4 3 5)

SYNOPSIS

(defunget-sublist-lengths(list &optional (remove-zeros nil))

## utilities/hailstone [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Implementation of the Collatz conjecture (see http://en.wikipedia.org/wiki/Collatz_conjecture) The Collatz conjecture suggests that by starting with a given number, and if it is even dividing it by two or if it is odd multiplying it by three and adding one, then repeating with the new result, the process will eventually always result in one.

ARGUMENTS

- A number to start with.

RETURN VALUE

A list of the results collected from each iteration starting with the specified number and ending with one.

EXAMPLE

(hailstone11) => (11 34 17 52 26 13 40 20 10 5 16 8 4 2 1)

SYNOPSIS

(defunhailstone(n)

## utilities/hz2ms [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Convert a frequency in Hertz to the equivalent number of milliseconds.

ARGUMENTS

- A number that is a Hertz frequency.

RETURN VALUE

A number that is the millisecond equivalent of the specified Hertz frequency.

EXAMPLE

(hz2ms261.63) => 3.8221915

SYNOPSIS

(defunhz2ms(hertz)

## utilities/interleave [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Interleave the elements of an aribitrary number of lists. Should the lists not be of the same length, this function will only use up as many elements as in the shortest list.

ARGUMENTS

As many lists as need to be interleaved.

RETURN VALUE

A new list of interleaved elements.

EXAMPLE

(INTERLEAVE '(1 2 3 4 5) '(a b c d) '(x y z)) --> (1 A X 2 B Y 3 C Z) (INTERLEAVE '(1 2 3 4 5) '(a b c d e) '(v w x y z)) --> (1 A V 2 B W 3 C X 4 D Y 5 E Z)

SYNOPSIS

(defuninterleave(&rest lists)

## utilities/interpolate [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Get the interpolated value at a specified point within an envelope. The envelope must be specified in the form of a list of break-point pairs.

ARGUMENTS

- A number that is the point within the specified envelope for which to return the interpolated value. - A list of break-point pairs.

OPTIONAL ARGUMENTS

keyword arguments: - :scaler. A number that is the factor by which to scale the values of the break-point pairs in the given envelope before retrieving the interpolated value. Default = 1. - :exp. A number that is the exponent to which the result should be raised. Default = 1. - :warn. T or NIL to indicate whether the method should print a warning if the specified point is outside of the bounds of the x-axis specified in the list of break-point pairs. T = warn. Default = T.

RETURN VALUE

EXAMPLE

;;; Using the defaults (interpolate50 '(0 0 100 1)) => 0.5 ;;; Specifying a different scaler (interpolate50 '(0 0 100 1) :scaler 2) => 1.0 ;;; Specifying a different exponent by which the result is to be raised (interpolate50 '(0 0 100 1) :exp 2) => 0.25

SYNOPSIS

(defuninterpolate(point env &key (scaler 1) (exp 1) (warn t))

## utilities/invert-env [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

June 15th 2017, Edinburgh

DESCRIPTION

Invert an envelope so that its maximum value becomes its minimum, vice-versa, and everything inbetween.

ARGUMENTS

A list of X-Y breakpoint pairs

RETURN VALUE

A list of X-Y breakpoint pairs exhibiting the inversion.

EXAMPLE

(invert-env'(0 0 100 1)) -> (0 1.0 100 0.0) (invert-env'(0 .3 40 .4 100 .9)) -> (0 0.9 40 0.79999995 100 0.3) (invert-env'(0 -.9 40 .4 100 .9)) -> (0 0.9 40 -0.39999998 100 -0.9)

SYNOPSIS

(defuninvert-env(env)

## utilities/list-to-string [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Convert a list to a string.

ARGUMENTS

- A list.

OPTIONAL ARGUMENTS

- A string that will serve as a separator between the elements. Default = " ". - T or NIL to indicate whether a list value of NIL is to be returned as "NIL" or NIL. T = "NIL" as a string. Default = T.

RETURN VALUE

EXAMPLE

;;; Using defaults (list-to-string'(1 2 3 4 5)) => "1 2 3 4 5" ;;; Specifying a different separator (list-to-string'(1 2 3 4 5) "-") => "1-2-3-4-5" ;;; A NIL list returns "NIL" as a string by default (list-to-stringNIL) => "nil" ;;; Setting the second optional argument to NIL returns a NIL list as NIL ;;; rather than as "NIL" as a string (list-to-stringNIL "" nil) => NIL

SYNOPSIS

(defunlist-to-string(list &optional (separator " ") (nil-as-string t))

## utilities/logarithmic-steps [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Create a list of numbers progressing from the first specified argument to the second specified argument over the specified number of steps using an exponential curve rather than linear interpolation.

ARGUMENTS

- A number that is the starting value in the resulting list. - A number that is the ending value in the resulting list. - An integer that will be the length of the resulting list - 1.

OPTIONAL ARGUMENTS

- A number that will be used as the exponent when determining the exponential interpolation between values. Default = 2.

RETURN VALUE

A list of numbers.

EXAMPLE

(logarithmic-steps1 100 19) => (1.0 1.3055556 2.2222223 3.75 5.888889 8.638889 12.0 15.972222 20.555555 25.75 31.555555 37.97222 45.0 52.63889 60.88889 69.75 79.22222 89.30556 100.0)

SYNOPSIS

(defunlogarithmic-steps(low high num-steps &optional (exponent 2))

## utilities/middle [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Get the number value that ismiddleof two number values.

ARGUMENTS

- A first number. - A second number.

RETURN VALUE

A number.

EXAMPLE

(middle7 92) => 49.5

SYNOPSIS

(defunmiddle(lower upper)

## utilities/mins-secs-to-secs [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Derive the number of seconds from a minutes-seconds value that is indicated as a string of the form "0:00.000" or a two-item list in the form '(minutes seconds) or three-item list in the form '(minutes seconds milliseconds)

ARGUMENTS

- A time in minutes and seconds, as described above.

OPTIONAL ARGUMENTS

- if a string is to be passed, then a character that denotes the separator between minutes and seconds. Default = #\:

RETURN VALUE

A decimal number that is a number in seconds.

EXAMPLE

(mins-secs-to-secs'(2 1)) => 121.0 (mins-secs-to-secs'(16 59 534))) => 1019.534 (mins-secs-to-secs"3:06.829")) => 186.829 ;; using a different separator character between minutes and seconds (mins-secs-to-secs"3-36.29" #\-) 0.0001) => 216.29

SYNOPSIS

(defunmins-secs-to-secs(time &optional (post-mins #\:))

## utilities/move-elements [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

02-Mar-2011

DESCRIPTION

Move the specified elements from one list (if they are present in that list) to another, deleting them from the first.

ARGUMENTS

- A list of elements that are the elements to be moved. - A list from which the specified elements are to be moved and deleted. - A list to which the specified elements are to be moved.

OPTIONAL ARGUMENTS

- A predicate by which to test that the specified elements are equal to elements of the source list. Default = #'eq.

RETURN VALUE

Two values: A first list that is the source list after the items have been moved; a second list that is the target list after the items have been moved.

EXAMPLE

(move-elements'(3 5 8) '(1 2 3 4 5 6 7 8 9) '(a b c d e)) => (1 2 4 6 7 9), (8 5 3 A B C D E)

SYNOPSIS

(defunmove-elements(what from to &optional (test #'eq))

## utilities/move-to-end [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

22-May-2011

DESCRIPTION

Move a specified element of a given list to the end of the list, returning the new list. NB: If the element exists more than once in the given list, all but one of the occurrences will be removed and only one of them will be placed at the end.

ARGUMENTS

- An item that is an element of the list that is the second argument. - A list.

RETURN VALUE

A list.

EXAMPLE

;;; All unique items (move-to-end2 '(1 2 3 4 5)) => (1 3 4 5 2) ;;; Duplicate items (move-to-end2 '(1 2 3 2 4 2 5)) => (1 3 4 5 2)

SYNOPSIS

(defunmove-to-end(what list &optional (test #'eql))

## utilities/nconc-sublists [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Concatenate corresponding sublists of a given list. Each sublist in the argument should have the same length and number of sublists etc.

ARGUMENTS

A list of lists.

RETURN VALUE

A list of lists.

EXAMPLE

(nconc-sublists'(((1 2) (a b) (cat dog)) ((3 4) (c d) (bird fish)) ((5 6) (e f) (pig cow)))) => ((1 2 3 4 5 6) (A B C D E F) (CAT DOG BIRD FISH PIG COW))

SYNOPSIS

(defunnconc-sublists(lists)

## utilities/nearest [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

15th May 2020, Heidhausen

DESCRIPTION

Return thenearestnumber in a list to the first argument

ARGUMENTS

- the number we're looking to get the closest to - the list of numbers we'll search

RETURN VALUE

the element of the list that's closest to the first argument, the list sorted bynearestto the number, the distances to the number for the sorted list.

OPTIONAL ARGUMENTS

none

EXAMPLE

(nearest1.21 '(4 2 5 3 5 4 1.2 1.3 1.1999)) --> 1.2

SYNOPSIS

(defunnearest(num list)

## utilities/nearest-power-of-2 [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Return the closest number to the specified value that is a power of two but not greater than the specified value (unless the optional argument is T: see below).

ARGUMENTS

- A number.

OPTIONAL ARGUMENTS

- T or NIL to indicate whether we can return a power of 2 greater than the argument, if that is nearer to the argument than the lower power or 2.

RETURN VALUE

An integer that is a power of two.

EXAMPLE

(nearest-power-of-231) => 16 (nearest-power-of-231 t) => 32 (nearest-power-of-232) => 32 (nearest-power-of-233) => 32

SYNOPSIS

(defunnearest-power-of-2(num &optional allow>)

## utilities/now-string [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Daniel Ross (mr.danielross[at]gmail[dot]com)

DATE

Sat 28 Mar 2020 13:21:08 GMT - London

DESCRIPTION

Return a string representing the current time in the format: YEAR MONTH DAY - HOURS MINUTES SECONDS e.g. "20200328-132227" It is thought that this function might be useful when outputing multiple files during the test phase of a piece. E.g. (cmn-display +mini+ :file (concatenate 'string "my-piece" (now-string) ".eps"))

ARGUMENTS

None

OPTIONAL ARGUMENTS

None

RETURN VALUE

A string

EXAMPLE

(now-string) => "20200328-132227" (concatenate 'string "my-piece_" (now-string) ".eps") => "my-piece_20200328-133357.eps"

SYNOPSIS

(defunnow-string()

## utilities/octave-freqs [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

A boolean test to determine whether two specified frequencies are octave transpositions of the same pitch class.

ARGUMENTS

- A first number that is a frequency in Hertz. - A second number that is a frequency in Hertz.

OPTIONAL ARGUMENTS

- T or NIL to indicate whether identical frequencies ("unison") are also to be considered octave transpositions of the same pitch class. T = unisons are also octaves. Default = T.

RETURN VALUE

T or NIL.

EXAMPLE

(octave-freqs261.63 2093.04) => T (octave-freqs261.63 3000.00) => NIL (octave-freqs261.63 261.63) => T (octave-freqs261.63 261.63 nil) => NIL

SYNOPSIS

(defunoctave-freqs(freq1 freq2 &optional (unison-also t))

## utilities/one-to-many [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

June 23rd 2020

DESCRIPTION

Find aone-to-manyrelationship between the first argument and a number of equally-spaced points given in the second argument. The first argument is a number between 0.0 and 1.0 (inclusive). We calculate the proximities from this point to the number of points given and return them as a list, optionally raised to a given exponent. The list returned is scaled so that all values sum to 1.0, so this is particularly useful for, say, calculating a number of amplitude scalers for a multi-voice synthesis process.

ARGUMENTS

- the point: a number between 0.0 and 1.0 inclusive - the number of points to use in the calculation. This will also be the number of results returned. Alternatively this can be a list of numbers between 0.0 and 1.0. This way you can pass your own points for e.g. an unequally-spaced set. In this case though the proximity is still determined from a maximum of 1.0, not the highest number in the given list.

OPTIONAL ARGUMENTS

- the exponent to raise proximities to. 1.0 will return a linear relationship. > 1.0 will exaggerate the relationships so that those points further away from the first argument will be pushed further away than a linear relationship. < 1.0 will lessen the distances.

RETURN VALUE

a list of numbers the length of which is the same as the 2nd argument and the sum of which is 1.0

EXAMPLE

(one-to-many.8 7) --> (0.045112778 0.082706764 0.12030074 0.15789473 0.19548872 0.21804512 0.18045112) (one-to-many.8 7 .7) --> (0.06509622 0.09950039 0.1293403 0.15646003 0.18169008 0.19612299 0.17178996) (one-to-many.8 7 1.3) --> (0.030845987 0.06782856 0.11039718 0.15721251 0.20752355 0.23917702 0.1870151) ;;; passing 5 points: these don't have to have min/max of 0 and 1 ... (one-to-many.8 '(0 .1 .35 .7 .92)) --> (0.07067137 0.10600708 0.19434628 0.3180212 0.31095406) ;;; ... and they don't have to be in ascending order either (one-to-many.8 '(0 .1 .35 .7 .2)) --> (0.08510638 0.12765959 0.23404254 0.38297874 0.17021276)

SYNOPSIS

(defunone-to-many(one how-many &optional (expt 1.0))

## utilities/os-format-path [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Leon Focker: leon@leonfocker.de

DATE

March 30th 2023

DESCRIPTION

Converts device-names ("/E/", "E:/") according to type Windows: "E:" Unix: "/E/" If type is nil it will be set to the system this function was called on.

ARGUMENTS

- a string representing a path

OPTIONAL ARGUMENTS

- a string or symbol which could be unix, linux or windows. If nil the type of the current system will automatically be chosen.

RETURN VALUE

- a string representing a path

EXAMPLE

(os-format-path"/E/samples/kicks/kick.wav") => "/E/samples/kicks/kick.wav" (os-format-path"E:/samples/kicks/kick.wav") => "/E/samples/kicks/kick.wav" (os-format-path"/E/samples/kicks/kick.wav" 'windows) => "E:/samples/kicks/kick.wav" (os-format-path"E:/samples/kicks/kick.wav" 'windows) => "E:/samples/kicks/kick.wav"

SYNOPSIS

(defunos-format-path(path &optional type)

## utilities/parse-audacity-label-file [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

August 12th 2019

DESCRIPTION

Parse a labels file exported from Audacity and return a list of (start end label) triplets. Times are in seconds.

ARGUMENTS

- the path to the label file

RETURN VALUE

a list

SYNOPSIS

(defunparse-audacity-label-file(label-file)

## utilities/parse-audacity-label-file-for-loops [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Read an audacity label file and return its loop points as groups. NB: If this fails it's probably because there's a tab between time and label instead of spaces: save in emacs to detab. NB: Beware that marker files created on different operating systems from the one on which this function is called might trigger errors due to newline character mismatches.

ARGUMENTS

- A string that is the name of the label file to be parsed, including directory path and extension.

RETURN VALUE

Returns a list of lists which are the grouped time points. Also prints separate feedback to the listener.

EXAMPLE

(parse-audacity-label-file-for-loops"/path/to/24-7loops1.txt") => 313 markers, 50 loops read ((25.674559 25.829296 26.116327 26.649048 27.038843) (32.211884 32.33669 32.481815 32.618233 32.716915 32.902676 33.227757 33.61959) (36.893604 37.059048 37.160633 37.27383 37.439274 37.4683 37.627937) (39.52907 39.81932 39.999275 40.2634 40.338867 40.605896) (45.612698 45.818775 46.050976 46.145306 46.275192) (46.4566 46.644535 46.76934 46.886894 46.971066 47.16553) (84.15927 84.260864 84.292786 84.355194 84.47274 84.52789 84.556915 84.65415) ... (676.1075 676.79114 677.1503 677.57904 678.12366) (799.29205 799.8019 800.58984 800.96063 801.13446 801.45886) (804.98145 805.2016 805.5724 805.83887 806.31396))

SYNOPSIS

(defunparse-audacity-label-file-for-loops(label-file)

## utilities/parse-reaper-file-for-loops [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

July 1st 2021

DESCRIPTION

Read a reaper file and return its loop points as groups. The reaper file must contain markers with the word 'clm-loop-point-start' and 'clm-loop-point-stop' with any number of 'clm-loop-point' markers inbetween. This defines a new set of loop points, of which there can be any number. Any number of markers without these names can be between the -start and -stop markers; they will be ignored. It is assumed that the sound file you'll process starts at time zero in the reaper file and within itself.

ARGUMENTS

- A string that is the name of the marker file to be parsed, including directory path and extension. OPTIONAL ARGUMENTS: T or NIL to issue a warning if a marker is found beginning with 'clm-loop-point' but continuing with something other than -start or -stop. Default = T

RETURN VALUE

Returns a list of lists which are the grouped time points.

SYNOPSIS

(defunparse-reaper-file-for-loops(reaper-file &optional (warn t))

## utilities/parse-reaper-file-for-segment [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

July 5th 2021

DESCRIPTION

Parse a reaper file and look for markers that correspond to the second argument. What we're after is sound file segments i.e. with a start and an end. So markers can be added with a certain symbol e.g. gran marking the start and that symbol with -end tacked on e.g. gran-end to indicate where a segment ends.

ARGUMENTS

- the path to the reaper file - the marker name we'll look for

RETURN VALUE

a list of start-end pairs (in seconds)

EXAMPLE

(parse-reaper-file-for-segment"barbara-markers2.RPP" 'gran) -> '((542.9326 548.098) (598.7433 600.6894) (944.8951 945.41925) (947.9406 948.8009) (952.61755 959.5987) (971.784 975.9188)))))

SYNOPSIS

(defunparse-reaper-file-for-segment(reaper-file marker)

## utilities/parse-wavelab-marker-file-for-loops [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Read a wavelab marker file and return its loop points as groups. The marker file must contain markers with the word "loop". A marker with that name will start a new set of loop points, and nameless markers will belong to the group until the next "loop" marker.

ARGUMENTS

- A string that is the name of the marker file to be parsed, including directory path and extension.

OPTIONAL ARGUMENTS

keyword arguments: - :sampling-rate. An integer that is the sampling rate of the sound file to which the marker file refers. This value will affect the resulting time points. Default = 44100. - :max-length. The maximum duration in seconds between two points: anything greater than this will result in a warning being printed.

RETURN VALUE

Returns a list of lists which are the grouped time points. Also prints separate feedback to the listener.

EXAMPLE

(parse-wavelab-marker-file-for-loops"/path/to/24-7loops1.mrk") => WARNING: utilities::parse-wavelab-marker-file-for-loopsloop points 10:13.213 to 10:14.475 are too long (1.2620239) WARNING: utilities::parse-wavelab-marker-file-for-loopsloop points 10:33.223 to 10:34.486 are too long (1.2630615) WARNING: utilities::parse-wavelab-marker-file-for-loopsloop points 10:36.456 to 10:37.522 are too long (1.06604) 312 markers, 50 loops read ((25.674559 25.829296 26.116327 26.649048 27.038843) (32.211884 32.33669 32.481815 32.618233 32.716915 32.902676 33.227757 33.61959) (36.893604 37.059048 37.160633 37.27383 37.439274 37.4683 37.627937) (39.52907 39.81932 39.999275 40.2634 40.338867 40.605896) (45.612698 45.818775 46.050976 46.145306 46.275192) (46.4566 46.644535 46.76934 46.886894 46.971066 47.16553) (84.15927 84.260864 84.292786 84.355194 84.47274 84.52789 84.556915 84.65415) ... (655.91077 656.4554 656.80304 657.4519 658.04285 658.8192) (676.1075 676.79114 677.1503 677.57904 678.12366) (799.29205 799.8019 800.58984 800.96063 801.13446 801.45886) (804.98145 805.2016 805.5724 805.83887 806.31396))

SYNOPSIS

(defunparse-wavelab-marker-file-for-loops(marker-file &key (sampling-rate 44100) (max-length 1.0))

## utilities/partial-freqs [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

13-Dec-2011

DESCRIPTION

A Boolean test to determine whether either of two specified frequencies can be considered a harmonic partial of the other.

ARGUMENTS

- A first frequency in Hertz. - A second frequency in Hertz.

OPTIONAL ARGUMENTS

- T or NIL to indicate whether identical frequencies ("unison") are also to be considered partials of each other. T = unison are partials. Default = T.

RETURN VALUE

T if one of the frequencies has the ratio of a harmonic partial to the other, otherwise NIL.

EXAMPLE

(partial-freqs300 900) => T (partial-freqs300 700) => NIL (partial-freqs300 300) => T (partial-freqs300 300 nil) => NIL

SYNOPSIS

(defunpartial-freqs(freq1 freq2 &optional (unison-also t))

## utilities/pdivide [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Creates a list of proportionally related times, dividing a starting duration into a number of smaller durations a specified number of times. We start with a proportion as a ratio (e.g. 3/2) and divide the given duration into two parts according to that ratio. Then those two parts will be divided into the same ratios. This will iterate the number of times indicated by the second argument. The following are some classical proportions: Latin (Greek) (3 : 2) Sesquialtera (Diapente) (4 : 3) Sesquitertia (Diatessaron) (5 : 4) Sesquiquarta (Diatonus Semitonus) (8 : 3) Duplasuperbipartiens (Diapson Diatesseron) (9 : 8) Sesquioctava (Tonus)

ARGUMENTS

- an integer or ratio (in Lisp terms, a rational) e.g. 3/2 - an integer >=1 specifying the number of times to iterate the process of dividing the duration into proportions.

OPTIONAL ARGUMENTS

keyword arguments: - :duration. The overall duration to apply the proportional divisions to. Units are arbitrary of course as this is just a number. Default 1.0. - :print. If T, print each level of division as we proceed. Default NIL. - :reverse. If T reverse the proportion (so 3/2 becomes 2/3). Default NIL. - :alternate. If T, reverse the proportion every other division (not iteration) so that if we have a proportion of 3/2 on the second iteration we divide into 3/2 then 2/3. Default NIL. - :increment. If T, then each time we divide we increment both sides of the proportion, so 3:2 becomes 4:3 which becomes 5:4 etc. Default NIL. - :halves. This will only make a difference if :increment is T: As results tend overall towards increasing (when numerator < denominator e.g. 2/3) or decreasing (numerator > denominator e.g. 3/2) numbers, we can mix things up by dividing the resultant list into two halves and splicing their elements one after the other. Default NIL. - :shuffle. Mix things up by shuffling the resultant list. As this uses the shuffle algorithm we have fixed-seed randomness so results will be the same upon each call within the same Lisp implementation/version. Default NIL.

RETURN VALUE

Three values: the list of ascending timings from the last generation of the calculated proportions; the durations of each part for the last generation; the list of ascending timings for _each_ generation of the calculated proportions (a list of lists).

EXAMPLE

Notice here that each generation prints the proportions along with the durations these correspond to and the start time of each (cumulative durations). (pdivide3/2 4 :duration 35 :print t) PRINTS: Generation 1: 3 (21.00=21.00), 2 (14.00=35.00), Generation 2: 3 (12.60=12.60), 2 (8.40=21.00), 3 (8.40=29.40), 2 (5.60=35.00), Generation 3: 3 (7.56=7.56), 2 (5.04=12.60), 3 (5.04=17.64), 2 (3.36=21.00), 3 (5.04=26.04), 2 (3.36=29.40), 3 (3.36=32.76), 2 (2.24=35.00), Generation 4: 3 (4.54=4.54), 2 (3.02=7.56), 3 (3.02=10.58), 2 (2.02=12.60), 3 (3.02=15.62), 2 (2.02=17.64), 3 (2.02=19.66), 2 (1.34=21.00), 3 (3.02=24.02), 2 (2.02=26.04), 3 (2.02=28.06), 2 (1.34=29.40), 3 (2.02=31.42), 2 (1.34=32.76), 3 (1.34=34.10), 2 (0.90=35.00), RETURNS: (0.0 4.5360003 7.5600004 10.584001 12.6 15.624001 17.640001 19.656002 21.000002 24.024002 26.040003 28.056004 29.400003 31.416004 32.760006 34.104008 35.000008) (4.5360003 3.0240002 3.0240004 2.0160003 3.0240004 2.0160003 2.0160003 1.3440002 3.0240004 2.0160003 2.0160003 1.3440002 2.0160003 1.3440001 1.3440001 0.896) ((0.0 4.5360003 7.5600004 10.584001 12.6 15.624001 17.640001 19.656002 21.000002 24.024002 26.040003 28.056004 29.400003 31.416004 32.760006 34.104008 35.000008) (0.0 7.5600004 12.6 17.640001 21.000002 26.040003 29.400003 32.760002 35.000004) (0.0 12.6 21.0 29.400002 35.0) (0.0 21.0 35.0)) (pdivide3/2 4 :duration 35 :print t :increment t :halves t) PRINTS: Generation 1: 3 (21.00=21.00), 2 (14.00=35.00), Generation 2: 4 (12.00=12.00), 3 (9.00=21.00), 5 (7.78=28.78), 4 (6.22=35.00), Generation 3: 6 (6.55=6.55), 5 (5.45=12.00), 7 (4.85=16.85), 6 (4.15=21.00), 8 (4.15=25.15), 7 (3.63=28.78), 9 (3.29=32.07), 8 (2.93=35.00), Generation 4: 10 (3.44=3.44), 9 (3.10=6.55), 11 (2.86=9.40), 10 (2.60=12.00), 12 (2.53=14.53), 11 (2.32=16.85), 13 (2.16=19.01), 12 (1.99=21.00), 14 (2.15=23.15), 13 (2.00=25.15), 15 (1.88=27.03), 14 (1.75=28.78), 16 (1.70=30.48), 15 (1.59=32.07), 17 (1.51=33.58), 16 (1.42=35.00), RETURNS: (0.0 3.4449766 5.595868 8.696347 10.6936035 13.550747 15.428142 18.025545 19.77778 22.30621 24.0064 26.324125 27.918053 30.078053 31.58647 33.580315 35.0) (3.4449766 2.1508918 3.100479 1.9972568 2.8571434 1.8773947 2.5974028 1.752235 2.5284283 1.7001898 2.317726 1.593928 2.16 1.5084175 1.9938462 1.4196872) ((0.0 3.4449766 6.5454555 9.402599 12.000002 14.52843 16.846155 19.006155 21.000002 23.150894 25.148151 27.025547 28.777782 30.477972 32.0719 33.58032 35.000004) (0.0 6.5454555 12.000002 16.846157 21.000004 25.148151 28.77778 32.0719 35.000004) (0.0 12.000001 21.0 28.777779 35.0) (0.0 21.0 35.0))

SYNOPSIS

(defunpdivide(start levels &key (duration 1.0) print reverse alternate halves shuffle increment)

## utilities/pexpand [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Instead of dividing an overall duration (pdivide) we start with a proportion and expand outwards from there, keeping each newly created part in the same proportion. This is repeated the number of times specified in the first argument. Useful for generating maps (section structure).

ARGUMENTS

The number of times to expand proportionally.

OPTIONAL ARGUMENTS

As many integer proportions as required. If the last argument here is t, then instead of using letters to denote sections we use numbers instead.

RETURN VALUE

3 values: 1) a list showing the cumulative count (e.g. bar numbers) of where major and minor sections occur. Topmost sections will have the labels A, B, C, etc. with subsections such as A.A, A.B, ... C.C.C.C. Of course, wherever a major section starts, an arbitrary number of subsections also begin, but only the most major section is present in the list. 2) the structure of the sections and subsections in the form of a list of sublists for each, and containing the section labels paired with their length. The bottommost subsection will have a length of the sum of the proportions, with higher subsection groupings showing multiples of this. 3) the overall length of the structure produced (also the first element of the second returned value).

EXAMPLE

;;; 2 generations: (pexpand2 3 2) => (1 (A) 6 (A A A B) 11 (A A A C) 16 (A A B) 21 (A A B B) 26 (A B) 31 (A B A B) 36 (A B A C) 41 (A B B) 46 (A B B B) 51 (A C) 56 (A C A B) 61 (A C A C) 66 (A C B) 71 (A C B B) 76 (B) 81 (B A A B) 86 (B A A C) 91 (B A B) 96 (B A B B) 101 (B B) 106 (B B A B) 111 (B B A C) 116 (B B B) 121 (B B B B)) (125 (((A) 75) (((A A) 25) (((A A A) 15) ((A A A A) 5) ((A A A B) 5) ((A A A C) 5)) (((A A B) 10) ((A A B A) 5) ((A A B B) 5))) (((A B) 25) (((A B A) 15) ((A B A A) 5) ((A B A B) 5) ((A B A C) 5)) (((A B B) 10) ((A B B A) 5) ((A B B B) 5))) (((A C) 25) (((A C A) 15) ((A C A A) 5) ((A C A B) 5) ((A C A C) 5)) (((A C B) 10) ((A C B A) 5) ((A C B B) 5)))) (((B) 50) (((B A) 25) (((B A A) 15) ((B A A A) 5) ((B A A B) 5) ((B A A C) 5)) (((B A B) 10) ((B A B A) 5) ((B A B B) 5))) (((B B) 25) (((B B A) 15) ((B B A A) 5) ((B B A B) 5) ((B B A C) 5)) (((B B B) 10) ((B B B A) 5) ((B B B B) 5))))) 125 ;;; 3 generations: (pexpand3 3 2) => (1 (A) 6 (A A A A A B) 11 (A A A A A C) 16 (A A A A B) 21 (A A A A B B) 26 (A A A B) 31 (A A A B A B) 36 (A A A B A C) 41 (A A A B B) 46 (A A A B B B) 51 (A A A C) 56 (A A A C A B) 61 (A A A C A C) 66 (A A A C B) 71 (A A A C B B) 76 ... 581 (B B B A A B) 586 (B B B A A C) 591 (B B B A B) 596 (B B B A B B) 601 (B B B B) 606 (B B B B A B) 611 (B B B B A C) 616 (B B B B B) 621 (B B B B B B)) (625 (((A) 375) (((A A) 125) (((A A A) 75) (((A A A A) 25) (((A A A A A) 15) ((A A A A A A) 5) ((A A A A A B) 5) ((A A A A A C) 5)) (((A A A A B) 10) ((A A A A B A) 5) ((A A A A B B) 5))) ... (((B B B) 50) (((B B B A) 25) (((B B B A A) 15) ((B B B A A A) 5) ((B B B A A B) 5) ((B B B A A C) 5)) (((B B B A B) 10) ((B B B A B A) 5) ((B B B A B B) 5))) (((B B B B) 25) (((B B B B A) 15) ((B B B B A A) 5) ((B B B B A B) 5) ((B B B B A C) 5)) (((B B B B B) 10) ((B B B B B A) 5) ((B B B B B B) 5))))))) 625 ;;; 2 generations of 3 proportional values, returning numbers for labels (pexpand2 3 2 4 t) => (1 (1) 10 (1 1 1 2) 19 (1 1 1 3) 28 (1 1 2) 37 (1 1 2 2) 46 (1 1 3) 55 (1 1 3 2) 64 (1 1 3 3) 73 (1 1 3 4) 82 (1 2) 91 (1 2 1 2) 100 (1 2 1 3) 109 (1 2 2) 118 (1 2 2 2) 127 (1 2 3) 136 (1 2 3 2) 145 (1 2 3 3) 154 (1 2 3 4) ... (3 4 2 2) 694 (3 4 3) 703 (3 4 3 2) 712 (3 4 3 3) 721 (3 4 3 4)) (729 (((1) 243) (((1 1) 81) (((1 1 1) 27) ((1 1 1 1) 9) ((1 1 1 2) 9) ((1 1 1 3) 9)) (((1 1 2) 18) ((1 1 2 1) 9) ((1 1 2 2) 9)) (((1 1 3) 36) ((1 1 3 1) 9) ((1 1 3 2) 9) ((1 1 3 3) 9) ((1 1 3 4) 9))) ... (((3 2 2) 18) ((3 2 2 1) 9) ((3 2 2 2) 9)) (((3 2 3) 36) ((3 2 3 1) 9) ((3 2 3 2) 9) ((3 2 3 3) 9) ((3 2 3 4) 9))) (((3 3) 81) (((3 3 1) 27) ((3 3 1 1) 9) ((3 3 1 2) 9) ((3 3 1 3) 9)) (((3 3 2) 18) ((3 3 2 1) 9) ((3 3 2 2) 9)) (((3 3 3) 36) ((3 3 3 1) 9) ((3 3 3 2) 9) ((3 3 3 3) 9) ((3 3 3 4) 9))) (((3 4) 81) (((3 4 1) 27) ((3 4 1 1) 9) ((3 4 1 2) 9) ((3 4 1 3) 9)) (((3 4 2) 18) ((3 4 2 1) 9) ((3 4 2 2) 9)) (((3 4 3) 36) ((3 4 3 1) 9) ((3 4 3 2) 9) ((3 4 3 3) 9) ((3 4 3 4) 9))))) 729

SYNOPSIS

(defunpexpand(generations &rest proportions)

## utilities/pexpand-find [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Find the cumulative number of where a label occurs in a list returned by pexpand.

ARGUMENTS

- the label we're looking for - a list of the type returned by pexpand (first returned value).

OPTIONAL ARGUMENTS

- a function to be called when the label cannot be found. Default = #'error but could also be #'warn or NIL.

RETURN VALUE

An integer.

SYNOPSIS

(defunpexpand-find(label list &optional (on-error #'error))

## utilities/pexpand-section-length [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Return the length (integer) of any arbitrary section in the data returned by pexpand.

ARGUMENTS

- The (rest of) the kind of list returned as the second value of a call to pexpand. - The section ID we want the length of, either as a list or single symbol.

RETURN VALUE

An integer or NIL if the section can't be found.

EXAMPLE

(pexpand-section-length(rest (nth-value 1 (pexpand 2 3 6 4 5))) '(c a b)) => 108 (pexpand-section-length(rest (nth-value 1 (pexpand 2 3 6 4 5))) 'c) => 1296

SYNOPSIS

(defunpexpand-section-length(pexpand-list section)

## utilities/polar-to-cartesian [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Leon Focker: leon@leonfocker.de

DESCRIPTION

Convert a point in a 3D coordinate space from the polar system to cartesian coordinates. This differs from the normal definition of this conversion, in that the elevation is the angle from true horizontal, not vertical...

ARGUMENTS

- The horizonal angle from the Y axis (alpha, azimuth angle) in degree. - The vertical angle from the X axis (polar, elevation) between +-180° - The distance from the origin (the radius), 0 <= distance <= 1

RETURN VALUE

A list that holds the x y and z coordinates for the point.

EXAMPLE

(polar-to-cartesian0 45 1) => (0.0 0.70710677 0.70710677)

SYNOPSIS

(defunpolar-to-cartesian(angle elevation distance)

## utilities/power-of-2 [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Test whether the specified number is a power of two and return the logarithm of the specified number to base 2. This method returns two values: T or NIL for the test and a decimal that is the logarithm of the specified number to base 2.

ARGUMENTS

- A number.

RETURN VALUE

Two values: T or NIL for the test and a decimal number that is the logarithm of the specified number to base 2.

EXAMPLE

(power-of-216) => T, 4.0 (power-of-217.3) => NIL, 4.1127

SYNOPSIS

(defunpower-of-2(float)

## utilities/prime [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

August 5th 2019, Heidhausen

DESCRIPTION

Taken from dlocsig.lisp by Fernando Lopez Lezcano (in the CLM package): Return T or NIL to indicated whether the argument is aprimenumber or not.

ARGUMENTS

an integer (all other types, including floats, will trigger an error)

RETURN VALUE

T or NIL

SYNOPSIS

(defunprime(val)

## utilities/pts2cm [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Convert a specified number of points to a length in centimeters at a resolution of 72ppi.

ARGUMENTS

- A number.

RETURN VALUE

A number.

EXAMPLE

(pts2cm150) => 5.2916665

SYNOPSIS

(defunpts2cm(points)

## utilities/radian-to-degree [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Leon Focker: leon@leonfocker.de

DESCRIPTION

Convert an angle in radians to its equivalent in degrees

ARGUMENTS

- The number in radians

RETURN VALUE

The number in degrees

EXAMPLE

(radian-to-degreepi) => 180

SYNOPSIS

(defunradian-to-degree(radian)

## utilities/random-amount [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Return a random number from within a total range of <percent> of the given number, centering around zero. Thus, if the <number> is 100, and the <percent> is 5, the results will be a random number between -2.5 and +2.5.

ARGUMENTS

A number.

OPTIONAL ARGUMENTS

A number that will be a percent of the given number.

RETURN VALUE

A random positive or negative number.

EXAMPLE

;;; Using the default will return numbers within a 5% span of the given number, ;;; centering around zero. With 100 that means between -2.5 and +2.5. (loop repeat 10 collect (random-amount100)) => (0.7424975 -1.4954442 -1.7126495 1.5918689 -0.43478793 -1.7916341 -1.9115914 0.8541988 0.057197176 2.0713913) ;;; Specifying 10% of 80 will return random numbers between -4.0 and +4.0 (loop repeat 10 collect (random-amount80 10)) => (-0.66686153 3.0387697 3.4737322 -2.3753185 -0.8495751 -0.47580242 -0.25743783 -1.1395472 1.3560238 -0.5958566)

SYNOPSIS

(defunrandom-amount(number &optional (percent 5))

## utilities/random-from-list [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Return a random element from a specified list of elements.

ARGUMENTS

- A list.

OPTIONAL ARGUMENTS

- An integer can be passed stating the length of the list, for more efficient processing. NB: There is no check to ensure this number is indeed the length of the list. If the number is less than the length of the list, only elements from the first part of the list will be returned. If it is greater than the length of the list, the method may return NIL.

RETURN VALUE

An element from the specified list.

EXAMPLE

(random-from-list'(3 5 7 11 13 17 19 23 29)) => 13

SYNOPSIS

(defunrandom-from-list(list &optional list-length) ; for efficiency

## utilities/randomise [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Return a random decimal number close to (+ or -) the number specified (within a certain percentage of that number's value). Note that if you want the result to go from 0 to 2x the argument, then <percent> needs to be 200, not 100.

ARGUMENTS

- A number.

OPTIONAL ARGUMENTS

- A number that is a percentage value, such that any random number returned will be within that percentage of the original number's value. Default = 5.

RETURN VALUE

A decimal number.

EXAMPLE

(loop repeat 10 collect (randomise100)) => (99.413795 99.15346 98.682014 100.76199 97.74929 99.05693 100.59494 97.96452 100.42091 100.01329)

SYNOPSIS

(defunrandomise(number &optional (percent 5))

## utilities/read-file-as-string [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Leon Focker: leon@leonfocker.de

DATE

April 30th 2023.

DESCRIPTION

Read an entire file (not just an s-expression) a into string and return it

ARGUMENTS

- A string that is the path to a file (directory and filename)

RETURN VALUE

A string with the contents of the file

EXAMPLE

(read-from-file "/path/to/lisp-lorem-ipsum.txt")

SYNOPSIS

(defunread-file-as-string(infile)

## utilities/read-from-file [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Read a Lisp expression from a file. This is determined by the Lisp parenthetical syntax.

ARGUMENTS

- A string that is a file name including directory path and extension.

RETURN VALUE

The Lisp expression contained in the file.

EXAMPLE

(read-from-file"/path/to/lisp-lorem-ipsum.txt") => (LOREM IPSUM DOLOR SIT AMET CONSECTETUR ADIPISCING ELIT CRAS CONSEQUAT CONVALLIS JUSTO VITAE CONSECTETUR MAURIS IN NIBH VEL EST TEMPUS LOBORTIS SUSPENDISSE POTENTI SED MAURIS MASSA ADIPISCING VITAE DIGNISSIM CONDIMENTUM VOLUTPAT VEL FELIS FUSCE AUGUE DUI PULVINAR ULTRICIES IMPERDIET SED PHARETRA EU QUAM INTEGER IN VULPUTATE VELIT ALIQUAM ERAT VOLUTPAT VIVAMUS SIT AMET ORCI EGET EROS CONSEQUAT TINCIDUNT NUNC ELEMENTUM ADIPISCING LOBORTIS MORBI AT LOREM EST EGET MATTIS ERAT DONEC AC RISUS A DUI MALESUADA LOBORTIS AC AT EST INTEGER AT INTERDUM TORTOR VIVAMUS HENDRERIT CONSEQUAT AUGUE QUISQUE ALIQUAM TELLUS NEC VESTIBULUM LOBORTIS RISUS TURPIS LUCTUS LIGULA IN BIBENDUM FELIS SEM PULVINAR DOLOR VIVAMUS RHONCUS NISI GRAVIDA PORTA VULPUTATE IPSUM LACUS PORTA RISUS A VULPUTATE MAGNA JUSTO A EST)

SYNOPSIS

(defunread-from-file(file)

## utilities/reflect-list [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Order a list of numbers from least to greatest, then transpose the list so that if an element is the second lowest, it will be replaced by the second highest etc.

ARGUMENTS

- A list or numbers.

RETURN VALUE

A list of numbers.

EXAMPLE

(reflect-list'(1 4 3 5 9 6 2 7 8 8 9)) => (9 6 7 5 1 4 8 3 2 2 1)

SYNOPSIS

(defunreflect-list(list)

## utilities/remove-all [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Remove all of the specified elements from a list, returning a list containing only those elements that are not in the first argument list.

ARGUMENTS

- A first list that is the list of items to remove. - A second list that is the original list.

OPTIONAL ARGUMENTS

- A predicate for testing equality between the elements of the two lists. Default = #'eq.

RETURN VALUE

A list.

EXAMPLE

(remove-all'(3 5 8 13) '(1 2 3 4 5 6 7 8 9 10 11 12 13)) => (1 2 4 6 7 9 10 11 12)

SYNOPSIS

(defunremove-all(rm-list list &optional (test #' eq))

## utilities/remove-elements [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Remove a specified number of elements from a given list starting at a specified position (0-based) within the list.

ARGUMENTS

- A list. - An integer that is the 0-based position within that list that will be the first element to be removed. - An integer that is the number of elements to remove.

RETURN VALUE

A list.

EXAMPLE

(remove-elements'(1 2 3 4 5 6 7) 2 4) => (1 2 7)

SYNOPSIS

(defunremove-elements(list start how-many)

## utilities/remove-more [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Remove all instances of a list of specified elements from an original list. The predicate used to test the presence of the specified elements in the original list must be specified by the user (such as #'eq, #'equalp, #'= etc.)

ARGUMENTS

- A list. - A predicate with which to test the presence of the specified elements. - A sequence of elements to be removed from the given list.

RETURN VALUE

A list.

EXAMPLE

(remove-more'(1 2 3 4 5 5 5 6 7 7 8) #'= 5 7 2) => (1 3 4 6 8)

SYNOPSIS

(defunremove-more(list test &rest remove)

## utilities/replace-elements [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Replace the elements in list between start and end (inclusive) with the new list.

ARGUMENTS

- A list. - An integer that is first position of the segment of the original list to be replaced. - An integer that is the last position of the segment of the original list to be replaced. - A list that is to replace the specified segment of the original list. This list can be of a different length than that of the segment of the original specified by the start and end positions.

RETURN VALUE

A list.

EXAMPLE

(replace-elements'(1 2 3 4 5 6 7 8 9) 3 7 '(dog cat goldfish)) => (1 2 3 DOG CAT GOLDFISH 9)

SYNOPSIS

(defunreplace-elements(list start end new)

## utilities/rescale [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

June 8th 2016, Edinburgh

DESCRIPTION

Given a value within an original range, return its value withing a new range

ARGUMENTS

- the value we want torescale- the original minimum - the original maximum - the new minimum - the new maximum

OPTIONAL ARGUMENTS

keyword arguments: :out-of-range. The function to call when the first argument is not within the range of arguments two and three. This would normally be #'error, #'warn or NIL. If #'warn or NIL, argument 1 will be hard-limited to the original range. Default = #'error :type-of-result. Usually this function uses float precision, but by setting type-of-result to #'double-float or #'rationalize, it is more precise.

RETURN VALUE

The value within the new range (a number)

EXAMPLE

(rescale.5 0 1 0 100) ==> 50.0

SYNOPSIS

(defunrescale(val min max new-min new-max &optional (out-of-range #'error) (type-of-result #'float))

## utilities/round-if-close [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Round a decimal number if it is within a given tolerance to the next whole number.

ARGUMENTS

- A decimal number.

OPTIONAL ARGUMENTS

- If the given number is this amount or less than the nearest whole number, round the given number to the nearest whole number.

RETURN VALUE

If the given number is within the tolerance, return the number, otherwise return the nearest whole number.

EXAMPLE

(round-if-close1.999998) => 1.999998 (round-if-close1.999999) => 2

SYNOPSIS

(defunround-if-close(num &optional (tolerance 0.000001))

## utilities/scale-env [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Scale either the x-axis values, the data values, or both of a list of break-point pairs by specified factors.

ARGUMENTS

- An envelope in the form of a list of break-point pairs. - A number that is the factor by which the y values (data segment of the break-point pairs) are to be scaled.

OPTIONAL ARGUMENTS

keyword arguments: - :y-min. A number that is the minimum value for all y values after scaling. NB The -min/-max arguments are hard-limits only; they do not factor into the arithmetic. - :y-max. A number that is the maximum value for all y values after scaling. - :x-scaler. A number that is the factor by which to scale the x-axis values of the break-point pairs. - :x-min. A number that is the minimum value for all x values after scaling. NB: This optional argument can only be used if a value has been specified for the :x-scaler. - :x-max. A number that is the maximum value for all x values after scaling. NB: This optional argument can only be used if a value has been specified for the :x-scaler. - :first-x. If a number, scale the x-axis so that this is the first x-value. This then ignores x-scaler. - :last-x. If a number, scale the x-axis so that this is the last x-value. This then ignores x-scaler.

RETURN VALUE

An envelope in the form of a list of break-point pairs.

EXAMPLE

;;; Scaling only the y values. (scale-env'(0 53 25 189 50 7 75 200 100 3) 0.5) => (0 26.5 25 94.5 50 3.5 75 100.0 100 1.5) ;;; Scaling the y values and setting a min and max for those values (scale-env'(0 53 25 189 50 7 75 200 100 3) 0.5 :y-min 20 :y-max 100) => (0 26.5 25 94.5 50 20 75 100 100 20) ;;; Scaling only the x-axis values (scale-env'(0 53 25 189 50 7 75 200 100 3) 1.0 :x-scaler 2) => (0 53.0 50 189.0 100 7.0 150 200.0 200 3.0) ;;; Scaling the x values and setting a min and max for those values (scale-env'(0 53 25 189 50 7 75 200 100 3) 1.0 :x-scaler 2 :x-min 9 :x-max 90) => (9 53.0 50 189.0 90 7.0 90 200.0 90 3.0) ;;; 'Stretching' the envelope by providing first-x and last-x values (scale-env'(1 0 5 1 20 0) 1 :first-x 0 :last-x 100) => (0.0 0 21.052631 1 100.0 0)

SYNOPSIS

(defunscale-env(env y-scaler &key x-scaler first-x last-x (x-min most-negative-double-float) (y-min most-negative-double-float) (x-max most-positive-double-float) (y-max most-positive-double-float))

## utilities/secs-to-mins-secs [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Convert a number of seconds into a string of the form "24:41.723" where seconds are always rounded to three decimal places (i.e. milliseconds).

ARGUMENTS

- the number of seconds

OPTIONAL ARGUMENTS

keyword arguments: - :post-mins. The string used to separate minutes and seconds. Default ":" - :post-secs. The string used to separate seconds and milliseconds. Default "." - :post-msecs. The string used to follow milliseconds. Default "" - :same-width. Ensure minutes values are always two characters wide, like seconds, i.e with a leading 0. - :round. Round to the nearest second and don't print milliseconds. Default NIL.

RETURN VALUE

A string

EXAMPLE

(secs-to-mins-secs77.1232145) "1:17.123" (secs-to-mins-secs67.1) "1:07.100" (secs-to-mins-secs67.1 :same-width t) "01:07.100" (secs-to-mins-secs67.1 :same-width t :post-secs "s") "01:07s100" (secs-to-mins-secs67.1 :post-secs "secs" :post-mins "min" :post-msecs "msecs") "1min07secs100msecs" (secs-to-mins-secs67.7 :same-width t :round t) "01:08"

SYNOPSIS

(defunsecs-to-mins-secs(seconds &key round (post-mins ":") (post-secs ".") (post-msecs "") (same-width nil))

## utilities/semitones [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Return the sample-rate conversion factor required for transposing an audio file by a specific number ofsemitones. The number ofsemitonescan be given as a decimal number, and may be positive or negative.

ARGUMENTS

- A number ofsemitones.

OPTIONAL ARGUMENTS

- A number that is the factor required to transpose by an octave. Default = 2.0. - A number that is the number ofsemitonesper octave. Default = 12.

RETURN VALUE

A number.

EXAMPLE

;;; Usage with default values (semitones3) => 1.1892071 ;;; Specifying a different number ofsemitonesper octave (semitones3 2.0 13) => 1.1734605 ;;; Specifying a different factor for transposing by an octave (semitones3 4.0) => 1.4142135 ;;; Fractionalsemitonesare allowed (semitones3.72) => 1.2397077 ;;; Negativesemitonesare also allowed (semitones-3.72) => 0.80664176

SYNOPSIS

(defunsemitones(st &optional (octave-size 2.0) (divisions-per-octave 12))

## utilities/setf-last [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Change the last element in a given list to a specified new element.

ARGUMENTS

- A list. - The new last element of that list.

RETURN VALUE

Returns the new last element.

EXAMPLE

(let ((l '(1 2 3 4 5))) (setf-lastl 'dog) l) => (1 2 3 4 DOG)

SYNOPSIS

(defmacrosetf-last(list new-last)

## utilities/sort-symbol-list [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Sort a list of symbols alphabetically ascending, case-insensitive.

ARGUMENTS

A list of symbols.

RETURN VALUE

The same list of symbols sorted alphabetically ascending, case-insensitive.

EXAMPLE

(sort-symbol-list'(Lorem ipsum dolor sit amet consectetur adipiscing)) => (ADIPISCING AMET CONSECTETUR DOLOR IPSUM LOREM SIT)

SYNOPSIS

(defunsort-symbol-list(list)

## utilities/splice [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Insert the elements of a first list into a second list beginning at a specified index (0-based).

ARGUMENTS

- A list that contains the elements to be inserted into the second list. - A list into which the elements of the first argument are to be inserted. - An integer that is the index within the second list where the elements are to be inserted.

RETURN VALUE

- A list.

EXAMPLE

(splice'(dog cat goldfish) '(1 2 3 4 5 6 7 8 9) 3) => (1 2 3 DOG CAT GOLDFISH 4 5 6 7 8 9)

SYNOPSIS

(defunsplice(elements into-list where)

## utilities/split-groups [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Create a list consisting of as many repetitions of a specified number as will fit into a given greater number, with the last item in the new list being the value of any remainder.

ARGUMENTS

- A number that is to be split into repetitions of a specified smaller number (the second argument). - The number that is to be the repeating item in the new list. This number must be smaller than the first number.

RETURN VALUE

A list consisting of repetitions of the specified number, with the last element being any possible remainder.

EXAMPLE

(split-groups101 17) => (17 17 17 17 17 16)

SYNOPSIS

(defunsplit-groups(num divider)

## utilities/split-into-sub-groups [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Create a new list consisting of sublists made from the elements of the original flat list, whose lengths are determined by the second argument to the function. NB: The lengths given in the second argument are not required to add up to the length of the original list. If their sum is less than the original list, the resulting list of sublists will only contain a segment of the original elements. If their sum is greater than the length of the original list, the last sublist in the new list will be shorter than the corresponding group value.

ARGUMENTS

- A flat list. - A list of integers that are the lengths of the consecutive subgroups into which the original list is to be divided.

RETURN VALUE

A list of lists.

EXAMPLE

;; Used with a list of subgroup lengths whose sum is equal to the length of the ;; original list (split-into-sub-groups'(1 2 3 4 5 6 7 8 9 10) '(2 2 3 2 1)) => ((1 2) (3 4) (5 6 7) (8 9) (10)) ;; Used with a list of subgroup lengths whose sum is less than the length of the ;; original list (split-into-sub-groups'(1 2 3 4 5 6 7 8 9 10) '(2 1)) => ((1 2) (3)) ;; Used with a list of subgroup lengths whose sum is greater than the length of ;; the original list (split-into-sub-groups'(1 2 3 4 5 6 7 8 9 10) '(2 3 17)) => ((1 2) (3 4 5) (6 7 8 9 10))

SYNOPSIS

(defunsplit-into-sub-groups(list groups)

## utilities/split-into-sub-groups2 [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Create a new list of lists by splitting the original flat list into sublists of the specified length. NB: The length given as the second argument is not required to be fit evenly into the length of the original flat list. If the original list is not evenly divisible by the specified length, the resulting list of sublists will contain a final sublist of a different length.

ARGUMENTS

- A flat list. - An integer that is the length of each of the sublists to be created.

RETURN VALUE

A list of lists.

EXAMPLE

;; The second argument fits evenly into the length of the original list. (split-into-sub-groups2'(1 2 3 4 5 6 7 8 9 10 11 12) 3) => ((1 2 3) (4 5 6) (7 8 9) (10 11 12)) ;; The second argument does not fit evenly into the length of the original ;; list. (split-into-sub-groups2'(1 2 3 4 5 6 7 8 9 10 11 12) 5) => ((1 2 3 4 5) (6 7 8 9 10) (11 12))

SYNOPSIS

(defunsplit-into-sub-groups2(list length &optional shuffle)

## utilities/split-into-sub-groups3 [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Split a given flat list into sublists of the specified length, putting any remaining elements, if there are any, into the last sublist.

ARGUMENTS

- A flat list. - An integer that is the length of the new sublists.

RETURN VALUE

A list of lists.

EXAMPLE

(split-into-sub-groups3'(1 2 3 4 5 6 7 8 9 10 11 12) 3) => ((1 2 3) (4 5 6) (7 8 9) (10 11 12)) (split-into-sub-groups3'(1 2 3 4 5 6 7 8 9 10 11 12) 5) => ((1 2 3 4 5) (6 7 8 9 10 11 12))

SYNOPSIS

(defunsplit-into-sub-groups3(list length)

## utilities/split-into-sub-groups4 [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

August 28th 2018, Heidhausen

DESCRIPTION

Split into sub-groups with lengths defined by the integers in the second argument list. The difference here to related functions is that the given lengths will repeat circularly until no more elements of the first argument remain.

ARGUMENTS

- the list to split into sub-groups - a list of lengths, to be repeated

RETURN VALUE

a list of sublists

EXAMPLE

(split-into-sub-groups4'(1 2 3 4 5 6 7 8 9 10 11 12) '(3 4)) ==> ((1 2 3) (4 5 6 7) (8 9 10) (11 12)) (split-into-sub-groups4'(1 2 3 4 5 6 7 8 9 10 11 12 13 14) '(3 4)) ==> ((1 2 3) (4 5 6 7) (8 9 10) (11 12 13 14)) (split-into-sub-groups4'(1 2 3 4 5 6 7 8 9 10 11 12) '(1 2 3 4)) ==> '((1) (2 3) (4 5 6) (7 8 9 10) (11) (12))

SYNOPSIS

(defunsplit-into-sub-groups4(list lengths)

## utilities/srt [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Return the semitone transposition for a given sampling rate conversion factor.

ARGUMENTS

- A number that is a sample-rate conversion factor.

OPTIONAL ARGUMENTS

- A number that is the factor required for transposing one octave. - A number that is the number of scale degrees in an octave.

RETURN VALUE

A number.

EXAMPLE

;;; Using the defaults (srt1.73) => 9.4893 ;;; Using a sample-rate conversion factor of 4.0 for the octave and specifying ;;; 13 divisions of the octave (srt1.73 4.0 13) => 5.14

SYNOPSIS

(let ((last8vesize 0) (log8ve 0.0)) ;; so we don't have to recalculate each time (defunsrt(srt&optional (octave-size 2.0) (divisions-per-octave 12) ;; MDE Tue Feb 7 16:59:45 2012 -- round so we don't get tiny ;; fractions of semitones due to float inaccuracies? (round-to 0.0001))

## utilities/string-replace [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Replace specified segments of a string with a new specified string.

ARGUMENTS

- A string that is the string segment to be replaced. - A string that is the string with which the specified string segment is to be replaced. - The string in which the specified segment is to be sought and replaced.

RETURN VALUE

A string.

EXAMPLE

(string-replace"flat" "\\flat" "bflat clarinet") => "b\\flat clarinet"

SYNOPSIS

(defunstring-replace(what with string)

## utilities/swap-elements [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Swap the order of each consecutive pair of elements in a list.

ARGUMENTS

- A list.

RETURN VALUE

A list.

EXAMPLE

(swap-elements'(1 2 3 4 5 6 7 8 9 10)) => (2 1 4 3 6 5 8 7 10 9) (swap-elements'(1 2 3 4 5 6 7 8 9)) => (2 1 4 3 6 5 8 7 9)

SYNOPSIS

(defunswap-elements(list)

## utilities/update-app-src [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DATE

June 1st 2013

DESCRIPTION

TEMPORARILY DISABLED DUE TO SVN SERVER ACCESS RESTRICTIONS. NB This function currently works in SBCL and CCL on UNIX systems only. For users of the slippery chicken app, this function will update the source code of the app to the latest in the online subversion (svn) repository. An internet connection is therefore necessary. The first time it is run it will delete the current source code and download all the new source code, so make sure to back up if you've modified the source code yourself (not recommended). When it is run from then on, it will only update the source code that is out of date. Once the source code is updated, you'll need to restart the app or just Lisp for the changes to be recompiled. **NB** The first time you call this function, you might get a "certificate error". In order to accept the certificate, start the terminal application and type the following: cd /tmp/ svn co https://svn.ecdf.ed.ac.uk/repo/user/medward2/sc-tags/sc-latest/src That should give you a prompt in the terminal from which you can accept the certificate. Then the next time you try it from Lisp the certificate should not cause a problem. Users without the app can always download the latest source code in a terminal by issuing the following command. svn co https://svn.ecdf.ed.ac.uk/repo/user/medward2/sc-tags/sc-latest/src

ARGUMENTS

The full path to the slippery-chicken application, minus the last slash. Remember that this can't include any spaces in file/folder names

OPTIONAL ARGUMENTS

keyword arguments: - :rm. The path to the shell 'rm' command. Default = "/bin/rm" - :svn. The path to the shell 'svn' command. Default = "/usr/bin/svn"

RETURN VALUE

The shell return value of the call to SVN, usually 0 on success.

EXAMPLE

Running for the first time: (update-app-src"/tmp/sc-app/slippery-chicken.app") A /tmp/sc-app/slippery-chicken.app/Contents/Resources/sc/src/sndfile.lsp A /tmp/sc-app/slippery-chicken.app/Contents/Resources/sc/src/osc.lsp A /tmp/sc-app/slippery-chicken.app/Contents/Resources/sc/src/osc-sc.lsp [...] Checked out revision 3608. 0 or after successfully updating a previously updated version: ... At revision 3608. 0

SYNOPSIS

(defunupdate-app-src(path-to-app &key (rm "/bin/rm") (svn "/usr/bin/svn"))

## utilities/visualize [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Leon Focker: leon@leonfocker.de

DATE

February 23rd 2023

DESCRIPTION

Print a Visualization of an array or a list into the repl with 64 values -> *ascii art* <-

ARGUMENTS

- An array or a list

OPTIONAL ARGUMENTS

keyword arguments: :y-range. Maximum value that the y-axis display. When nil, the graph will be normalized. :start. Where to start reading the sequence from. Default = 0 :abs. When t, the absolute value of all numbers is visualized :scale. If the sequence is shorter than 64 and scale is t, the graph will be scaled to 64 values

RETURN VALUE

":)"

EXAMPLE

(visualize(loop repeat 64 for i from 0 by 0.1 collect (sin i))) (visualize(loop repeat 128 for i from 0 by 0.1 collect (sin i)) :start 64) (visualize(loop repeat 128 for i from 0 by 0.1 collect (* (sin i) 2)) :scale nil :start 96) (visualize(loop repeat 55 for i from 0 by 0.1 collect (* (sin i) 2)) :scale nil :abs t :y-range 1)

SYNOPSIS

(defunvisualize(ls &key y-range (start 0) abs (scale t))

## utilities/wavelab-to-audacity-marker-file [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Write a .txt file suitable for import to audacity with the same name and in the same directory as the file argument.

ARGUMENTS

- A string that is the name of a wavelab marker file, including directory path and extension.

OPTIONAL ARGUMENTS

- An integer that is the sampling rate of the sound file to which the wavelab marker file refers. This value will affect the times of the output.

RETURN VALUE

Returns T and prints the number of markers read to the listener.

EXAMPLE

(wavelab-to-audacity-marker-file"/path/to/24-7.mrk" 44100) => 51 markers read

SYNOPSIS

(defunwavelab-to-audacity-marker-file(file &optional (sampling-rate 44100))

## utilities/wrap-list [ Functions ]

[ Top ] [ utilities ] [ Functions ]

DESCRIPTION

Shift the elements of a list to start at a specified position and wrap to the beginning of the list to the list's tail.

ARGUMENTS

- A list. - An integer which is the 0-based position in the original list where the new list is to begin.

RETURN VALUE

A list.

EXAMPLE

(wrap-list'(1 2 3 4 5 6 7 8 9) 4) => (5 6 7 8 9 1 2 3 4)

SYNOPSIS

(defunwrap-list(list start)

## utilities/write-list-to-coll [ Functions ]

[ Top ] [ utilities ] [ Functions ]

AUTHOR

Daniel Ross (mr.danielross[at]gmail[dot]com)

DATE

Tue 18 Feb 2020 15:38:40 GMT

DESCRIPTION

Turn a list of lists into a text file, formatted to be read by the MaxMSP [coll] object. This is a bit like gen-max-coll-file (see set-palette.lsp) but instead works with any data in a list.

ARGUMENTS

- A list of lists in the form '((a b c) (d e f))

OPTIONAL ARGUMENTS

keyword arguments :file - the output file. Default = "/tmp/sc-max-coll.txt" :base - the minimum number for coll indexing. In the resulting output file, each list in the list of lists will be preceeded by an (increasing) integer and a comma. This argument sets the base value of that integer. Default = 0. :capitalize - Should any outputted text be capitalized or not? Default = NIL. :if-exists - what to do if the file already exists. This argument is passed to with-open-file. More info here: http://clhs.lisp.se/Body/m_w_open.htm Default = :supercede :prefix - add a string prefix to the item number. Default = NIL. :alt-label - if you do not want the items labels to be consecutive numbers, then you can here either provide a list of lists or a function. If a list of lists, this must be the same length as the first argument. If a function, it must be called with the item number (which increases incrementally from base).

RETURN VALUE

The output file location

EXAMPLE

(let ((l '((hello!)(how are you?)(very well thank you.)(1 2 3 4)))) (write-list-to-colll :base 6)) => "/tmp/sc-max-coll.txt" The resulting text file will looks like this when opened: 6, hello!; 7, how are you?; 8, very well thank you.; 9, 1 2 3 4; ;; DJR Tue 3 Mar 2020 13:52:34 GMT (let ((l '((hello!)(how are you?)(very well thank you.)(1 2 3 4)))) (write-list-to-colll :base 15 :alt-label #'(lambda (count) (let ((l '(foo bar))) (nth (mod count 2) l))) :prefix "yes_")) => "/tmp/sc-max-coll.txt" The resulting text file will looks like this when opened: yes_bar, hello!; yes_foo, how are you?; yes_bar, very well thank you.; yes_foo, 1 2 3 4;

SYNOPSIS

(defunwrite-list-to-coll(data-list &key (base 0) (file "/tmp/sc-max-coll.txt") (capitalize nil) (if-exists :supersede) ;; DJR Tue 3 Mar 2020 13:52:34 GMT (prefix "") alt-label)