Skip to content

Commit 4319383

Browse files
author
emezzzzz
committed
readme: rewrite with resonant-circuit philosophy, full feature docs, and Daphne Oram epigraph
1 parent e2f05bf commit 4319383

1 file changed

Lines changed: 268 additions & 13 deletions

File tree

README.md

Lines changed: 268 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
11
# ORAM
22

3-
ORAM is an alpha local-first sound workstation for recording, looping, sampling,
4-
listening, and generating sound material.
3+
> "We seem to have tuned circuits within us"
4+
> — Daphne Oram, *An Individual Note of Music, Sound and Electronics*
55
6-
It started as a speech-operated terminal looper for synthetic sound studies. The
7-
current app has several surfaces around the same core idea:
6+
ORAM is a local-first sound workstation for recording, looping, sampling,
7+
listening, and generating sound material. It is built from the idea that sound
8+
is never at rest.
9+
10+
Every recorded layer becomes a flowing circuit: a small river of frequencies,
11+
tensions, residues and resonances that can be listened to, transformed, summoned
12+
and returned. The user does not simply control the system. They tune with it.
13+
14+
```text
15+
record → resonate → listen → transform → generate → return
16+
```
17+
18+
Named after **Daphne Oram** — pioneer of electronic music, inventor of the
19+
Oramics machine, and composer who built instruments to hear what did not yet
20+
exist.
21+
22+
## What ORAM Is
23+
24+
ORAM started as a speech-operated terminal looper for synthetic sound studies.
25+
The current app has several surfaces around the same core idea:
826

927
- Python CLI/TUI instrument
1028
- localhost dashboard and daemon
@@ -15,8 +33,17 @@ ORAM is not a DAW replacement, not a chatbot, and not a hosted prompt-to-song
1533
service. It is a small instrument where local audio, structured commands, and
1634
optional BYOK providers become constrained audio actions.
1735

36+
Not stable objects, but flowing resonant states. Not notes, but unstable
37+
entities. Not fixed frequencies, but living circuits of relation.
38+
1839
```text
19-
recorder -> looper -> sampler -> engine router -> local archive
40+
layers = circuits
41+
loops = resonant fields
42+
prompts = tuning gestures
43+
generation = summoning
44+
analysis = listening back
45+
effects = tension-shaping
46+
archive = trace of a state
2047
```
2148

2249
## Alpha Status
@@ -58,19 +85,182 @@ Current known alpha gaps:
5885
| VST3 | `plugins/oram-plugin` | Alpha build with JUCE module-info generation |
5986
| Standalone plugin app | `plugins/oram-plugin` | Alpha debug/release build |
6087

88+
## Core Flow
89+
90+
The performer records sound. The sound loops. The performer speaks or types.
91+
The agent listens to the speech, parses intent, and translates it into a
92+
constrained audio action. The sound changes. The performer listens again. The
93+
process repeats as a cycle of recording, transformation, and listening.
94+
95+
ORAM does not only generate sound. It listens for states of tension. Every loop
96+
is treated as a resonant body: unstable, mutable, recursive, alive. The user is
97+
not outside the circuit. The listener, the microphone, the machine, the model,
98+
and the sound form one tuned system.
99+
100+
```text
101+
recorder → looper → sampler → engine router → local archive
102+
```
103+
61104
## What It Does
62105

63-
- Records host or microphone audio into four layers.
106+
- Records host or microphone audio into layered circuits (up to four layers).
64107
- Loops, overdubs, mutes, solos, clears, pans, and volumes layers.
65108
- Parses typed or spoken commands into structured ORAM actions.
66-
- Applies offline DSP such as reverse, pitch, filter, reverb, granular, trim,
67-
fades, and spatial transforms.
68-
- Generates local mock sound by default.
69-
- Optionally routes generation to BYOK providers such as ElevenLabs and
70-
Stability AI.
109+
- Applies offline DSP tension-shaping: reverse, pitch, speed, filter, reverb,
110+
chorus, delay, flanger, phaser, distortion, bitcrush, stutter, granular,
111+
normalize, trim, fades, and spatial transforms.
112+
- Listens back — spectral analysis of pitch, BPM, key, harmonics, and frequency
113+
character through local FFT, LLM-based interpretation, or hybrid routes.
114+
- Generates sound through Local Mock by default, or summons textures through
115+
BYOK providers (ElevenLabs, Stability AI, fal Stable Audio).
71116
- Writes generated sounds into `~/Music/ORAM Library`.
72-
- Archives sessions with mix/stem WAVs, command logs, metadata, waveform text,
73-
and listening reports.
117+
- Archives sessions as traces of a state: mix/stem WAVs, command logs, metadata,
118+
waveform text, and listening reports.
119+
120+
### DSP Effects (Tension-Shaping)
121+
122+
| Effect | Description |
123+
| --- | --- |
124+
| `reverse` | full buffer reverse |
125+
| `pitch` | pitch shifting |
126+
| `speed` | time-stretch / speed ratio |
127+
| `filter` | lowpass, highpass, bandpass with frequency and Q |
128+
| `reverb` | convolution / algorithmic reverb |
129+
| `chorus` | chorus modulation |
130+
| `delay` | delay with feedback |
131+
| `flanger` | flanger |
132+
| `phaser` | phaser |
133+
| `distortion` | distortion / saturation |
134+
| `bitcrush` | bit reduction / sample rate reduction |
135+
| `stutter` | stutter / glitch buffer repeat |
136+
| `granular` | granular synthesis / processing |
137+
| `normalize` | loudness normalization |
138+
| `trim` | silence trimming, region selection |
139+
| `fade` | fade in / out curves |
140+
| `spatial` | spatial positioning: near, far, wide |
141+
142+
### Listening (Analysis)
143+
144+
ORAM treats listening as an active circuit, not passive reception. The body is
145+
also a resonator, a filter, a modulation system — a circuit that becomes
146+
activated by external vibrations.
147+
148+
Three listening routes:
149+
150+
| Route | Engine | Description |
151+
| --- | --- | --- |
152+
| `spectral` | local FFT | frequency content, waveform statistics, amplitude dynamics |
153+
| `llm` | BYOK provider | spectral data sent to an LLM for natural language interpretation |
154+
| `hybrid` | both | combines spectral and LLM analysis into a unified listening report |
155+
156+
Listening produces `listening_report.md` files with layer-by-layer analysis,
157+
frequency content, amplitude/dynamics statistics, waveform visualization, and
158+
optional natural language interpretation.
159+
160+
### Generation (Summoning)
161+
162+
Generation is always non-vocal — ORAM produces sound textures, effects, and
163+
music, never speech. Available engines:
164+
165+
| Engine | Type | Description |
166+
| --- | --- | --- |
167+
| `mock` | local | test tones, noise, or silence for development |
168+
| `elevenlabs` | BYOK | sound generation via ElevenLabs API |
169+
| `stability` | BYOK | audio generation via Stability AI API |
170+
| `fal` | BYOK | Stable Audio generation via fal |
171+
172+
Prompt types: `generate [prompt]`, `generate bed [prompt]`,
173+
`generate texture [prompt]`, `generate hit [prompt]`, `regenerate`.
174+
175+
### Session Archive (Trace of a State)
176+
177+
Each session archives as a complete trace:
178+
179+
```text
180+
session_name/
181+
├── session.json # metadata, timestamps, engine config
182+
├── commands.log # chronological command log
183+
├── mix.wav # stereo mixdown
184+
├── stems/
185+
│ ├── layer_1.wav
186+
│ ├── layer_2.wav
187+
│ ├── layer_3.wav
188+
│ └── layer_4.wav
189+
├── generated/ # generated audio files
190+
├── listening_report.md # analysis report
191+
└── waveform.txt # ASCII waveform visualization
192+
```
193+
194+
## Command Grammar
195+
196+
All interaction flows through structured commands — tuning gestures that resolve
197+
to bounded audio actions. Poetic language is accepted as input but must resolve
198+
to validated operations.
199+
200+
### Recording and Transport
201+
202+
```text
203+
record [layer N] # capture into layer
204+
overdub [layer N] # layer new audio over existing
205+
stop # stop recording / transport
206+
play / pause # transport controls
207+
arm / disarm # arm layer for recording
208+
```
209+
210+
### Layer Control
211+
212+
```text
213+
mute layer N # mute a circuit
214+
solo layer N # isolate a circuit
215+
clear layer N # erase layer audio
216+
set layer N volume 0.8 # set amplitude
217+
set layer N pan -0.5 # set stereo position
218+
```
219+
220+
### Effects (Tension-Shaping)
221+
222+
```text
223+
reverse layer N # reverse audio buffer
224+
set speed N ratio # time-stretch / speed
225+
filter layer N lowpass 800 # filter with frequency
226+
reverb layer N # reverb wash
227+
chorus / delay / flanger / phaser
228+
distortion / bitcrush # saturation / reduction
229+
stutter / granular # glitch / granular synthesis
230+
trim / fade in / fade out
231+
normalize
232+
spatial:far / spatial:near / spatial:wide
233+
```
234+
235+
### Generation (Summoning)
236+
237+
```text
238+
generate [prompt] # summon a texture
239+
generate bed [prompt] # summon a bed layer
240+
generate texture [prompt] # summon a texture
241+
generate hit [prompt] # summon a percussive hit
242+
regenerate # re-summon with last prompt
243+
```
244+
245+
### Listening (Listening Back)
246+
247+
```text
248+
listen # analyze current state
249+
listen layer N # listen to a specific circuit
250+
listen mix # listen to the full mix
251+
describe # describe what's sounding
252+
listen --route hybrid|spectral|llm
253+
```
254+
255+
### Session and System
256+
257+
```text
258+
save / export / archive # persist the trace
259+
name [session_name] # name the session
260+
load session [name] # recall a previous state
261+
credentials set|status|test [provider]
262+
mode [mode_name] / status / help / quit
263+
```
74264

75265
## Local-First Model
76266

@@ -148,13 +338,50 @@ tab cycle mode
148338
q quit
149339
```
150340

341+
## Dashboard Controls
342+
343+
The browser dashboard (click the `oram` title to open the About modal) provides
344+
a visual control surface with:
345+
346+
```text
347+
⏺ record from mic into selected layer
348+
⊕ overdub onto selected layer
349+
fx open DSP transforms (reverse, granulate, reverb…)
350+
✦ summon — listen to what's sounding and generate a new layer
351+
◉ export mix
352+
⊘ hard-silence capture/layers/pending output
353+
+ add layer
354+
```
355+
356+
Layer corners: top-left select/mute (right-click: solo), top-right export,
357+
bottom-left generate, bottom-right clear. Waveform drag sets loop region.
358+
Volume strip supports drag, scroll, double-click for unity.
359+
360+
Keyboard shortcuts in the dashboard:
361+
362+
```text
363+
1-4 select layer
364+
r record
365+
o overdub
366+
k kill
367+
g generate
368+
l listen
369+
m mute
370+
u unmute all
371+
⌘K command palette
372+
/ focus prompt
373+
esc close
374+
```
375+
151376
## macOS App
152377

153378
The native app in `apps/macos` is a SwiftUI shell around the local Python ORAM
154379
daemon. It launches or discovers `oram daemon`, stores provider keys in macOS
155380
Keychain, controls recording/generation/listening/library workflows, and writes
156381
generated sounds to the ORAM Library.
157382

383+
Views: Record, Generate, Listen, Library, Settings, About.
384+
158385
Build and run locally:
159386

160387
```bash
@@ -320,6 +547,10 @@ Privacy notes: [docs/security/local-first-privacy.md](docs/security/local-first-
320547

321548
## Architecture
322549

550+
```text
551+
record → resonate → listen → transform → generate → return
552+
```
553+
323554
Core architecture:
324555

325556
- [architecture.md](architecture.md)
@@ -334,6 +565,30 @@ Session archive format:
334565

335566
- [session_format.md](session_format.md)
336567

568+
Design principles:
569+
570+
- [concept.md](concept.md)
571+
572+
## Design Principles
573+
574+
**Constrained vocabulary**: commands map to bounded actions. Poetic language is
575+
accepted as input but must resolve to structured, validated operations.
576+
577+
**Offline transforms**: expensive DSP happens outside the realtime audio
578+
callback. The callback only does bounded, predictable work.
579+
580+
**Graceful degradation**: if STT fails, keyboard controls remain. If the LLM
581+
is unavailable, the deterministic parser handles commands. If generation fails,
582+
existing loops continue.
583+
584+
**Minimal identity**: the interface is monochrome-first, lowercase, austere.
585+
The complexity lives inside the loop, not in the chrome.
586+
587+
**Sound as material**: ORAM treats sound not as notation or signal, but as
588+
a changing field of tensions. Not stable objects, but flowing resonant states.
589+
Not notes, but unstable entities. Not fixed frequencies, but living circuits
590+
of relation.
591+
337592
## Development Checks
338593

339594
```bash

0 commit comments

Comments
 (0)