Skip to content

Drawn Wave Shape Recipes

atom edited this page Sep 3, 2026 · 1 revision

Drawn Wave-Shape Recipes

This page approaches Drawn as a synthesizer programmer rather than as a catalogue of mathematical functions.

The recipes are deliberately small. Most begin with either two authored amplitudes:

"data": [-1, 1]

or four familiar quarter-cycle landmarks:

"data": [0, 1, 0, -1]

Stage-1 construction decides what those few numbers mean between — or across — the authored values. An optional stage-2 transform then asks which Fourier, Haar, or Walsh components should rebuild the completed waveform.

Recipe layer Main question Current v3 tools
Construction (resample_mode) What complete waveform do these authored values describe? Steps, Linear, Power, Power Symmetric, Superellipse, Cardinal family, Fourier
Transform (transform) Which components of that completed 512-internal-cycle-sample waveform should rebuild it? Fourier, Haar, Walsh-Hadamard

Fourier deliberately belongs to both rows: sparse Fourier construction and whole-waveform Fourier transformation are related operations at different pipeline stages. Haar and Walsh are transform-only.

For the exact reconstruction rules, storage contract, and numerical function comparisons, see Drawn Waveform. For the complete operation/default table and function-by-function gallery, see Drawn Mathematical Reference.

The example JSON files are deliberately readable. A useful way to learn the reconstruction rules is to download one, open it in a text editor, change one field, import it again, and compare the result. The recipes below point out a few especially revealing edits.

In the cyclic diagrams, filled dots are authored values. When wrap:true supplies the final connection back to the first authored value, a hollow dot at cycle position 1 shows that implicit closing point. For Steps, a filled marker identifies the beginning of the authored state interval. With steps=0 the value is held from that marker until the next state begins; with nonzero steps=N the same fixed points are joined by complementary signed curves.

Mathematical ideals are reference points

A mathematically ideal waveform is useful as a reference, but it is not automatically a better synthesizer waveform.

Physical oscillators, amplifiers, filters, converters, sampling systems, and other signal paths have finite bandwidth and finite precision. Analogue component choice and tolerances, calibration, age, temperature, and — in some designs and environments — humidity can alter what an instrument actually produces. Digital systems introduce their own sampling, interpolation, quantisation, filtering, and algorithmic behaviour.

“Distortion” is the technically correct word for a departure from an intended or ideal signal, even when the result is desirable. In synthesizer culture the word can sound negative, but classic instruments are not coveted because they produce mathematically perfect sine, triangle, saw, or square waves. Their characteristic departures from those ideals are often part of what makes them identifiable and useful.

Drawn makes that territory deliberate and calculable. A waveform can be close to a familiar mathematical shape without being identical to it. Slightly different curvature, dwell time, symmetry, overshoot, clipping, or spectral balance can be exactly what a patch needs.

So the useful questions are not only:

  • “How close is this to a pure sine?”
  • “Is this an exact square?”

They also include:

  • “What happens if I soften it?”
  • “What happens if I make the transition steeper?”
  • “What happens if I remove one point?”
  • “What happens if I add a point?”
  • “What happens if I keep only its low harmonics?”
  • “What happens if I listen to the difference?”

Start from a sine, then decide how to bend it

A sine is a useful common reference because several Drawn reconstruction families can reach it, or get extremely close to it, from very little authored data. They do not get there by the same route.

Pure sine overlaid with three sparse Drawn reconstruction routes

Four compact starting points are:

Construction Why it is useful
[-1,1], pow-symmetric=1.7503, wrap:true A two-point local curve that is very sine/cosine-like. Change the exponent to move smoothly toward triangle-like or softer-square territory.
[0,1,0,-1], bare cardinal, wrap:true Four familiar quarter-cycle landmarks with neighbour-aware cubic curvature. Change the signed Cardinal amount to reshape how the curve approaches and leaves those landmarks.
[0,1,0,-1], bare cardinal-limit, wrap:true The same near-sine as bare Cardinal on these landmarks, because its tangents still fit inside the available rail headroom. Push the amount harder to hear the local rail-safe limiter take over.
[0,1,0,-1], fourier A mathematically exact sine reconstruction to Float32/numerical precision from four periodic samples. Edit a landmark or the harmonic selection and the effect is global/spectral rather than confined to one local segment.

The corresponding importable examples are two-point sine-like Power, four-landmark Cardinal, and four-point Fourier sine.

Several intentionally characterful distortions derived from sine starting points

The second figure is not a ranking. It shows three different kinds of departure from the sine reference: local symmetric curvature, neighbour-aware clipping, and a global Fourier change caused by lowering one quarter-cycle landmark from -1 to -0.7. Each can be useful as an oscillator waveform or as a Scanning LFO contour. For LFO audition, slow the rate enough to hear the motion of the controlled generator, then raise Rate/Depth once the contour is familiar.

Then dissect the completed waveform

Once a stage-1 sine or near-sine is familiar, keep its construction fixed and add a transform. For example, start from the same four Cardinal landmarks and compare:

fourier=1
haar=:3
walsh=:15

Those selectors do not reinterpret the four authored points. Stage 1 first constructs the complete 512-internal-cycle-sample waveform; the transform then decomposes and rebuilds that completed table in its own basis. Try -1, -3, or another negative singleton to invert one selected component rather than omitting it.

This is a useful way to hear the distinction between changing the curve that makes the waveform and changing the components that rebuild the waveform.

The same sine landmarks are also a compact demonstration of why cardinal-limit exists:

Cardinal, cardinal-limit, and cardinal-clip compared on the same four sine landmarks

At the bare default, ordinary cardinal and cardinal-limit coincide on [0,1,0,-1]: no tangent needs limiting. As the shared signed Cardinal control is pushed, ordinary cardinal preserves the raw trajectory and proportionally fits the completed result when required, cardinal-limit spends only the tangent headroom that keeps the continuous cubic inside ±1, and cardinal-clip hard-clips excursions. On this source, positive cardinal-limit reaches its maximum rail-safe tangent state at about N=0.752204; values above that through +1 make the same limited curve. That saturation point is specific to these authored amplitudes.

Importable pushed cardinal-limit sine-landmark example

Two values can already make several classic shapes

Exact square: steps

{
  "data": [-1, 1],
  "resample_mode": "steps",
  "wrap": true
}

Exact two-state square wave made from the two Drawn values minus one and plus one with steps

Importable JSON

Bare steps and steps=0 are exact held-state reconstruction. The two values divide the cycle into two equal-duration states: with 512 internal cycle samples, [-1,1] is exactly 256 samples at -1, then 256 samples at +1.

That is a mathematically exact discrete 50% square wave, not an approximation to one. Other state lists can build exact pulse/step sequences just as directly.

Steps is intrinsically cyclic. The final state returns to the first at the cycle seam, so canonical recipes use "wrap": true; imported false, null, or an omitted field are tolerated but have the same effective topology.

In the diagrams, each Steps marker is placed at the beginning of its ordinary held-state interval. That point becomes especially useful once Steps is parameterised.

Slew or bend the Steps intervals: steps=N

For a synth-first example, keep the same two values as the exact square and change only the mode:

{
  "data": [-1, 1],
  "resample_mode": "steps=-0.1",
  "wrap": true
}

Exact steps zero square wave compared with a steps minus 0.1 square wave whose edges have finite curved slew

Importable steps=-0.1 slew recipe

The steps=0 reference is an exact discrete square whose edges change instantaneously. steps=-0.1 is one classic-synth-style slew example: it starts moving immediately after each state boundary and then settles progressively toward the new level, retaining long high/low dwell regions while replacing the mathematical vertical edge with finite curved travel. That resembles a common RC-like analogue slew characteristic: real oscillator/output and waveform-shaping circuitry has finite bandwidth and does not produce an infinitely vertical voltage step. FWG is reproducing that broad behaviour here, not claiming a component-level model of any one vintage oscillator. The figure also includes steps=+0.1 as the complementary late-moving edge.

There is no prescribed amount or sign. steps=N accepts any finite value from -1 through +1, at whatever numeric precision is useful. Try -0.05, -0.1, -0.23, nearby positive values, or anything else in range. Smaller nonzero magnitudes stay closer to a hard square; larger magnitudes spend more of each state interval moving. The two signs put the curved motion on complementary sides of the same cyclic state boundaries.

Exact square compared with several negative Steps values showing progressively broader slew

Use the numbers as a listening control, not a vintage-synth calibration scale.

The same mechanism is more general than analogue-style slew. The parameterised form keeps the same authored state positions and bends the interval from one state boundary to the next.

Engineering reference

For finite nonzero N in -1…+1, FWG uses the existing signed Power geometry with:

p = 1 / |N|

Positive values use the slow-start / fast-finish Power direction; negative values use its complementary fast-start / slow-finish direction. Both pass through the same fixed authored state points.

Classic Steps compared with complementary steps plus and minus 0.3 curves between the same cyclic authored boundaries

Positive steps=0.3 JSON · Negative steps=-0.3 JSON

The parameter has unusually simple landmarks:

  • steps=0 — exact classic held Steps;
  • steps=±0.5 — signed Power exponent ±2 geometry;
  • steps=±⅓ — signed Power exponent ±3 geometry;
  • steps=±0.25 — signed Power exponent ±4 geometry;
  • steps=+1 = steps=-1 = linear — both signed formulas naturally reduce to a straight line, with no special case.

So the signed symmetry converges through ±1 = linear, rather than through the special 0 case. As the magnitude approaches zero, each sign becomes increasingly step-like from its own complementary direction; exactly 0 remains the explicit zero-order-hold construction.

Nonzero steps=N is intentionally a musician-facing reciprocal spelling of wrapped signed Power, not a separate curve family. Where the reciprocal is finite:

steps=N  ==  pow=1/N, wrap:true

For example, steps=-0.1 is exactly wrapped pow=-10, and steps=-0.05 is exactly wrapped pow=-20. The reason to keep the Steps spelling is the control language: a musician can start at steps=0 for an exact square/pulse hold, add a small signed amount of slew, and reach linear at ±1 without thinking in very large reciprocal Power exponents. Exact steps=0 has no finite pow equivalent.

Because the points retain their ordinary Steps spacing, adding more authored states automatically gives each connection less horizontal room. That makes parameterised Steps useful for anything from broad two-state bends to small curved departures in a dense step sequence without a separate transition-width parameter.

Triangle: linear

A phase-familiar four-point triangle is:

{
  "data": [0, 1, 0, -1],
  "resample_mode": "linear",
  "wrap": true
}

Exact triangle wave through zero plus one zero minus one using linear interpolation and wrap

Importable JSON

linear does what its name says: it draws a straight line from each value in data to the next one. With four values and wrap:true, the four authored points are spaced evenly around the cycle — here at 0%, 25%, 50%, and 75% — and the last quarter of the cycle draws the straight line from the final -1 back to the first 0.

A still smaller construction is [-1,1] with linear and wrap:true. The two values are then equally spaced cyclic anchors: -1 at the beginning of the cycle and +1 halfway around it. Linear reconstruction draws one straight rise during the first half and, because wrap:true connects the final anchor back to the first, one straight return during the second half.

Try the topology yourself: download the example JSON, open it in a text editor, change "wrap": true to "wrap": false, and import it again. With wrap:false, the same two numbers are interpreted as the first and last points of an open sequence, so FWG draws only the straight rise from -1 to +1; when the finished table loops, it jumps back to -1 at the seam. This is a compact way to see exactly what wrap changes.

One parameter can move between familiar territories

pow-symmetric: triangle → sine-like → soft square

With the same two authored amplitudes and the same wrapped topology:

{
  "data": [-1, 1],
  "resample_mode": "pow-symmetric=1",
  "wrap": true
}

pow-symmetric=1 is mathematically exact linear interpolation, so the result is a triangle.

Two-point wrapped pow-symmetric equals one triangle wave

JSON

Change only the value:

"resample_mode": "pow-symmetric=1.7503"

and the same two points become very close to a phase-shifted sine/cosine:

Two-point wrapped pow-symmetric 1.7503 wave compared with a pure phase-shifted sine

JSON

Increase the value further and the waveform spends more of the cycle near its extremes:

Two-point wrapped pow-symmetric 4 soft square-like wave

JSON

Two-point wrapped pow-symmetric 8 harder square-like wave

JSON

The sign is just as useful as the magnitude. A negative value uses the complementary out-in symmetric curve. For example:

"resample_mode": "pow-symmetric=-1.75"

Comparison of wrapped two-point pow-symmetric plus 1.75 and minus 1.75 waveforms

Importable negative-value JSON

Where the positive value lingers nearer the extrema and moves faster through the middle of each transition, the negative value moves away from each extremum sooner and spends more of the transition around its midpoint. In a two-point wrapped bipolar waveform, that means visibly more dwell around zero. Try changing only the sign in the JSON and re-importing it.

There is no requirement to stop at the value that most closely resembles a textbook waveform. Positive, negative, and nearby values are different waveforms and different LFO contours.

superellipse: geometric segment shaping

superellipse is useful when you want a segment to behave more like geometry than like an ordinary easing curve. superellipse=2 is the exact retained circle-in case; larger magnitudes push progressively farther toward rectangular geometry. The sign selects the time-complementary direction.

A single non-wrapped transition from -1 to +1 makes that easy to see:

Superellipse 4 transition from minus one to plus one

Importable superellipse=4 JSON

At superellipse=16, most of the geometric change is pushed much closer to one end of the segment:

Superellipse 16 transition from minus one to plus one

Importable superellipse=16 JSON

These examples show one transition rather than a complete cyclic waveform on purpose. In a sparse Drawn construction, the same segment rule is applied between every neighbouring pair of authored points. Add wrap:true and it also shapes the final-to-first segment. Change the sign to see the complementary direction, then try the same setting on three or four authored amplitudes to turn the geometric transition into a complete waveform or LFO contour.

Four cardinal points: phase landmarks a synth programmer recognises

The four values:

"data": [0, 1, 0, -1]

place zero crossings and extrema at the familiar quarter-cycle positions when used with wrap:true: the four authored values sit at cycle positions 0, 0.25, 0.5, and 0.75, and the hollow point at cycle position 1 repeats the first value to show the implicit closing segment.

Cardinal: nearly a sine by default

{
  "data": [0, 1, 0, -1],
  "resample_mode": "cardinal",
  "wrap": true
}

Bare cardinal means cardinal=0.621864 on the shared ±1 Cardinal scale.

Four-cardinal-point Cardinal default waveform compared with a pure sine

Importable JSON

Against a pure sine at the current 512-internal-cycle-sample core, this construction is extremely close: correlation is about 0.999993, with RMS amplitude difference about 0.00297.

Cardinal is neighbour-aware rather than merely shaping each segment in isolation. Each point helps determine the tangent through its neighbours. That lets the same four values behave like zero crossings and extrema instead of four unrelated easing segments.

Cardinal limiting: signed Cardinal curvature without leaving ±1

cardinal-limit starts from the same signed Cardinal tangent as cardinal, but limits each shared anchor tangent according to the ±1 amplitude headroom at that authored value. It does not require the curve to remain monotone; negative values can still bow backwards or create local reversals as long as the continuous cubic stays inside the Drawn rails.

The accepted public parameter range is -1…+1; bare cardinal-limit means 0.621864.

With four rail-touching phase landmarks, a strong positive amount is restrained around the ±1 extrema instead of being globally attenuated or hard-clipped:

{
  "data": [0, 1, 0, -1],
  "resample_mode": "cardinal-limit=0.860022",
  "wrap": true
}

Comparison of cardinal, cardinal-limit, and cardinal-clip at public N 0.860022 on four phase landmarks

Importable cardinal-limit=0.860022 JSON

Negative values are easier to hear on authored points that do not already sit on the rails. This eight-point mid-rail construction leaves room for reverse-pointing negative tangents:

{
  "data": [-0.65, 0.15, 0.7, -0.1, -0.8, 0.25, 0.6, -0.2],
  "resample_mode": "cardinal-limit=-0.860022",
  "wrap": true
}

Signed negative cardinal-limit N -0.860022 compared with ordinary Cardinal at the same public value on mid-rail data

Importable cardinal-limit=-0.860022 JSON

Try -0.62, -0.75, -0.860022, and -0.91 on the same data. Unlike the earlier monotonicity-limited research prototype, the Bézier rail limiter preserves a genuine signed continuum whenever the anchor amplitudes leave enough headroom.

Cardinal clipping: sine-like → soft square → harder square

cardinal-clip uses the same Cardinal reconstruction, then hard-clips any raw reconstruction outside -1…+1.

At the default, nothing needs clipping and it is identical to ordinary Cardinal.

At a larger value:

{
  "data": [0, 1, 0, -1],
  "resample_mode": "cardinal-clip=0.860022",
  "wrap": true
}

Cardinal clip N 0.860022 soft square made from four cardinal points

JSON

And harder:

"resample_mode": "cardinal-clip=0.926417"

Cardinal clip N 0.926417 harder square made from four cardinal points

JSON

The unclipped partner is deliberately different. cardinal=0.860022 produces a temporary reconstruction that overshoots the normal Drawn rails:

Pre-admission Cardinal N 0.860022 reconstruction visibly overshooting plus and minus one

JSON

FWG measures that complete 512-internal-cycle-sample reconstruction before it becomes Drawn state. If its sampled peak exceeds ±1, the whole waveform is proportionally attenuated into the Drawn ±1 domain; DC is scaled by the same factor and is not removed. A reconstruction already within ±1 is left at its original amplitude. cardinal-clip, by contrast, has already changed the shape by flattening excursions against the rails before admission.

Together with cardinal-limit=value, these are three deliberate sound-design treatments of the same signed Cardinal tangent: fit the completed result, restrain the trajectory locally, or hard-clip the result.

Fourier: treat the points as periodic samples

Fourier takes a different view of the authored values. It treats them as equally spaced samples of one periodic waveform and reconstructs that waveform from its harmonic content.

Fourier is intrinsically cyclic. Canonical construction records use wrap:true, but the periodic interpretation does not depend on an ordinary local interpolation seam.

Four points make an exact sine

{
  "data": [0, 1, 0, -1],
  "resample_mode": "fourier",
  "wrap": true
}

Four point Fourier reconstruction exactly matching a sine wave at the 512-sample core

Importable JSON

Those four samples contain only harmonic 1, with zero DC. Bare fourier, fourier=1, and fourier=:1 therefore reconstruct the same sine. Under the final v3 selector grammar, fourier=-1 reconstructs that same harmonic with its coefficient contribution inverted — a 180° phase reversal — rather than meaning “remove harmonic 1.”

Body, residual, and inversion are different operations

The final shared selector language is:

  • fourier=N — exactly order N;
  • fourier=-N — exactly order N, coefficient contribution inverted;
  • fourier=:B — orders 0…B;
  • fourier=A: — order A upward;
  • fourier=A:B — inclusive range;
  • comma — union, with an explicit negative singleton overriding normal inclusion for that component.

For a 512-sample real Drawn waveform the public namespace is 0…256. Direct sparse Fourier may physically contain fewer orders; a valid unavailable order simply contributes zero.

With this seven-point arbitrary shape:

"data": [-1, 0.9, 0.85, -0.8, 0.15, 1, -0.3]

the low-order body is:

"resample_mode": "fourier=:2"

Seven-point Fourier reconstruction retaining orders zero through two

JSON

The complementary available residual above order 2 is:

"resample_mode": "fourier=3:"

Seven-point Fourier residual retaining order three upward

JSON

And all available harmonic information is:

Seven-point full Fourier reconstruction

JSON

The body/residual pair is selected by omission/ranges. Negative singleton terms now do something that omission cannot do: invert a retained component. For example fourier=:3,-2 keeps orders 0 through 3 but phase-reverses order 2.

fourier-clip uses the same selector grammar and differs only when the selected reconstruction overshoots ±1 before Drawn admission.

Use Fourier on an existing FWG waveform

Fourier is also useful after you have already made a complete waveform elsewhere in FWG:

  1. Make or randomise a waveform you like in an ordinary generator.
  2. Use Copy Input 1 Source → Drawn to capture the current 512-sample source.
  3. Export Drawn to obtain the literal editing surface.
  4. In a text editor, keep the 512 data values and set resample_mode to a Fourier selector such as fourier=:8, fourier=9:, or fourier=:16,-3.
  5. Re-import and A/B the result.

Exactly 512 numeric values are normally literal, but Fourier/Fourier-clip are the deliberate stage-1 exception: they analyse those complete samples instead of bypassing reconstruction. That makes this a convenient way to dissect a generated waveform without deleting or resampling any of its 512 values first.

pow: direction matters — and so does point count

pow is deliberately one-sided rather than symmetric. A positive value such as pow=8 keeps each segment near its starting amplitude for longer and makes most of the move late in the segment. The negative partner, pow=-8, is the exact time-complement: it makes most of the move early and eases toward the destination.

There is also no rule that says a useful periodic recipe has to use four phase landmarks. With three authored values and wrap:true, the same directed curve is applied to three successive cyclic segments. For example:

{
  "data": [0, 1, -1],
  "resample_mode": "pow=8",
  "wrap": true
}

Three-point cyclic wave using pow 8

JSON

Change only the sign — and therefore the direction of the curve:

Three-point cyclic wave using pow minus 8

JSON

This is another good text-editor experiment: keep data and wrap unchanged, switch only pow=8pow=-8, and listen to how moving the same amplitude transition earlier or later changes both an audio waveform and an LFO contour.

Or make every segment symmetric and steep:

Three-point cyclic wave using pow-symmetric 8

JSON

These are not failed four-point sine recipes. They are three-point waveforms.

That is a useful general habit with Drawn:

  1. start from a recognisable sparse construction;
  2. add a point;
  3. remove a point;
  4. move one point;
  5. change only the reconstruction value;
  6. compare clipped and unclipped forms;
  7. listen both as audio and as an LFO.

Transform the completed waveform

The recipes above mostly explore stage-1 construction: how a few authored values become a complete waveform. The optional v3 transform stage starts after that waveform has been materialised to the canonical bounded 512-sample Float32 Drawn table. Fourier, Haar, and Walsh then provide three very different ways to select, invert, or discard structure.

Cardinal → high-sequency Walsh → normalise

Importable JSON

{
  "data": [0, 1, -1],
  "resample_mode": "cardinal=0.79",
  "wrap": true,
  "transform": "walsh=15:",
  "normalise": true
}

Stage 1 makes the curved waveform from recipe 2. Walsh then discards sequencies below 15 and rebuilds from the faster rectangular/global components. Final normalisation restores the meaningful peak if the selected reconstruction is quieter than full scale.

Useful variations include walsh=8:, walsh=31:, or a bounded range such as walsh=15:80.

Haar coarse body with the top retained band inverted

Importable JSON

{
  "data": [1, -1, 0],
  "resample_mode": "linear",
  "wrap": true,
  "transform": "haar=:5,-5"
}

haar=:5 retains the mean plus bands 1 through 5. The additional -5 leaves band 5 selected but reverses its contribution. This is a compact way to hear that a negative singleton is coefficient inversion, not omission.

Try haar=:5, then haar=:5,-5, then invert a different retained band.

Fourier harmonic inversion

Importable JSON

{
  "data": [0, 1, -1],
  "resample_mode": "linear",
  "wrap": true,
  "transform": "fourier=:8,-3"
}

The transform retains DC and harmonic orders 1 through 8, but harmonic 3 is rebuilt with its coefficient pair multiplied by −1. Its magnitude is retained while its contribution is phase-reversed by 180°.

Compare fourier=:8, fourier=:8,-3, and combinations such as fourier=:8,-2,-3,-5.

Walsh component inversion

Importable JSON

{
  "data": [0, 1, -1],
  "resample_mode": "cardinal=0.79",
  "wrap": true,
  "transform": "walsh=:80,-37"
}

This keeps sequencies 0 through 80 but reverses sequency 37's contribution. Walsh inversion can change cancellations and edge structure without changing which component numbers are present.

Try a few isolated negative terms inside a broad retained range.

Sparse Fourier as stage-1 construction

Importable JSON

{
  "data": [0, 1, -0.3, 0.7, -1],
  "resample_mode": "fourier=:3,-2"
}

Fourier is the one v3 basis that also has a direct sparse construction role. Here the authored points are treated as the source of a small real DFT; the selector requests the available low orders through 3 and reverses order 2 where it exists.

Because sparse input may physically contain fewer orders than the public 0…256 selector domain, a valid unavailable order simply contributes zero.

Fourier construction → Haar transform

Importable JSON

{
  "data": [0, 1, -0.3, 0.7, -1],
  "resample_mode": "fourier",
  "transform": "haar=:5,-3",
  "normalise": true
}

This demonstrates the hard two-stage boundary. Sparse Fourier first constructs and admits the canonical 512-sample Drawn waveform. Haar receives those exact samples, keeps bands 0 through 5, reverses band 3, and final normalisation is applied once at the end.

Changing stage 1 to linear, steps, or cardinal while keeping the same Haar transform is a useful A/B experiment.

Steps → Fourier high-frequency residual

Importable JSON

{
  "data": [-1, 1],
  "resample_mode": "steps",
  "transform": "fourier=12:",
  "normalise": true
}

The exact held waveform is constructed first, then Fourier keeps harmonic order 12 upward. This removes the low harmonic body while preserving the faster spectral structure that remains available in the completed 512-sample waveform.

Move the lower boundary up and down to hear where the waveform stops reading as its original body and starts reading mainly as edge/detail material.

Linear → coarse Haar

Importable JSON

{
  "data": [-1, 1],
  "resample_mode": "linear",
  "wrap": true,
  "transform": "haar=:4"
}

A smooth wrapped linear construction is rebuilt from the mean and coarse Haar bands only. On smooth sources this often produces the characteristic dyadic block/staircase effect associated with Haar.

Try haar=:2, haar=:3, haar=:4, and progressively finer upper bands. The apparent “quantisation” is time/dyadic structure, not uniform amplitude quantisation.

DC-offset final normalise

Importable JSON

{
  "data": [0.25, 0.5],
  "resample_mode": "steps",
  "normalise": true
}

Final normalise:true is one uniform gain around zero. This all-positive waveform becomes approximately +0.5…+1.0 rather than being remapped to −1…+1. DC remains part of the waveform and scales with everything else.

This is useful for distinguishing FWG's final peak normalisation from bipolar min/max remapping.

Walsh versus Walsh-clip stress

Importable JSON

{
  "data": [0, 1, -1, 0.25, -0.4],
  "resample_mode": "steps",
  "transform": "walsh-clip=8:95"
}

Selected transform components can reconstruct beyond ±1 because removing components also removes some cancellations. The -clip transform family hard-clips those excursions instead of proportionally fitting the complete reconstruction.

For an A/B comparison, change only:

walsh-clip=8:95

to:

walsh=8:95

If a particular selection does not overshoot, the two variants are expected to be identical.

Recipe-building patterns

A few useful ways to explore without inventing a completely new recipe each time:

  • Keep construction fixed; move a transform boundary. Example: haar=:2:3:4, or walsh=8:16:32:.
  • Keep the selected set; invert one component. Example: fourier=:8fourier=:8,-3.
  • Keep the transform fixed; change stage 1. Compare steps ; haar, linear ; haar, and cardinal ; haar from the same authored points.
  • Use normalise:true only after you have heard the unnormalised relationship. It can make quiet residual/detail selections easier to compare, but the gain can hide how much energy the selection originally retained.
  • Flatten and hand-edit. Once a formula has taken you close to the wanted shape, ordinary Drawn editing can take over; the recipe is a shortcut, not a cage.

Listen in more than one role

A recipe can be evaluated several ways without changing the Drawn data itself.

For direct audio:

  • route Drawn to Input 1;
  • choose Wavetable Type 0 – Input 1.

For Scanning:

  • choose a Scanning – … generator;
  • use the same Drawn waveform as the Scanning LFO;
  • vary LFO Rate and LFO Depth.

For Morph A/B:

  • put one Drawn recipe in START and another in END;
  • keep the other patch settings equal;
  • use S and E to compare endpoints before auditioning the Morph.

A difference that is subtle as a single-cycle oscillator can be obvious as a slow LFO, and vice versa. Neither audition is inherently the more important one.

Exact rules and mathematical gallery

For the complete mode/parameter table, formulas, selector domains, comparison methodology, numerical similarity table, and the restored function-by-function gallery, see Drawn Mathematical Reference.

Fractured Wavetable Generator

Start here

🎹 Workspaces

🎹 Build and shape sounds

🎹 Make and keep results

🎹 Scanning and custom trajectories

Help and reference

🔧 Advanced / technical reference

Clone this wiki locally