@maccesar/titools 5.2.0 → 5.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +69 -0
- package/README.md +80 -72
- package/agents/ti-pro.md +1 -1
- package/commands/ti-audit.md +2 -2
- package/docs/examples.md +91 -0
- package/docs/knowledge-index.md +57 -0
- package/lib/downloader.js +1 -1
- package/package.json +4 -2
- package/skills/purgetss/references/multi-density-images.md +1 -1
- package/skills/ti-admob-unified/SKILL.md +21 -7
- package/skills/ti-admob-unified/assets/example/app.js +229 -25
- package/skills/ti-admob-unified/assets/example/lib/ads.js +30 -2
- package/skills/ti-admob-unified/assets/example/library-usage.js +33 -1
- package/skills/ti-admob-unified/references/api-reference.md +39 -16
- package/skills/ti-admob-unified/references/banners.md +9 -9
- package/skills/ti-admob-unified/references/contributing.md +14 -9
- package/skills/ti-admob-unified/references/dependencies.md +31 -25
- package/skills/ti-admob-unified/references/fullscreen.md +43 -28
- package/skills/ti-admob-unified/references/game-monetization.md +138 -7
- package/skills/ti-admob-unified/references/getting-started.md +75 -31
- package/skills/ti-admob-unified/references/index.md +5 -2
- package/skills/ti-admob-unified/references/integration.md +8 -6
- package/skills/ti-admob-unified/references/library.md +41 -10
- package/skills/ti-admob-unified/references/mediation-parity.md +17 -0
- package/skills/ti-admob-unified/references/mediation.md +22 -9
- package/skills/ti-admob-unified/references/migration.md +11 -7
- package/skills/ti-admob-unified/references/module-changelog.md +41 -11
- package/skills/ti-admob-unified/references/privacy.md +35 -8
- package/skills/ti-admob-unified/references/production.md +67 -0
- package/skills/ti-admob-unified/references/rewarded-interstitial.md +101 -0
- package/skills/ti-admob-unified/references/roadmap.md +28 -31
- package/skills/ti-admob-unified/references/source-notes.md +51 -4
- package/skills/ti-admob-unified/references/source-snapshot.json +249 -45
- package/skills/ti-admob-unified/references/third-party-notices.md +4 -4
- package/skills/ti-game/SKILL.md +23 -6
- package/skills/ti-game/references/api.md +34 -30
- package/skills/ti-game/references/debugging-performance.md +18 -9
- package/skills/ti-game/references/examples.md +103 -20
- package/skills/ti-game/references/input.md +101 -0
- package/skills/ti-game/references/patterns.md +39 -15
- package/skills/ti-game/references/physics.md +80 -52
- package/skills/ti-game/references/project-setup.md +118 -56
- package/skills/ti-game/references/recipes-action.md +107 -8
- package/skills/ti-game/references/recipes-adventure-effects.md +41 -9
- package/skills/ti-game/references/roadmap.md +10 -3
- package/skills/ti-game/references/source-notes.md +81 -0
- package/skills/ti-game/references/tilemaps.md +12 -4
- package/skills/ti-synthengine/SKILL.md +81 -95
- package/skills/ti-synthengine/assets/example/README.md +84 -0
- package/skills/ti-synthengine/assets/example/app.js +1178 -0
- package/skills/ti-synthengine/assets/example/lib/sequenceOwner.js +83 -0
- package/skills/ti-synthengine/assets/example/lib/sequenceScore.js +25 -0
- package/skills/ti-synthengine/references/advanced-examples.md +174 -0
- package/skills/ti-synthengine/references/android-sim80-correction-evidence.zip +0 -0
- package/skills/ti-synthengine/references/android-sim80-correction.json +162 -0
- package/skills/ti-synthengine/references/api.md +434 -380
- package/skills/ti-synthengine/references/audio-engine.md +157 -230
- package/skills/ti-synthengine/references/bypass-physical-recheck-evidence.zip +0 -0
- package/skills/ti-synthengine/references/examples.md +123 -253
- package/skills/ti-synthengine/references/frontier-android-evidence.zip +0 -0
- package/skills/ti-synthengine/references/frontier-ipad-evidence.zip +0 -0
- package/skills/ti-synthengine/references/frontier-physical-validation.json +1918 -0
- package/skills/ti-synthengine/references/guide.md +188 -156
- package/skills/ti-synthengine/references/performance-review-evidence.zip +0 -0
- package/skills/ti-synthengine/references/performance-review.json +1146 -0
- package/skills/ti-synthengine/references/physical-validation.json +1457 -0
- package/skills/ti-synthengine/references/recipes-interaction.md +549 -0
- package/skills/ti-synthengine/references/recipes.md +423 -599
- package/skills/ti-synthengine/references/recommendations.md +63 -113
- package/skills/ti-synthengine/references/sound-design.md +134 -258
- package/skills/ti-synthengine/references/source-notes.md +93 -105
- package/skills/ti-synthengine/references/source-snapshot.json +379 -32
- package/skills/ti-synthengine/references/stats-performance.md +64 -20
- package/skills/ti-synthengine/references/studio-validation.json +6202 -0
- package/skills/ti-synthengine/references/troubleshooting.md +109 -121
- package/skills/ti-synthengine/references/unified-bypass-performance.json +22425 -0
- package/skills/ti-synthengine/references/unified-validation.json +314 -0
- package/AGENTS-VERCEL-RESEARCH.md +0 -175
|
@@ -1,117 +1,77 @@
|
|
|
1
|
-
> Source snapshot: official TiSynthEngine 1.0.0
|
|
1
|
+
> Source snapshot: official TiSynthEngine 1.0.0 documentation at release source commit `e7cbbe8a6f9ab38088fd8029c7b43cef6501101f` (2026-10-24). Upstream `documentation/recommendations.md` SHA-256: `206593e03b860b2d1c39316bf286cd276307bdb0120be050c262b21749bcccd8`.
|
|
2
2
|
|
|
3
3
|
# Recommendations
|
|
4
4
|
|
|
5
|
-
The defaults work for ordinary tones and chords. The choices below matter when
|
|
6
|
-
an app has dense overlap, user-controlled values, demanding speakers or several
|
|
7
|
-
audio systems sharing one lifecycle.
|
|
5
|
+
The defaults work for ordinary tones and chords. The choices below matter when an app has dense overlap, user-controlled values, demanding speakers or several audio systems sharing one lifecycle.
|
|
8
6
|
|
|
9
7
|
## Group simultaneous notes
|
|
10
8
|
|
|
11
|
-
Use `playChord()` when pitches form one known simultaneous event. The chord is
|
|
12
|
-
atomic. Protected profiles normalize per-voice source gain by the square root
|
|
13
|
-
of the event voice count; `raw` bypasses that normalization. Separate `playTone()`
|
|
14
|
-
calls are appropriate for independent touches and effects, but their start
|
|
15
|
-
times and gain are independent too.
|
|
9
|
+
Use `playChord()` when pitches form one known simultaneous event. The chord is atomic. Protected profiles normalize per-voice source gain by the square root of the event voice count; `raw` bypasses that normalization. Separate `playTone()` calls are appropriate for independent touches and effects, but their start times and gain are independent too.
|
|
16
10
|
|
|
17
|
-
For keys or pads a user can trigger freely, keep each event around 0.4 to 0.7
|
|
18
|
-
until the worst overlap has been heard. Raising every event above 1 is usually
|
|
19
|
-
a sign that the session needs `balanced`, not that each note needs more gain.
|
|
11
|
+
For keys or pads a user can trigger freely, keep each event around 0.4 to 0.7 until you have listened to the worst overlap. If every event needs gain above 1, consider `balanced` for the session before raising individual notes further.
|
|
20
12
|
|
|
21
13
|
## Choose the mixing profile once
|
|
22
14
|
|
|
23
|
-
| Situation
|
|
24
|
-
|
|
|
25
|
-
| General app audio and chords
|
|
26
|
-
| Mostly single notes that need more level
|
|
27
|
-
| Low pitches or distortion from a small phone speaker | `speakerSafe`
|
|
28
|
-
| The app performs its own strict gain staging
|
|
15
|
+
| Situation | Profile |
|
|
16
|
+
| ---------------------------------------------------- | -------------- |
|
|
17
|
+
| General app audio and chords | `conservative` |
|
|
18
|
+
| Mostly single notes that need more level | `balanced` |
|
|
19
|
+
| Low pitches or distortion from a small phone speaker | `speakerSafe` |
|
|
20
|
+
| The app performs its own strict gain staging | `raw` |
|
|
29
21
|
|
|
30
|
-
The profile is fixed for the stream. Changing it requires `shutdown()` and a
|
|
31
|
-
new `startEngine()` call, so it should not be a live sound-design control.
|
|
22
|
+
The profile is fixed for the stream. Changing it requires `shutdown()` and a new `start()` call, so it should not be a live sound-design control.
|
|
32
23
|
|
|
33
|
-
If a phone buzzes under `speakerSafe`, lower the event volume or raise the
|
|
34
|
-
pitch. Small drivers can distort acoustically even when the digital output is
|
|
35
|
-
well below its ceiling.
|
|
24
|
+
If a phone buzzes under `speakerSafe`, lower the event volume or raise the pitch. Small drivers can distort acoustically even when the digital output is well below its ceiling.
|
|
36
25
|
|
|
37
26
|
## Size `maxVoices` for real overlap
|
|
38
27
|
|
|
39
28
|
`maxVoices` controls capacity. It does not make the engine louder or quieter.
|
|
40
29
|
|
|
41
|
-
| App behavior
|
|
42
|
-
|
|
|
43
|
-
| Occasional interface feedback
|
|
44
|
-
| Game effects with overlap
|
|
45
|
-
| Chords, keys or long release tails |
|
|
46
|
-
| Explicit stress testing
|
|
30
|
+
| App behavior | Starting value |
|
|
31
|
+
| ---------------------------------- | -------------: |
|
|
32
|
+
| Occasional interface feedback | 4 to 8 |
|
|
33
|
+
| Game effects with overlap | 8 to 16 |
|
|
34
|
+
| Chords, keys or long release tails | 16 to 24 |
|
|
35
|
+
| Explicit stress testing | 32 |
|
|
47
36
|
|
|
48
|
-
Count release tails
|
|
49
|
-
steals the slot with the least time remaining when the pool is full. The short
|
|
50
|
-
fade prevents a hard click but cannot preserve the stolen note.
|
|
37
|
+
Count release tails along with buttons pressed at the same instant. Replacement first selects the lowest eligible priority; higher-priority voices are protected. Among that priority, timed-only events steal the slot with the least time remaining; sustained/transport voices prefer a releasing slot, then the oldest attack. The short fade avoids a hard click; the stolen note still ends early.
|
|
51
38
|
|
|
52
39
|
## Keep one lifecycle owner
|
|
53
40
|
|
|
54
|
-
Require the module in one audio service or controller, start it after the first
|
|
55
|
-
layout settles, and shut it down from the same owner. This avoids an engine that
|
|
56
|
-
outlives its window or a timer that starts after cleanup.
|
|
41
|
+
Require the module in one audio service or controller, start it after the first layout settles, and shut it down from the same owner. This avoids an engine that outlives its window or a timer that starts after cleanup.
|
|
57
42
|
|
|
58
|
-
A 250 ms debounce after `postlayout` is a practical baseline for a plain
|
|
59
|
-
screen. Heavy startup work, advertisements or entry animations may need more.
|
|
60
|
-
Measure the real app instead of increasing the delay indefinitely.
|
|
43
|
+
A 250 ms debounce after `postlayout` is a practical baseline for a plain screen. Heavy startup work, advertisements or entry animations may need more. Measure the real app instead of increasing the delay indefinitely.
|
|
61
44
|
|
|
62
|
-
Route recovery is automatic. Do not call `shutdown()` just because headphones
|
|
63
|
-
were inserted or removed. The sound crossing the transition may end early;
|
|
64
|
-
play later sounds normally once the system has moved to the new route.
|
|
45
|
+
Route recovery is automatic. Do not call `shutdown()` just because headphones were inserted or removed. The sound crossing the transition may end early; play later sounds normally once the system has moved to the new route.
|
|
65
46
|
|
|
66
47
|
## Coexisting with other audio
|
|
67
48
|
|
|
68
|
-
On iOS, the audio session is app-wide and the last component to configure it
|
|
69
|
-
wins. By default TiSynthEngine selects `Playback`, which ignores the ring/silent
|
|
70
|
-
switch and normally interrupts other apps. That behavior fits an instrument or
|
|
71
|
-
an app whose sound must be heard.
|
|
49
|
+
On iOS, the audio session is app-wide and the last component to configure it wins. By default TiSynthEngine selects `Playback`, which ignores the ring/silent switch and normally interrupts other apps. That behavior fits an instrument or an app whose sound must be heard.
|
|
72
50
|
|
|
73
|
-
A game that should respect the silent switch and let other apps' music keep
|
|
74
|
-
playing starts the engine with the ambient session:
|
|
51
|
+
A game that should respect the silent switch and let other apps' music keep playing starts the engine with the ambient session:
|
|
75
52
|
|
|
76
53
|
```javascript
|
|
77
|
-
synth.
|
|
54
|
+
synth.start({ audioSession: 'ambient' })
|
|
78
55
|
```
|
|
79
56
|
|
|
80
|
-
The engine applies the category at startup and again when it resumes after a
|
|
81
|
-
route change. Other native audio modules may still configure the app-wide
|
|
82
|
-
session later. Test the final startup sequence, interruptions, background
|
|
83
|
-
behavior and route changes on iOS. Android accepts the option and ignores it.
|
|
57
|
+
The engine applies the category at startup and again when it resumes after a route change. Other native audio modules may still configure the app-wide session later. Test the final startup sequence, interruptions, background behavior and route changes on iOS. Android accepts the option and ignores it.
|
|
84
58
|
|
|
85
|
-
Android mixes independent output streams at the system level, but another app
|
|
86
|
-
or stale test process can still consume low-latency resources. Force-stop old
|
|
87
|
-
test builds when diagnosing a glitch that does not reproduce after reboot.
|
|
59
|
+
Android mixes independent output streams at the system level, but another app or stale test process can still consume low-latency resources. Force-stop old test builds when diagnosing a glitch that does not reproduce after reboot.
|
|
88
60
|
|
|
89
61
|
## Keep resonance, FM and detune in check
|
|
90
62
|
|
|
91
|
-
The resonant filter, FM and stacked detuned voices change level and spectrum
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
- A
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
- A
|
|
98
|
-
|
|
99
|
-
- A resonance that keeps reaching the limiter makes the whole mix pump. Lower
|
|
100
|
-
the volume or the Q before reaching for a different profile.
|
|
101
|
-
- FM is not band-limited. A high carrier with a large `fmDepth` and `fmRatio`
|
|
102
|
-
aliases. Keep carriers of bell-like sounds around 500 Hz, or lower the index.
|
|
103
|
-
- A detuned stack is one voice per copy. Count them when choosing `maxVoices`.
|
|
104
|
-
Protected profiles divide per-voice source gain by the square root of the
|
|
105
|
-
event voice count; `raw` does not. Correlated or phase-aligned voices can still
|
|
106
|
-
reinforce each other, so this is not a guarantee of constant loudness or peaks.
|
|
107
|
-
- `patternend` follows the pattern scheduler. Use it to chain cues and release
|
|
108
|
-
state, not to line up audio to the sample.
|
|
63
|
+
The resonant filter, FM and stacked detuned voices change level and spectrum more than the basic controls do.
|
|
64
|
+
|
|
65
|
+
- A `lowpass` or `highpass` boosts the cutoff region by about `filterQ`, so Q 10 is roughly 20 dB. Raise Q in small steps and lower the event `volume` as you go. `bandpass` keeps unity gain at its center when level must stay put.
|
|
66
|
+
- A swept cutoff passes over every harmonic, so the level moves during the sweep. Judge a wah or laser at its loudest moment, which may occur after the start.
|
|
67
|
+
- A resonance that keeps reaching the limiter makes the whole mix pump. Lower the volume or the Q before reaching for a different profile.
|
|
68
|
+
- FM is not band-limited. A high carrier with a large `fmDepth` and `fmRatio` aliases. Keep carriers of bell-like sounds around 500 Hz, or lower the index.
|
|
69
|
+
- A detuned stack is one voice per copy. Count them when choosing `maxVoices`. Protected profiles divide per-voice source gain by the square root of the event voice count; `raw` does not. Correlated or phase-aligned voices can still reinforce each other, so this is not a guarantee of constant loudness or peaks.
|
|
70
|
+
- `sequenceend` reports completion or stopping by sequence identifier. Put contiguous notes into one sequence when sample timing matters; the event crosses JavaScript delivery latency.
|
|
109
71
|
|
|
110
72
|
## Validate values at the app boundary
|
|
111
73
|
|
|
112
|
-
The native API rejects invalid values instead of clamping them. Use
|
|
113
|
-
`getDefaults().limits` for a user-facing slider, remote configuration or saved
|
|
114
|
-
sound preset.
|
|
74
|
+
The native API rejects invalid values instead of clamping them. Use `getDefaults().limits` for a user-facing slider, remote configuration or saved sound preset.
|
|
115
75
|
|
|
116
76
|
```javascript
|
|
117
77
|
function acceptedFrequency (raw) {
|
|
@@ -123,30 +83,17 @@ function acceptedFrequency (raw) {
|
|
|
123
83
|
}
|
|
124
84
|
```
|
|
125
85
|
|
|
126
|
-
Do not copy the frequency maximum into application code. It depends on the
|
|
127
|
-
active sample rate and should be read again after startup.
|
|
86
|
+
Do not copy the frequency maximum into application code. It depends on the active sample rate and should be read again after startup.
|
|
128
87
|
|
|
129
|
-
The same rule applies to `noiseRate`, `lowPassHz` and `filterHz`. Validate a
|
|
130
|
-
custom `waveTable` as 2 to 64 finite values from -1 to 1, and remember that
|
|
131
|
-
`bitDepth` accepts zero or an integer from 2 to 16. For `detune`, check the
|
|
132
|
-
resulting pitch too: a shifted pitch that leaves the frequency range is
|
|
133
|
-
rejected even when the cents value is in range.
|
|
88
|
+
The same rule applies to `noiseRate`, `lowPassHz` and `filterHz`. Validate a custom `waveTable` as 2 to 64 finite values from -1 to 1, and remember that `bitDepth` accepts zero or an integer from 2 to 16. For `detune`, check the resulting pitch too: a shifted pitch that leaves the frequency range is rejected even when the cents value is in range.
|
|
134
89
|
|
|
135
|
-
Check Boolean return values during development. A rejected call includes the
|
|
136
|
-
method, key and reason in the native log. Logging that result at the caller is
|
|
137
|
-
often enough to identify a stale preset or misspelled field.
|
|
90
|
+
Check Boolean return values during development. A rejected call includes the method, key and reason in the native log. Logging that result at the caller is often enough to identify a stale preset or misspelled field.
|
|
138
91
|
|
|
139
92
|
## Test the intended sound
|
|
140
93
|
|
|
141
|
-
Listen on the output people will use. Headphones reveal noise and stereo detail;
|
|
142
|
-
the phone speaker reveals acoustic buzz, weak bass and mono collapse. Test at
|
|
143
|
-
low, normal and high system volume.
|
|
94
|
+
Listen on the output people will use. Headphones reveal noise and stereo detail; the phone speaker reveals acoustic buzz, weak bass and mono collapse. Test at low, normal and high system volume.
|
|
144
95
|
|
|
145
|
-
Use one sustained chord when judging polyphonic timbre. A loop that starts the
|
|
146
|
-
same chord before its predecessor finishes deliberately changes the number of
|
|
147
|
-
overlapping events. That can drive the limiter in a repeating cycle and sound
|
|
148
|
-
like pumping. Keep the loop as an extreme scheduling and recovery test, not as
|
|
149
|
-
the reference for how the chord should sound.
|
|
96
|
+
Use one sustained chord when judging polyphonic timbre. A loop that starts the same chord before its predecessor finishes deliberately changes the number of overlapping events. That can drive the limiter in a repeating cycle and sound like pumping. Use the loop to stress scheduling and recovery, and the single sustained chord as the tonal reference.
|
|
150
97
|
|
|
151
98
|
Exercise the real worst case:
|
|
152
99
|
|
|
@@ -154,11 +101,9 @@ Exercise the real worst case:
|
|
|
154
101
|
- the fastest pattern the app can request;
|
|
155
102
|
- a long release followed by unrelated feedback;
|
|
156
103
|
- a route change while a note is playing;
|
|
157
|
-
- screen off, interruption and background transitions if the product depends
|
|
158
|
-
on them.
|
|
104
|
+
- screen off, interruption and background transitions if the product depends on them.
|
|
159
105
|
|
|
160
|
-
An underrun counter only describes transport. A clean counter cannot tell you
|
|
161
|
-
whether a waveform, pitch or mix is pleasant.
|
|
106
|
+
An underrun counter only describes transport. A clean counter cannot tell you whether a waveform, pitch or mix is pleasant.
|
|
162
107
|
|
|
163
108
|
## Binaural placement
|
|
164
109
|
|
|
@@ -166,22 +111,27 @@ Use the [integration guide](guide.md#integrate-binaural-in-a-2d-app) to convert
|
|
|
166
111
|
|
|
167
112
|
## Known limits
|
|
168
113
|
|
|
169
|
-
-
|
|
170
|
-
|
|
171
|
-
- Every event has a finite duration of at most 60 seconds. There is no looping.
|
|
114
|
+
- Use `noteOn` with app-supplied IDs for individual release and compatible live updates. Check the required methods before enabling controls; timed events do not return voice handles.
|
|
115
|
+
- Timed tones and chords last at most 60 seconds including release. Sequence intervals and explicit note lengths use the sequence unit, at most 300 beats or 60,000 ms; sequence ADSR remains in milliseconds and release may extend beyond the interval. Sustained `noteOn` voices last until release, replacement or shutdown.
|
|
172
116
|
- The module synthesizes waveforms and does not play audio files.
|
|
173
|
-
-
|
|
174
|
-
-
|
|
175
|
-
their end through `patternend`, which is the only event the module emits.
|
|
117
|
+
- One native transport supports up to four independent sequences, preallocated by `maxSequences`. All share at most 32 voices.
|
|
118
|
+
- A single tone or chord has no completion event. Sequences emit `sequenceend` with their identifier and completed/stopped reason.
|
|
176
119
|
- Voice capacity and mixing profile remain fixed until shutdown.
|
|
177
|
-
-
|
|
178
|
-
- `lowPassHz` is a plain one-pole filter. The resonant filter has fixed 12 dB
|
|
179
|
-
per octave and one exponential sweep; there is no filter envelope.
|
|
120
|
+
- Sequences run on the sample clock in beats or milliseconds. `duration` controls intervals; `length` independently controls note duration.
|
|
121
|
+
- `lowPassHz` is a plain one-pole filter. The resonant filter has fixed 12 dB per octave and one exponential sweep; there is no filter envelope.
|
|
180
122
|
- FM has one modulator and works only on `SINE`.
|
|
181
|
-
- Binaural positions
|
|
182
|
-
-
|
|
183
|
-
- The module provides generic synthesis primitives
|
|
184
|
-
|
|
123
|
+
- Binaural positions occupy a front plane. Spatial held voices support smooth live movement; there is no rear positioning, distance attenuation or head tracking. Output is two channels, without a multichannel 2.1/5.1 routing API.
|
|
124
|
+
- One chorus/delay/reverb/saturation chain processes selected categories; per-voice sends override selection. It does not provide arbitrary routing or one processor per category.
|
|
125
|
+
- The module provides generic synthesis primitives and does not emulate hardware cycle by cycle.
|
|
126
|
+
|
|
127
|
+
Use a sample player or a dedicated music engine when a product needs streaming, sample loop points, audio-file decoding or multiple independent composition tracks. Use the native sequence transport for the supported musical grid.
|
|
128
|
+
|
|
129
|
+
## Use effects and held voices deliberately
|
|
130
|
+
|
|
131
|
+
Use `noteOn` for a sound whose duration follows interaction, such as a key, motor or beam; release its ID on touch end, cancellation, pause or scene teardown. Use `playSequence` for a finite musical cue or repeating grid. Neither needs JavaScript to keep an already accepted note alive. Both share the same 32-slot maximum with collision and interface tones; held notes can be stolen, and an accepted `updateVoice` on a stolen ID is a no-op. Optional priority 0-3 affects stealing; it reserves no voices. There is no voice-finished event.
|
|
132
|
+
|
|
133
|
+
Keep chorus/delay/reverb mixes modest when dialogue or short game feedback must remain distinct. One shared chain processes selected categories, not necessarily the whole mix. Select `applyTo` categories and each event's `bus`; an explicit `effectSend` overrides category selection. For example, select `music` for a victory sequence and leave `effects` dry, or set an individual shot's send to 0. Input/master gains and the final limiter remain global. Disabling effects lets tails drain for at most 30 seconds; use panic when immediate history invalidation is required. Start with saturation disabled and compare creative drive at matched levels. Do not use saturation as an automatic substitute for the final limiter.
|
|
134
|
+
|
|
135
|
+
Fixed input/event gain does not decrease when unrelated voices start. If level dips, inspect `maxLimiterReductionDb` and `preLimiterPeakDb`, then consider same-pitch phase cancellation or the device's speaker protection. Eight coherent independent voices can still exceed the limiter threshold; module capacity is not a clean-mix loudness guarantee. See [measurement example](advanced-examples.md#measure-peaks-and-limiter-reduction).
|
|
185
136
|
|
|
186
|
-
|
|
187
|
-
loop points, per-voice control or a synchronized composition timeline.
|
|
137
|
+
Measure the complete workload on each target device, including held voices, binaural, LFOs, all enabled effects and tails. The [historical statistics benchmark](stats-performance.md) predates these features; the [current technical report](studio-validation.json) includes an unmet full-chain host deadline criterion. Neither is a guarantee of game-frame rate, physical audio deadlines, heat or battery life.
|