Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 72 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,84 @@
# SIGINTTool

A browser-based signal sketchpad: draw a waveform, see its mathematical function, and hear the result. Shape sounds with drawn pitch and volume envelopes, and distinguish each oscillator by its own consistent color.
Draw a signal. See its function. Hear it.

**Project status:** Product and technical planning. The application described below is not implemented yet.
SIGINTTool is a browser signal sketchpad with colored oscillators, drawn pitch and
volume envelopes, a persistent soundboard, and audio-clip modulation. Processing
and storage stay on your device. No account or server upload is required.

## Project documents
## Run it

- [Product requirements](docs/PRD.md)
- [Technical design](docs/TECHNICAL_DESIGN.md)
- [Implementation plan and issue dependencies](docs/IMPLEMENTATION_PLAN.md)
- [Delivery tracker #1](https://github.com/CurtisTechSolutions/SIGINTTool/issues/1)
Use Node.js 22, then:

~~~sh
npm ci
npm run dev
~~~

Open **http://localhost:4173**. Click **Play** to enable browser audio.

~~~sh
npm run check
npm test
npm run build
~~~

The build is a static site in **dist/**. Serve that directory from localhost or
HTTPS; opening index.html as a file will not provide the worker/audio environment.
GitHub Actions also saves a static-site artifact for each successful build.

## What you can do

## Planned first release
- Draw with pencil, line, eraser, presets, snapping, zoom, numeric controls, and undo.
- Combine up to four named oscillators with persistent colors, phase, mute and solo.
- Draw pitch and volume independently, or create a finite amplitude timeline.
- Inspect sine fits, Fourier coefficients/errors, model overlays, output and spectrum.
- Save named soundboard pads with independent audio and editable snapshots.
- Import WAV/MP3, trim an excerpt, choose stereo conversion, and use it or a frozen
saved clip for volume-follow, ring, or pitch/varispeed modulation.
- Export mono WAV, source/modulated/rendered CSV, full coefficient JSON, and complete
standalone JavaScript/Python functions.
- Autosave locally; download JSON projects or self-contained asset-bearing ZIP bundles.

- Paint-like waveform editing, numeric controls, presets, and undo/redo.
- Periodic oscillators and direct finite-duration signals.
- Drawn pitch and volume envelopes with phase-continuous synthesis.
- Up to four independently editable oscillators with persistent colors, labels, mute/solo, and mono mixing.
- Readable sine fits, Fourier approximations with measured error, and general numerical functions for complex shapes.
- Browser audio, signal/spectrum inspection, WAV and data/function exports, and local project files.
- A named soundboard for saving sounds, replaying them from buttons, and reopening editable copies.
- Local WAV/MP3 imports or saved clips as modulation sources: volume follow, ring modulation, and pitch/varispeed.
- Self-contained project bundles that preserve the audio assets needed to edit and reproduce saved sounds.
Waveform horizontal position is **time** and vertical position is **signed amplitude**.
A spectrum uses **frequency** horizontally. Pitch and volume are separate time lanes.
Complex drawings have complete numerical functions; a compact sine expression is
explicitly an approximation.

Simple shapes may have compact formulas. Complex drawings retain complete numerical representations; the product will identify approximation and audio-processing differences explicitly.
## Limits and behavior

Finite sounds and retained imported clips are 1 ms–10 seconds. Imports accept
mono/stereo WAV or MP3 up to 20 MiB and 60 seconds. Projects support eight audio assets
and 20,000 editable points. Export rates are 44.1 and 48 kHz. One modulation route is
active at a time; save its result as a clip to build another stage.

Saved clips contain audio before monitor volume. Playback and WAV export apply monitor
volume once. Modulation sources are immutable copies: editing or removing their original
soundboard pad does not change dependent sounds. Browser storage can be cleared or run
out of space; download project backups for portability.

Function exports include source evaluators and complete numerical tables for modulated
and rendered output. These tables reproduce the saved settings; editable changes to
effects require the project bundle and a new render. Clip varispeed changes timing as
well as pitch.

## Documentation and validation

- [User guide](docs/USER_GUIDE.md)
- [Implementation decisions](docs/ENGINEERING_DECISIONS.md)
- [Validation and measured limits](docs/VALIDATION.md)
- [Product requirements](docs/PRD.md)
- [Technical design](docs/TECHNICAL_DESIGN.md)
- [Implementation plan](docs/IMPLEMENTATION_PLAN.md)
- [Delivery tracker](https://github.com/CurtisTechSolutions/SIGINTTool/issues/1)
- [Contributing and test setup](CONTRIBUTING.md)

Implementation setup and build commands will be added as part of [foundation issue #2](https://github.com/CurtisTechSolutions/SIGINTTool/issues/2).
The app uses native browser modules, Canvas, Web Workers, Web Audio, and IndexedDB.
Its local MP3 decoder is pinned and includes [third-party notices](src/vendor/README.md).
CI covers numerical tests, generated JS/Python, Chromium/Firefox/WebKit workflows, and
real Safari on macOS. See the validation report for measured scope and remaining human
acceptance checks.

## License

See [LICENSE](LICENSE).
See [LICENSE](LICENSE). Vendored components retain their own licenses in src/vendor/.
67 changes: 64 additions & 3 deletions docs/ENGINEERING_DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

## Browser-native modules

The application uses standard JavaScript modules, Canvas 2D, Web Workers, Web Audio, and IndexedDB. The planning documents recommended React/TypeScript as a starting option. This implementation chooses native modules because the workspace is primarily a canvas and a small set of controls, pure numerical code can run unchanged under Node, and the app can ship without third-party runtime code or a bundler. Modules separate the project contract, signal math, renderer, transport, storage, exports, and interface.
The application uses standard JavaScript modules, Canvas 2D, Web Workers, Web Audio, and IndexedDB. The planning documents recommended React/TypeScript as a starting option. This implementation chooses native modules because the workspace is primarily a canvas and a small set of controls, pure numerical code can run unchanged under Node, and the interface can ship without a UI framework or a bundler. A pinned, separately licensed WebAssembly decoder provides local MP3 support. Modules separate the project contract, signal math, renderer, transport, storage, exports, and interface.

Node 22 is the pinned development major. There are no application dependencies; the lockfile records this deliberately. Playwright 1.63.0 is pinned for CI browser checks. Its Chromium, Firefox, and WebKit tests do not substitute for actual Safari or a human usability study.
Node 22 is the pinned development major. There are no npm runtime dependencies; the MP3 distribution is vendored with notices and pinned source references. Playwright 1.63.0 is pinned for CI browser checks. Its Chromium, Firefox, and WebKit tests do not substitute for actual Safari or a human usability study.

## Build and release

`npm ci`, `npm run check`, `npm test`, and `npm run build` validate and produce a static `dist/` directory. `npm run dev` serves the workspace at localhost:4173. CI runs on every PR and on main, and retains the static build artifact. The inherited Docker publishing workflow was removed because the application has no container deployment requirement. Release preparation is an explicit manual workflow; implementation merges do not publish releases or containers.

The initial foundation includes versioned bounds/validation and independent model fixtures. DSP quality and maximum-resource evidence are added with the renderer; foundation issue #2 stays open until that evidence exists.
The foundation includes versioned bounds/validation, independent numerical fixtures, a custom radix-2 FFT, measured filter response, and maximum-workload profiling. See VALIDATION.md for evidence and remaining release acceptance checks.


## Bounded audio decoding
Expand All @@ -23,3 +23,64 @@ its pinned sources and licenses are included in src/vendor/README.md.
Supported WAV inputs are integer PCM 8/16/24/32-bit or IEEE float32. Extensible/compressed
WAV, free-format MP3, changing MP3 format midstream, and unrecognized trailing metadata
are rejected with a clear error. These limits are deliberate first-release boundaries.


## Rendering and mathematical exports
The renderer is shared by preview, soundboard caching and exports. It runs in workers
at four times the destination sample rate, reconstructs clip samples with a 64-tap
windowed-sinc kernel, and applies a 257-tap Blackman low-pass before decimation.
The tested filter target is less than 0.5 dB loss at 0.4 × destination sample rate and
more than 60 dB rejection at 0.5 × destination sample rate. This is a measured filter
contract, not a promise that every arbitrarily discontinuous drawing is artifact-free.

Periodic carriers use bandwidth-limited harmonic tables. Drawn log-linear pitch uses
exact segment integrals; the regular render grid advances through geometric increments,
with an analytic reset every 1,024 samples or at a knot to bound floating-point drift.
Clip-driven pitch/readhead changes use trapezoidal integration. Carrier DC is removed
before drawn gain; generated post-modulation DC is reported, not subtracted afterward.
Headroom is one global attenuation over the completed finite clip. Monitor gain is
outside the cached render and applied once at playback or monitored export.

Finite clip edges use up to 5 ms fades, including loop restarts. This preserves duration
but can make a short dip at a repeated seam. Modulator availability has bounded ramps;
clip looping uses periodic sinc reconstruction, with no implied time stretching.
Band-limited table selection can change high-harmonic content during a pitch sweep.

Source function exports contain full source/model tables, coefficient arrays, envelope
knots and phase-prefix segments. They retain source DC and precede clip modulation.
Modulated and rendered function exports carry complete numerical result tables. This
is an intentional, stateless definition of the fixed result: arbitrary-time queries
interpolate those tables and need no hidden follower/readhead state. They do not
re-synthesize modified effect settings. The separate project bundle preserves all
PCM assets and editable routing for that purpose.

## Runtime and persistence boundaries
Worker cancellation terminates the current computation. Playback uses generation
checks and one shared AudioContext; a stopped or obsolete job cannot start audio later.
Saved clips retain pre-monitor PCM and an independent project snapshot atomically.
Immutable content-derived audio IDs preserve dependencies after source-pad updates
or removal. The in-memory prepared-pad cache is bounded to 8 MiB; library listing reads
metadata. Current-project buffers are pruned when their references change.

Browser storage is local to its origin/profile and can be cleared or exhaust quota.
Failed transactions preserve the previous saved state. Removed sounds retain recovery
data for Undo; this release favors preserving referenced audio over automatic garbage
collection, so repeated updates/removals can leave unused records until browser data
is cleared after backing up projects.

Archive format version 1 uses standard ZIP STORE entries only. Import validates
directory/header consistency, byte/entry limits, paths, CRCs, PCM hashes, versions,
finite sample bounds and complete project references before changing state.

## Automation and release scope
Each implementation slice was a separate reviewed diff/PR, merged only after its
required CI jobs passed. The repository does not enable GitHub's automatic-merge flag;
the authorized merge operation was performed directly after verifying each PR head.
No production deployment, package publication, or scheduled background task is implied.

Real Safari tests use Apple's bundled safaridriver on a macOS runner. This is separate
from Playwright WebKit. [Apple's setup](https://developer.apple.com/documentation/safari-developer-tools/macos-enabling-webdriver)
documents enabling WebDriver for this test environment. Human listening, screen-reader
sessions and the five-person formative study remain explicit release acceptance work.

Native oscillators and AudioParam automation were evaluated as a simpler path, but a shared finite numerical renderer was selected to make arbitrary drawings, clip varispeed, exports and frozen soundboard results reproducible through one implementation. Web Audio schedules the completed buffer; a real-time AudioWorklet and continuously connected modulation graph are unnecessary for this finite first release.
2 changes: 2 additions & 0 deletions docs/IMPLEMENTATION_PLAN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# SIGINTTool implementation plan

> Implementation is now available on `main`. These documents retain the agreed requirements and original design recommendations. Actual choices, supported boundaries and evidence are in [ENGINEERING_DECISIONS.md](ENGINEERING_DECISIONS.md) and [VALIDATION.md](VALIDATION.md); use [USER_GUIDE.md](USER_GUIDE.md) to run the app.

**Status:** Proposed first-release backlog; implementation has not started in this planning change.
**Date:** 2026-09-30
**Tracking issue:** [#1 — Product delivery plan](https://github.com/CurtisTechSolutions/SIGINTTool/issues/1)
Expand Down
2 changes: 2 additions & 0 deletions docs/PRD.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# SIGINTTool — Draw a signal, see its function, hear its sound

> Implementation is now available on `main`. These documents retain the agreed requirements and original design recommendations. Actual choices, supported boundaries and evidence are in [ENGINEERING_DECISIONS.md](ENGINEERING_DECISIONS.md) and [VALIDATION.md](VALIDATION.md); use [USER_GUIDE.md](USER_GUIDE.md) to run the app.

**Status:** Proposed product requirements; no application has been implemented.
**Date:** 2026-09-30
**Repository:** [CurtisTechSolutions/SIGINTTool](https://github.com/CurtisTechSolutions/SIGINTTool)
Expand Down
2 changes: 2 additions & 0 deletions docs/TECHNICAL_DESIGN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# SIGINTTool technical design

> Implementation is now available on `main`. These documents retain the agreed requirements and original design recommendations. Actual choices, supported boundaries and evidence are in [ENGINEERING_DECISIONS.md](ENGINEERING_DECISIONS.md) and [VALIDATION.md](VALIDATION.md); use [USER_GUIDE.md](USER_GUIDE.md) to run the app.

**Status:** Proposed architecture for discussion, not implemented or benchmarked.
**Date:** 2026-09-30
**Product contract:** [PRD](PRD.md)
Expand Down
Loading
Loading