Files
MindMachine/ARCHITECTURE.md

277 lines
6.5 KiB
Markdown

# MindMachine - Architecture
## 1. Overview
MindMachine should be implemented as a modular mobile application with clearly separated concerns. The core architecture should isolate session timing, audio generation, visual rendering, preset management, and safety/setup flows so the app remains maintainable and easy to evolve.
For the first implementation, a native Android architecture is recommended.
---
## 2. Architecture Goals
The system should:
- remain readable and maintainable,
- separate user interface from stimulation logic,
- support deterministic session behavior,
- allow new presets and stimulation modes to be added safely,
- make safety-critical logic explicit and testable.
---
## 3. High-Level Components
## 3.1 Presentation layer
Responsible for:
- onboarding UI,
- safety warnings,
- preset selection,
- session setup,
- active session controls,
- completion screens.
Suggested responsibilities:
- render UI state,
- receive user input,
- dispatch commands to application logic,
- avoid direct low-level audio or rendering logic.
## 3.2 Session orchestration layer
Responsible for:
- starting, pausing, resuming, and stopping sessions,
- tracking elapsed and remaining time,
- coordinating visual and audio parameters,
- responding to interruptions,
- exposing session state to the UI.
This is the central control layer for the app.
## 3.3 Audio engine
Responsible for:
- generating stereo tones,
- applying left/right frequency differences,
- keeping playback stable,
- handling headphone/output changes,
- exposing playback status and error states.
## 3.4 Visual engine
Responsible for:
- rendering full-screen stimulation patterns,
- applying brightness/pulse/flash timing,
- switching between pattern modes,
- syncing to session state.
## 3.5 Preset and configuration layer
Responsible for:
- built-in presets,
- user-created session settings,
- loading/saving preferences,
- validating parameter ranges.
## 3.6 Safety layer
Responsible for:
- first-run acknowledgment state,
- pre-session warnings,
- session guardrails,
- interruption safety behavior,
- validation of risky configurations.
---
## 4. Suggested Package / Module Structure
```text
MindMachine/
├── app/
│ ├── ui/
│ │ ├── onboarding/
│ │ ├── home/
│ │ ├── session/
│ │ ├── settings/
│ │ └── completion/
│ ├── domain/
│ │ ├── session/
│ │ ├── preset/
│ │ ├── safety/
│ │ └── audio/
│ ├── data/
│ │ ├── presets/
│ │ ├── settings/
│ │ └── storage/
│ ├── engine/
│ │ ├── audio/
│ │ ├── visual/
│ │ └── timing/
│ └── platform/
│ ├── audio/
│ ├── display/
│ └── power/
├── docs/
└── tests/
```
---
## 5. Core Domain Objects
Suggested core models:
- `SessionPreset`
- `SessionConfig`
- `SessionState`
- `AudioConfig`
- `VisualConfig`
- `SafetyAcknowledgmentState`
- `SessionTimerState`
Example concepts:
- preset name
- duration
- blink frequency
- visual pattern type
- carrier frequency left/right
- binaural beat difference
- brightness level recommendation
- pause/running/completed/stopped state
---
## 6. Runtime Flow
### Start flow
1. UI gathers selected preset/config
2. Session orchestrator validates settings
3. Safety layer checks acknowledgment state
4. Audio engine prepares playback
5. Visual engine prepares rendering
6. Session timer starts
7. Active session begins
### During session
1. Session timer emits progress
2. Audio engine maintains output
3. Visual engine renders active frame state
4. UI observes reduced session state
5. Interruptions/errors are routed back to orchestrator
### Stop flow
1. User or timer ends session
2. Session orchestrator issues stop commands
3. Audio engine halts playback
4. Visual engine returns to safe idle state
5. UI shows completion state
---
## 7. State Management
The app should use a unidirectional state model where practical:
- UI emits intents/actions
- orchestration/domain logic computes next state
- UI renders derived state
This keeps behavior easier to test and reason about.
---
## 8. Timing Strategy
Timing should not rely on the UI render loop alone.
Recommended approach:
- maintain a dedicated session timer/controller,
- compute session progress from monotonic time when possible,
- let visual and audio engines consume a stable timing source,
- avoid coupling timing precision to screen redraw alone.
---
## 9. Audio Strategy
The audio engine should:
- generate left/right channels independently,
- support continuous tone generation,
- maintain stable playback buffers,
- surface output-device changes immediately.
Preferred properties:
- low glitch risk,
- deterministic playback,
- clear lifecycle methods: prepare, start, pause, resume, stop, release.
---
## 10. Visual Strategy
The visual engine should:
- use a dedicated full-screen rendering surface,
- support simple pattern strategies,
- derive pattern state from current session time,
- allow future expansion to more complex patterns.
Pattern implementations should be strategy-based, for example:
- `FlashPatternRenderer`
- `PulsePatternRenderer`
- `AlternatingPatternRenderer`
---
## 11. Safety Architecture
Safety checks should exist in more than one place:
- onboarding acknowledgment,
- pre-session checks,
- runtime interruption handling,
- parameter validation.
Examples:
- block session start if warnings not acknowledged,
- warn if stereo output is unavailable,
- stop or pause on critical runtime state changes,
- constrain dangerous parameter combinations.
---
## 12. Persistence
Persist only what is needed for version 1:
- onboarding/safety acknowledgment,
- recent preset selection,
- user-created presets,
- basic settings.
Do not overcomplicate storage in version 1.
---
## 13. Testing Strategy
Test at multiple levels:
### Unit tests
- preset validation
- session timing calculations
- safety rule evaluation
- parameter transformation logic
### Integration tests
- session start/stop flow
- audio engine lifecycle behavior
- interruption handling
- persistence loading/saving
### UI tests
- onboarding flow
- preset selection flow
- active session controls
- completion flow
---
## 14. Key Design Principles
- Keep components small and explicit
- Keep safety logic centralized and testable
- Avoid hidden coupling between UI and engines
- Prefer predictable configuration over clever automation
- Build for extension, but do not overengineer version 1