adc
result = adc(x, [bits=12], [full_scale=]|[vmin=], [vmax=], [dither=false], [seed=])
Input: x, bits, full_scale, vmax, dither, seed · Output: result
What it is
Quantises x (a length-N number vector) the way a converter does — with a reference range, not just a step size, so a signal outside [vmin, vmax] clips instead of being quantised as if the range were infinite. This is also the engine's quantization *simulator*: the design doc's quantize(bits:) and simulateADC(bits:, fullScale:) are this one function, not two more. bits (positional or named integer, at least 1, default 12) fixes the code count 2^bits; vmin/vmax (named numbers) default to -peak/+peak of x itself; full_scale= (named positive number) is the symmetric shorthand for vmin=-full_scale, vmax=+full_scale, sharing the word dbfs/is_clipped/detect_saturation use for the same quantity — giving it *together with* vmin= or vmax= is an error, not a precedence rule, the same way add_noise refuses snr= and amplitude= together. dither (named boolean, default false) adds two-LSB peak-to-peak TPDF noise before quantising, with seed (named integer) the RNG seed it uses. See the section above for the full field-by-field discussion.
Overloads
One call shape — this function is not overloaded.
| Code | Input | Output | Description |
result = adc(x, [bits=12], [full_scale=]|[vmin=], [vmax=], [dither=false], [seed=]) | x number or vectorQuantises x (a length-N number vector) the way a converter does — with a reference range, not just a step size, so a signal outside [vmin, vmax] clips instead of being quantised as if the range were infinite.bits optional (default 12)bits (positional or named integer, at least 1, default 12) fixes the code count 2^bits.full_scale number, optional (default ]|[vmin=)full_scale= (named positive number) is the symmetric shorthand for vmin=-full_scale, vmax=+full_scale, sharing the word dbfs/is_clipped/detect_saturation use for the same quantity — giving it *together with* vmin= or vmax= is an error, not a precedence rule, the same way add_noise refuses snr= and amplitude= together.vmax number or vector, optionalQuantises x (a length-N number vector) the way a converter does — with a reference range, not just a step size, so a signal outside [vmin, vmax] clips instead of being quantised as if the range were infinite.dither boolean, optional (default false)dither (named boolean, default false) adds two-LSB peak-to-peak TPDF noise before quantising, with seed (named integer) the RNG seed it uses.seed boolean, optionaldither (named boolean, default false) adds two-LSB peak-to-peak TPDF noise before quantising, with seed (named integer) the RNG seed it uses. | x Veca length-N Vec, the quantised signallsb Numa Num, (vmax - vmin) / 2^bitsclipped Numa Num, how many samples fell outside the rangesnr_ideal Numa Num, dBvmin Numa Num, the low end of the range actually usedvmax Numa Num, the high endbits Numa Num, the word length actually used | Returns a Record with fields x (a length-N Vec, the quantised signal), lsb (a Num, (vmax - vmin) / 2^bits), clipped (a Num, how many samples fell outside the range), snr_ideal (a Num, dB), vmin (a Num, the low end of the range actually used), vmax (a Num, the high end) and bits (a Num, the word length actually used). |
Examples
From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.
t = (0 to 4095) / 10000
v = 1.2 * sin(2 * pi * 101 * t) + 2.048
c = adc(v, bits = 12, vmin = 0, vmax = 4.096)
print("LSB {c.lsb * 1000:.3f} mV, clipped {c.clipped}, ideal SNR {c.snr_ideal:.1f} dB")
LSB 1.000 mV, clipped 0, ideal SNR 74.0 dB
from noise
How it works
── noise, interference, distortion ───────────────────────── add_noise(x, "gaussian", snr = 3) — noise specified the way a datasheet, a standard and a reviewer all specify it. An amplitude is not a statement about a measurement, because it depends entirely on how big the signal is; an SNR is. Pass amplitude= instead when a raw figure is what you were actually given. Works on a vector and on an image alike: every kind here is per-sample, so one function covers 1-D and 2-D rather than two that drift apart. adc(x, bits = 12, vmin = -1, vmax = 1, dither = false) — quantise the way an instrument does: a REFERENCE RANGE and a RESOLUTION, not a step size. add_noise(x, "quantize", ...) takes a raw step, which is the mathematician's parameter. A converter has a range, and the difference is not cosmetic: outside it the signal CLIPS, and a step-based model cannot express that at all -- it will happily quantise a signal ten times the converter's range and report no problem. Returns a record rather than a bare signal, because .clipped is not a detail: a converter that clips has stopped measuring, and a script that never looks at that number will report a flat-topped waveform as data.
From the note above this builtin in the interpreter, where the reasoning was written down as it was built.