Particles¶
(Work-in-progress design document)
Introduction¶
Solar Flares Particles is an algorithmic music production tool. It is designed to leverage the features of the SunVox file format and DLL.
It can be used in an “online” mode for experimentation and live performance, or in an “offline” mode where a composition is rendered to WAV file(s).
It’s intended to be highly tolerant of latency. This enables trusted devices to share a common Particles session. Possible uses include remote live sessions between several musicians, or using a remote audio rendering service from a lower-powered device.
Particles does not have a full-fledged performance UI. Solar Sails is an app that offers a way to use Particles.
System architecture¶
Data structures¶
Module map¶
Participants can each allocate and deallocate modules.
The module map is a mapping between (participant, module-uuid)
pairs and actual module numbers.
Track blocks¶
Participants can allocate and deallocate “track blocks” of up to 16 tracks.
Particles maintains a bank of 512 tracks, via 32 patterns of 16 tracks each. It assigns blocks of them virtually to participants as needed.
Consider a scenario where track blocks are allocated in this order:
- 7 tracks
- 5 tracks
- 6 tracks
- 6 tracks
- 2 tracks
- 3 tracks
The tracks would be mapped to actual SunVox patterns and tracks in this way:
Pattern 1 |
Track 1 |
Block 1 |
Track 1 |
Track 2 |
Track 2 |
||
Track 3 |
Track 3 |
||
Track 4 |
Track 4 |
||
Track 5 |
Track 5 |
||
Track 6 |
Track 6 |
||
Track 7 |
Track 7 |
||
Track 8 |
Block 2 |
Track 1 |
|
Track 9 |
Track 2 |
||
Track 10 |
Track 3 |
||
Track 11 |
Track 4 |
||
Track 12 |
Track 5 |
||
Track 13 |
Block 5 |
Track 1 |
|
Track 14 |
Track 2 |
||
Track 15 |
(unused) |
||
Track 16 |
(unused) |
Pattern 2 |
Track 1 |
Block 3 |
Track 1 |
Track 2 |
Track 2 |
||
Track 3 |
Track 3 |
||
Track 4 |
Track 4 |
||
Track 5 |
Track 5 |
||
Track 6 |
Track 6 |
||
Track 7 |
Block 4 |
Track 1 |
|
Track 8 |
Track 2 |
||
Track 9 |
Track 3 |
||
Track 10 |
Track 4 |
||
Track 11 |
Track 5 |
||
Track 12 |
Track 6 |
||
Track 13 |
Block 6 |
Track 1 |
|
Track 14 |
Track 2 |
||
Track 15 |
Track 3 |
||
Track 16 |
(unused) |
Code log¶
This is a log of code that was successfully executed by a participant. It’s intended for storage and sharing, not for execution by other participants.
Each entry contains:
- source code
- participant ID
- creation time
Event¶
An event is comprised of:
- creation time
- participant ID
- participant local sequence
- row number
- event type
- event data
Event types:
- NOTE_CMD
- module create
- module delete
- module connect
- module disconnect
- row
- track block allocate
- track block release
(TODO: explain these in more detail)
NOTE_CMD events have coordinates (track block, track, row), and can be overwritten. See “row log” below for caveats.
Event log¶
This is an append-only log of all events generated by all participants.
Rows¶
This is a row of notes intended to be sent to a playback server. It is structured as a 32x16 array containing NOTE_CMDs for each track of each pattern.
During creation of a row, track blocks are mapped to actual patterns and tracks, and participant modules are mapped to actual modules.
Row log¶
This is an append-only log of rows to be sent to the Playback server.
Row map¶
This is a map of row numbers to rows. Rows can be re-rendered and overwritten, but this must occur before playback reaches a given row.
Processes¶
Participant¶
A participant maintains these data structures locally:
- track block map
- module map
- code log
- event log
- row log
- row map
May connect to other participants to share log entries.
May connect to a playback server to send rows, and receive feedback about played rows.
Playback server¶
Receives rows and events from a designated participant, and plays them using SunVox DLL.
Sends feedback about rows played to connected processes. Feedback includes accurate timing information.
Maintains an internal row map of upcoming rows to play, by directly writing them into the SunVox-managed pattern buffers.
Can play back through local audio, or provide a stream of 32-bit samples for streaming to network or disk.
Latency-tolerant performance mode¶
The transfer of event payloads and playback of audio are designed to be resistant to high-latency environments. Audio playback is designed to be tightly synchronized in real time between all participants.
Of course, once sound is played back for a particular row, there’s no going back. The trick is to only allow performance changes to occur at some point in the future.
Each participant periodically monitors the latency between itself and its peers, and also broadcasts that to peers. Each peer chooses the maximum latency recently found, plus an additional 25%, as an event cutoff point. The peer then actively avoids creating events prior to the cutoff point.
Participants working remotely will need to work within these limitations, but will be rewarded with the pleasure of a synchronized audio experience.