-
Notifications
You must be signed in to change notification settings - Fork 0
Recipes
Task-oriented walkthroughs. Commands assume pip install "ambiscape[iso,ml]".
ambiscape probe NIGHT/ # sanity: takes, clock, convention
ambiscape analyze NIGHT/ --notes "living room, window closed, HVAC on"
# read NIGHT/README.md, look at analysis/overview.png:
# - steady lanes = machines; find the on/off transitions
# - anglegram ridge = where the dominant source sits
ambiscape draft NIGHT/ # regimes + events + tag hints
# listen to the hinted moments, edit -> annotations.json
ambiscape taxonomy NIGHT/ # Schaeffer map + Schafer timeline
ambiscape iso NIGHT/ # loudness/sharpness/roughnessambiscape probe FOLDER/ # prints ambix|fuma per take (from zTRK tags)No tags? Compute an azimuth histogram: a distribution hugging 0°/180° across varied content means the horizontal decode is getting a vertical channel — wrong map.
import ambiscape as asc
sess = asc.open_session("FOLDER")
x, fs = asc.read_span(sess, t0=CLAP_TIME - 2, dur=6)
print(asc.decay_time(x[:, 0], fs)) # {band: (T60, dynamic_range_dB)}Trust bands with ≥ 30 dB dynamic range where T20/T30-style fits agree. Remember the field rule: 5 s of stillness around the clap.
Every analyze writes analysis/summary.json. Aggregate:
import json, pathlib, pandas as pd
rows = {p.parent.parent.name: json.load(open(p))
for p in pathlib.Path(".").glob("*/analysis/summary.json")}
print(pd.DataFrame(rows).T[["leq_dbfs", "dynamics_L10_L90",
"diffuseness_median", "azimuth_R"]])-
asc.pick_segments(F)or choose by ear; cut with ffmpeg (-c copykeeps the 4-channel stream bit-exact). -
ambiscape speechgate SEGMENTS/— every file must PASS. - Convert to FLAC (
ffmpeg -i seg.wav -c:a flac seg.flac) — lossless, half the size, keeps all channels. - Tag
ambisonic b-format ambix(Freesound detects 4-channel B-format and provides the binaural spatial player); one pack per location; coarse geotags for home locations; CC license chosen once for the series.
pip install "ambiscape[viz]"Extract a short excerpt (above), then use ambiviz's aem, anglegram, or
directogram on it directly — the excerpt is exactly the "loadable file"
ambiviz is built for.
ambiscape analyze SESSION/ # needed first (cached minspec)
ambiscape rhythm SESSION/ # sources, periods, phase, variation
# read analysis/rhythm.json; look at analysis/rhythm_overview.pngInterpreting rhythm.json:
- one entry per source: its partials, cycle period, phase clusters (strike positions within the cycle), azimuth;
-
cycle: per position — hit rate, timing SD, slow wander vs cycle-to-cycle jitter, lag-1 autocorrelation. Shared wander across positions = a common clock; independent scatter = free clapper/mechanism; -
crosstalk_suspects: phase clusters that coincide with another source's strikes. Verify withrhythm.rise_spectrum— the artifact's rise spectrum shows the other source's partials.
Worked example: the Haarlem Damiaatjes case study (Case Study Haarlem Damiaatjes).
Recorder clocks drift. Calibrate against any event of known wall-clock time captured in the recording — a scheduled bell, a radio time signal, a phone alarm:
// SESSION/calibration.json
{"clock_offset_s": 665.0,
"method": "town bells end 21:30:00 sharp; last strike at file t=1266 s"}Positive = the clock was slow. Applied on open_session, so re-running
analyze/taxonomy/iso re-labels every figure and report with
corrected time. (Delete analysis/features/*.npz first — cached features
store the uncorrected start.)