Skip to content

feat(live)!: assemble a music's BGM and the live sounds as products - #74

Merged
nichinichisou0609 merged 4 commits into
redesign/depotfrom
redesign/live-audio
Oct 15, 2026
Merged

nichinichisou0609 merged 4 commits into
redesign/depotfrom
redesign/live-audio

Conversation

@nichinichisou0609

Copy link
Copy Markdown
Collaborator

What a live plays besides its chart becomes two products, each shared by every live that plays it: the BGM of a music and the sounds of an option set.

Products

  • live.music: a music id → music.json (the BGM sound: cue structure, layers) and each BGM layer in a web format; manifest music/<id>.json. Parameter format: aac (default; each layer records encoderDelay), opus, vorbis, mp3, or flac (the decoded file as stored). The atom audio.encode names the ffmpeg build.
  • live.sounds: default or NoteSePatternId=<ids> → sounds.json (note and live sounds, category volumes, the ACF's buses, categories and REACT, note and live sound tables, timings) and each sound's decoded FLAC; manifest sounds/<subject>.json. Its roots include the SoundVolumeSettings and AppConfigDefaultData MonoBehaviours of the APK's built-in files; it reads assets/Cri/Sound/Sirius.acf of the APK.

Neither keeps objects.

Pipeline

  • Built-in selectors: the address table (nnnotes.addresses/3) has a builtins table, objects of the APK's built-in files by class (GraphicsSettings) or by a MonoBehaviour's script class (MonoBehaviour:<class>). ProductStage.builtins names them as roots, and the roots fact carries them.

  • Cue sheets of a product: ProductStage.cue_sheets gives catalog keys whose ACB the product reads. The ACB is held in a bundle (the acb file of an object of the key) or is a raw file of the catalog that cri.audio decoded. Each one adds:

    • inputs acb:<key>;
    • the sheets input (the files cri.audio made of each ACB);
    • a dependency on the cri.audio tasks.

    A product file may be content the depot already holds, recorded without copying its bytes.

  • APK files: ProductStage.APK names files of the APK a stage reads; the fact apk gives them as inputs apk:<path>.

  • ProductStage.select(keys, env) takes the planning environment, so a product can select its subjects through master data.

  • content.liveaudio is now functions over master rows, ACB and ACF bytes, and the settings documents; the live directory export uses them too.

  • cri.audio/cri.movie record the first bytes of a raw file in the depot, so a later plan can classify a raw file whose download was trimmed.

  • The web audio formats, the bit-exact web encode and mp4_priming are in nnnotes.formats.encoders.

Breaking changes

  • link.addresses is at version 3 (nnnotes.addresses/3); the roots fact has builtins.
  • ProductStage.select takes env.
  • liveaudio.note_se_settings, acf_info and category_volumes take master rows, ACF bytes and the settings documents.

Tests

  • Synthetic ACBs of the live sheets' shape and an ACF (tests/helpers/cri.py, whose @UTF writer test_voices now shares) cover:
    • both products' documents and files: the decoded FLAC kept as stored, the AAC encoder delay, an incompatible encoder, an undecoded sheet, the settings objects;
    • subjects, keys, manifests and selection.
  • Planning tests:
    • cue sheets held in a bundle and as a raw file, through cri.audio;
    • a sheet the request does not hold;
    • built-in selectors in the address table and as request roots;
    • the recorded first bytes of a raw file;
    • planning without UnityPy.

nichinichisou0609 and others added 4 commits October 15, 2026 14:52
The address table (nnnotes.addresses/3) gains a `builtins` table: the
objects of the APK's built-in files by class ("GraphicsSettings") and
MonoBehaviours by their script's class ("MonoBehaviour:<class>"),
without MonoScripts and with a hierarchy listed by its root only.
AddressIndex.builtin(selector) reads it.

A product stage can name these selectors as roots
(ProductStage.builtins); the request fact "roots" carries them, so the
units of settings assets that the game reads without a catalog key or a
Resources.Load path are exported with the products that use them.

BREAKING CHANGE: link.addresses is at version 3 and writes
nnnotes.addresses/3; the roots fact has a "builtins" list.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cri.audio and cri.movie tell raw files apart by their first bytes (ACB,
AWB, USM). Those bytes were kept in memory only, so after the depot
trimmed its downloads a later plan could not classify a raw file whose
identity it already knew and stopped with the file pending.

The first bytes are now recorded in the depot per content
("magic:<sha256>"); a raw file without the record is read through its
locators, fetching it through the catalog when no local copy is left.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The web audio formats (WEB_AUDIO, the default format), the bit-exact
encode into one of them (web_encode) and the MP4 encoder delay reader
(mp4_priming) are in nnnotes.formats.encoders, below the pipeline, so
product stages encode audio the same way the site does. The site and
its command read them from there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two product stages make what a live plays besides its chart, each
shared by every live that plays it:

- live.music (subject: a music id) writes music.json, the BGM sound
  with its cue structure, and each layer of the BGM in a web format
  (parameter `format`, default AAC with its encoder delay; `flac`
  keeps the decoded file). Its manifest is music/<id>.json.
- live.sounds (subject: `default` or `NoteSePatternId=<ids>`) writes
  sounds.json, the note and live sounds with the category volumes, the
  ACF's buses, categories and REACT, the note and live sound tables and
  the timings, and each sound's decoded FLAC. Its roots include the
  sound settings of the APK's built-in files; it reads the ACF of the
  APK. Its manifest is sounds/<subject>.json.

Product stages gain what these need: cue sheets (the ACB a catalog key
loads, held in a bundle or a raw file, with the files cri.audio made of
it as inputs and the cri.audio tasks as dependencies), files of the APK
(the fact "apk", inputs "apk:<path>"), product files that are content
the depot already holds, and `select(keys, env)` with the planning
facts. content.liveaudio is a set of functions over master rows, ACB
and ACF bytes and the settings' documents, which the live directory
export uses as well.

BREAKING CHANGE: ProductStage.select takes the planning environment;
liveaudio.note_se_settings, acf_info and category_volumes take master
rows, ACF bytes and the settings' documents.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nichinichisou0609
nichinichisou0609 merged commit 46f21b5 into redesign/depot Oct 15, 2026
8 checks passed
@nichinichisou0609
nichinichisou0609 deleted the redesign/live-audio branch October 15, 2026 07:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant