Skip to content

Latest commit

 

History

History
53 lines (40 loc) · 2.52 KB

File metadata and controls

53 lines (40 loc) · 2.52 KB

Design notes

Some of the decisions behind sonoscript, and the trade-offs they carry.

Text as the interface

The whole project is built around the idea that an edit is easier to describe than to click through. "Delete from 4s to 4.8s" is unambiguous, diffable and scriptable in a way that dragging a selection is not. The instruction language is therefore the primary interface; the Python API is just the same operations without the parsing step.

The language is intentionally tiny — three verbs and a handful of modifiers. It is a domain language, not a general-purpose one: there are no variables, no loops, no arithmetic. If a script needs those, it is better generated from Python than expressed in the DSL.

Original-timeline coordinates

The single most important decision is that all edit coordinates refer to the original clip. The obvious alternative — apply each edit immediately, so later edits see the shifted timeline — was rejected because it makes scripts order-dependent in a way that surprises people: inserting two seconds at the start would silently move every later timestamp.

The cost is that overlapping edits cannot be resolved (there is no single timeline to place them on), so the editor rejects them. In practice edits rarely overlap, and a clear error is better than a silently wrong result.

Determinism and no assets

Every sound is synthesised from a seeded generator, so a script always produces byte-identical output. This is what makes the tests exact rather than tolerance-based, and it keeps the package tiny — there are no WAV assets to ship, license or load. The downside is that the palette sounds synthetic; the project is aimed at structured edits and evaluation, not at producing broadcast audio.

Equal-power crossfades

Butt-joining two segments almost always clicks, because the waveform jumps. A short crossfade removes the click, but a linear crossfade dips in perceived loudness through the middle (the two signals partially cancel). The equal-power (cosine/sine) curve keeps the summed power constant across the seam, which sounds even. Ten milliseconds is long enough to hide the click and short enough not to smear transients.

Why so few dependencies

NumPy and nothing else. WAV I/O goes through the standard-library wave module. This keeps installation trivial, the security surface small and the behaviour predictable across platforms — at the price of only supporting 16-bit PCM WAV. For a reference implementation whose point is clarity, that felt like the right side of the trade.