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:

  1. 7 tracks
  2. 5 tracks
  3. 6 tracks
  4. 6 tracks
  5. 2 tracks
  6. 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

_images/70a42910b30ec304218e70994bb6430cb4960f226fe1e30e178ad8e785c8aff7.svg

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.