@maccesar/titools 5.1.1 → 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.
Files changed (98) hide show
  1. package/CONTRIBUTING.md +69 -0
  2. package/README.md +112 -72
  3. package/agents/ti-pro.md +5 -1
  4. package/commands/ti-audit.md +5 -1
  5. package/docs/examples.md +91 -0
  6. package/docs/knowledge-index.md +57 -0
  7. package/lib/config.js +2 -0
  8. package/lib/downloader.js +1 -1
  9. package/package.json +4 -2
  10. package/skills/purgetss/references/multi-density-images.md +1 -1
  11. package/skills/ti-admob-unified/SKILL.md +58 -0
  12. package/skills/ti-admob-unified/agents/openai.yaml +4 -0
  13. package/skills/ti-admob-unified/assets/example/app.js +1207 -0
  14. package/skills/ti-admob-unified/assets/example/lib/ads.js +646 -0
  15. package/skills/ti-admob-unified/assets/example/library-usage.js +136 -0
  16. package/skills/ti-admob-unified/references/api-reference.md +615 -0
  17. package/skills/ti-admob-unified/references/banners.md +435 -0
  18. package/skills/ti-admob-unified/references/contributing.md +233 -0
  19. package/skills/ti-admob-unified/references/dependencies.md +91 -0
  20. package/skills/ti-admob-unified/references/fullscreen.md +238 -0
  21. package/skills/ti-admob-unified/references/game-monetization.md +148 -0
  22. package/skills/ti-admob-unified/references/getting-started.md +319 -0
  23. package/skills/ti-admob-unified/references/index.md +33 -0
  24. package/skills/ti-admob-unified/references/integration.md +87 -0
  25. package/skills/ti-admob-unified/references/library.md +220 -0
  26. package/skills/ti-admob-unified/references/mediation-parity.md +17 -0
  27. package/skills/ti-admob-unified/references/mediation.md +145 -0
  28. package/skills/ti-admob-unified/references/migration.md +259 -0
  29. package/skills/ti-admob-unified/references/module-changelog.md +84 -0
  30. package/skills/ti-admob-unified/references/module-license.txt +21 -0
  31. package/skills/ti-admob-unified/references/privacy.md +281 -0
  32. package/skills/ti-admob-unified/references/production.md +67 -0
  33. package/skills/ti-admob-unified/references/rewarded-interstitial.md +101 -0
  34. package/skills/ti-admob-unified/references/roadmap.md +143 -0
  35. package/skills/ti-admob-unified/references/source-notes.md +80 -0
  36. package/skills/ti-admob-unified/references/source-snapshot.json +644 -0
  37. package/skills/ti-admob-unified/references/third-party-notices.md +22 -0
  38. package/skills/ti-game/SKILL.md +31 -5
  39. package/skills/ti-game/references/api.md +36 -24
  40. package/skills/ti-game/references/debugging-performance.md +22 -7
  41. package/skills/ti-game/references/examples.md +113 -20
  42. package/skills/ti-game/references/input.md +101 -0
  43. package/skills/ti-game/references/patterns.md +56 -10
  44. package/skills/ti-game/references/physics.md +530 -0
  45. package/skills/ti-game/references/project-setup.md +131 -47
  46. package/skills/ti-game/references/recipes-action.md +149 -18
  47. package/skills/ti-game/references/recipes-adventure-effects.md +47 -4
  48. package/skills/ti-game/references/roadmap.md +11 -4
  49. package/skills/ti-game/references/source-notes.md +81 -0
  50. package/skills/ti-game/references/tilemaps.md +13 -4
  51. package/skills/ti-game-assets/SKILL.md +53 -0
  52. package/skills/ti-game-assets/agents/openai.yaml +4 -0
  53. package/skills/ti-game-assets/references/alpha.md +26 -0
  54. package/skills/ti-game-assets/references/art-direction.md +37 -0
  55. package/skills/ti-game-assets/references/integration.md +49 -0
  56. package/skills/ti-game-assets/references/manifest.example.json +429 -0
  57. package/skills/ti-game-assets/references/manifest.md +39 -0
  58. package/skills/ti-game-assets/references/offline-audio.md +33 -0
  59. package/skills/ti-game-assets/references/prompts.md +33 -0
  60. package/skills/ti-game-assets/references/repeating-textures.md +17 -0
  61. package/skills/ti-game-assets/references/responsible-ads.md +31 -0
  62. package/skills/ti-game-assets/references/sound-assets.md +42 -0
  63. package/skills/ti-game-assets/references/vector-sources.md +21 -0
  64. package/skills/ti-game-assets/scripts/alpha_tools.py +160 -0
  65. package/skills/ti-game-assets/scripts/requirements.txt +1 -0
  66. package/skills/ti-game-assets/scripts/validate_manifest.py +267 -0
  67. package/skills/ti-synthengine/SKILL.md +77 -67
  68. package/skills/ti-synthengine/assets/example/README.md +84 -0
  69. package/skills/ti-synthengine/assets/example/app.js +1178 -0
  70. package/skills/ti-synthengine/assets/example/lib/sequenceOwner.js +83 -0
  71. package/skills/ti-synthengine/assets/example/lib/sequenceScore.js +25 -0
  72. package/skills/ti-synthengine/references/advanced-examples.md +174 -0
  73. package/skills/ti-synthengine/references/android-sim80-correction-evidence.zip +0 -0
  74. package/skills/ti-synthengine/references/android-sim80-correction.json +162 -0
  75. package/skills/ti-synthengine/references/api.md +573 -153
  76. package/skills/ti-synthengine/references/audio-engine.md +272 -124
  77. package/skills/ti-synthengine/references/bypass-physical-recheck-evidence.zip +0 -0
  78. package/skills/ti-synthengine/references/examples.md +355 -106
  79. package/skills/ti-synthengine/references/frontier-android-evidence.zip +0 -0
  80. package/skills/ti-synthengine/references/frontier-ipad-evidence.zip +0 -0
  81. package/skills/ti-synthengine/references/frontier-physical-validation.json +1918 -0
  82. package/skills/ti-synthengine/references/guide.md +426 -75
  83. package/skills/ti-synthengine/references/performance-review-evidence.zip +0 -0
  84. package/skills/ti-synthengine/references/performance-review.json +1146 -0
  85. package/skills/ti-synthengine/references/physical-validation.json +1457 -0
  86. package/skills/ti-synthengine/references/recipes-interaction.md +549 -0
  87. package/skills/ti-synthengine/references/recipes.md +434 -420
  88. package/skills/ti-synthengine/references/recommendations.md +72 -85
  89. package/skills/ti-synthengine/references/sound-design.md +375 -155
  90. package/skills/ti-synthengine/references/source-notes.md +109 -0
  91. package/skills/ti-synthengine/references/source-snapshot.json +452 -0
  92. package/skills/ti-synthengine/references/stats-performance.json +2992 -0
  93. package/skills/ti-synthengine/references/stats-performance.md +82 -0
  94. package/skills/ti-synthengine/references/studio-validation.json +6202 -0
  95. package/skills/ti-synthengine/references/troubleshooting.md +123 -78
  96. package/skills/ti-synthengine/references/unified-bypass-performance.json +22425 -0
  97. package/skills/ti-synthengine/references/unified-validation.json +314 -0
  98. package/AGENTS-VERCEL-RESEARCH.md +0 -175
@@ -1,38 +1,51 @@
1
- > Source snapshot: official TiSynthEngine 1.0.0 documentation at commit `6685b81` (2026-08-29).
1
+ > Source snapshot: official TiSynthEngine 1.0.0 documentation at release source commit `e7cbbe8a6f9ab38088fd8029c7b43cef6501101f` (2026-10-24). Upstream `documentation/troubleshooting.md` SHA-256: `939960cde5860569699916208c0d3b352e60ba2a7603b5046dcefa9970294b70`.
2
2
 
3
3
  # Troubleshooting
4
4
 
5
- Start with the Boolean returned by the call and the native log. Most silent
6
- requests are contract rejections, a stale binary or an engine that never
7
- started.
5
+ Start with the Boolean returned by the call and the native log. Most silent requests are contract rejections, a stale binary or an engine that never started.
8
6
 
9
7
  ## A call returns `false`
10
8
 
11
- Look for a structured warning in logcat or the Xcode console:
9
+ For methods that emit structured validation warnings, inspect logcat or the Xcode console:
12
10
 
13
11
  ```text
14
- event=validation_warning method=playPattern key=steps reason=invalid_step_type action=rejected value=C4
12
+ event=validation_warning method=playTone key=duraton reason=unsupported_option action=rejected value=200
15
13
  ```
16
14
 
17
- Common fixes:
18
-
19
- | Reason | Check |
20
- | --- | --- |
21
- | `unsupported_option` | Remove or correct the named key. Every options object is strict. |
22
- | `invalid_step_type` | Make every pattern step an object, not a number or string. |
23
- | `conflicting_pitch_fields` | Send only one of `note`, `frequency` or `rest: true`. |
24
- | `missing_pitch_or_rest` | Add one pitch field or an explicit rest. |
25
- | `out_of_range` | Compare the value with `getDefaults().limits`. |
26
- | `not_integer` | Use whole milliseconds and integer waveform values where required. |
27
- | `invalid_note` | Check spelling, accidental case and octave. |
28
- | envelope reason | Make attack and release fit inside total duration. |
15
+ Always check the return value: `playSequence` rejects with 0, while Boolean methods reject with `false`. Some sequence/control rejection paths do not emit a structured warning; absence of a new log entry does not establish acceptance.
29
16
 
30
- Warnings are deduplicated by method, key and reason. Repeating the same bad
31
- call may return `false` without printing a new line each time.
17
+ Common fixes:
32
18
 
33
- An `overflow` warning means the command queue was full. Reduce the command
34
- burst or wait for the audio thread to consume queued work. Chords are rejected
35
- as a whole rather than partially started.
19
+ | Reason | Check |
20
+ | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
21
+ | `unsupported_option` | Remove or correct the named key. Every options object is strict. |
22
+ | `invalid_step_type` | Make every pattern step an object, not a number or string. |
23
+ | `conflicting_pitch_fields` | Timed/held calls use mutually exclusive `note`/`frequency`; each sequence step uses exactly one `notes` array, `frequencies` array or `rest: true`. |
24
+ | `missing_pitch_or_rest` | Add one pitch field or an explicit rest. |
25
+ | `out_of_range` | Compare the value with `getDefaults().limits`. |
26
+ | `not_integer` | Use integer milliseconds for timed tone/chord envelope fields and integer waveform values; native sequence intervals and lengths may be fractional. |
27
+ | `invalid_note` | Check spelling, accidental case and octave. |
28
+ | `invalid_sample_count` | Supply 2 to 64 values in `waveTable`. |
29
+ | `unsupported_value` | Use `none`, `lowpass`, `highpass` or `bandpass` for `filterType`. |
30
+ | `sustain_without_decay` | Add a `decay` greater than 0, or remove `sustain`. |
31
+ | `decay_exceeds_remaining_duration` | Shorten `attack` or `decay`, or lengthen `duration`. The default attack counts. |
32
+ | `filter_type_required` | Set `filterType` to a filter, or remove `filterHz`, `filterHzEnd` and `filterQ`. |
33
+ | `fm_requires_sine` | Use `SINE` for FM, or set `fmDepth` to 0 and remove `fmDepthEnd`. |
34
+ | `fm_depth_required` | Set `fmDepth` or `fmDepthEnd`, or remove `fmRatio`. |
35
+ | `conflicting_spatial_fields` | Remove `pan`, `panEnd`, `pans` and `panSpread` whenever sending `spatialX` or `spatialY`; check pattern root and steps. |
36
+ | `too_many_values` | Pass no more `pans` or `detunes` than the chord has pitches. |
37
+ | `missing_required` with `waveTable` | Add a table whenever `waveType` is `WAVETABLE`. |
38
+ | envelope reason | Make attack and release fit inside total duration. |
39
+
40
+ Warnings are deduplicated by method, key and reason. Repeating the same bad call may return `false` without printing a new line each time.
41
+
42
+ An `overflow` warning means the command queue was full. Reduce the command burst or wait for the audio thread to consume queued work. A chord is either accepted in full or rejected; it cannot start partially.
43
+
44
+ The envelope and filter rules apply to the final values of each sounding event. In a native sequence, each step's `overrides` merges over root `voice`: root `voice.sustain` is valid when every sounding step supplies compatible decay, and `voice.filterHz` needs a non-none filter type after merging. Timed tones/chords enforce their total-duration envelope budget; held and sequence ADSR has no sequence-interval budget. A `detune` that pushes the pitch, or `frequencyEnd`, outside the frequency range is rejected with `out_of_range`.
45
+
46
+ `fmDepthEnd: 0` is valid. It sweeps the index down to nothing. Omit the key, rather than passing 0, when the index should not move.
47
+
48
+ For the shaping controls, check the discontinuous disabled values as well as the numeric range: `bitDepth` accepts 0 or 2 through 16, and `pulseWidthEnd` accepts 0 or 0.05 through 0.95. A `waveTable` must contain only finite values from -1 to 1.
36
49
 
37
50
  ## The installed contract is wrong
38
51
 
@@ -45,98 +58,100 @@ if (actual !== '1.0.0') {
45
58
  }
46
59
  ```
47
60
 
48
- Confirm both entries in `tiapp.xml` pin 1.0.0. Then remove the application's
49
- build output and rebuild so Titanium does not reuse an archive from an earlier
50
- build. The module directories should be:
61
+ Confirm both entries in `tiapp.xml` pin 1.0.0. Then remove the application's build output and rebuild so Titanium does not reuse an archive from an earlier build. The module directories should be:
51
62
 
52
63
  ```text
53
64
  modules/android/ti.synthengine/1.0.0/
54
65
  modules/iphone/ti.synthengine/1.0.0/
55
66
  ```
56
67
 
68
+ For binaural, also inspect `getDefaults().limits.spatialX` and `.spatialY`. Use the official packages to avoid stale development binaries. Copying the package does not update an already installed app: rebuild and reinstall it.
69
+
70
+ ## Binaural does not change the position
71
+
72
+ Inspect the options sent to the native method as well as the settings screen:
73
+
74
+ - Every effect that should be spatial sends `spatialX` and/or `spatialY`. A switch alone does not modify existing playback calls.
75
+ - Values are finite numbers within -1 to 1, with positive Y above and negative Y below. A 0 to 100% height slider scales the source position; it does not put all sounds above.
76
+ - Turning binaural off removes both coordinate keys. Sending zeros leaves binaural enabled at the front center.
77
+ - No stereo placement fields remain, even with value 0 or through pattern inheritance. Handle the Boolean return value.
78
+ - The installed contract reports both spatial limits and the device has the rebuilt app.
79
+ - Use headphones and one broadband event at a time; with binaural off, points with the same X use the same horizontal placement regardless of Y.
80
+ - Timed tones/chords and each sequence attack keep their specified position. A spatial held voice can move through `updateVoice({ voiceId, spatialX, spatialY })`; omitted coordinates retain their previous value, and the FIR ramps over 10 ms without clearing history. A stereo voice cannot be converted to spatial by an update.
81
+
82
+ The [integration guide](guide.md#integrate-binaural-in-a-2d-app) contains the JavaScript conversion and explains switch/slider behavior.
83
+
84
+ ## Statistics are missing or show `null`
85
+
86
+ Older development packages can report 1.0.0 without statistics methods. Check `typeof synth.getStats`, `typeof synth.setStatsEnabled` and `typeof synth.resetStats`; install the current packages, rebuild and reinstall the app if needed.
87
+
88
+ Basic voice/queue/rejection counters do not require diagnostics. Timing, output peak/RMS and limiter reduction require `setStatsEnabled(true)` and a measured callback/window. `null` means unmeasured or unavailable; keep it distinct from zero. The current iOS backend always reports `null` for underruns, output buffer size and estimated hardware latency. Android backend metrics are best-effort and independent of the diagnostic switch.
89
+
90
+ Read at a modest rate, such as 5 Hz, and stop polling and optional measurements when the diagnostic owner hides or closes. `getStats()` never resets counters; call `resetStats()` deliberately. See the [integration recipe](guide.md#read-engine-statistics).
91
+
92
+ ## Render load changes while no notes are playing
93
+
94
+ `renderLoad` is measured callback elapsed time divided by the time represented by that audio block. The native value is a fraction: `0.012` means 1.2%, and `1.0` means 100%. The interactive example displays percentages.
95
+
96
+ An open stream keeps delivering blocks, even in silence. It consumes commands, processes the output/limiter and measures signal levels when diagnostics are enabled. That work continues with zero active voices. Later sounds can use the running output without reopening it for each event, reducing repeated startup work. Envelopes and fades still handle abrupt signal changes; an open stream alone cannot guarantee a click-free onset.
97
+
98
+ The iOS app-wide session policy (`ambient` or `playback`) is separate from whether the native stream is open. Scheduling, system activity and measurement overhead cause elapsed time to vary between blocks. Expect a small, changing baseline. The two displayed decimals do not guarantee that level of timing accuracy.
99
+
100
+ A block at 100% has used its nominal time budget; repeated readings at or above that level warrant investigation. Low readings describe the observed blocks and do not prove every deadline was met or establish sound quality. Compare matching configurations on the same device. Stopping playback with `stopAll()` leaves the stream open; `shutdown()` closes it and optional measurements become `null`. See the [statistics contract](api.md#getstats).
101
+
57
102
  ## The first sound glitches
58
103
 
59
- Do not start the engine during the first layout. Add the `postlayout` listener
60
- before opening the window, debounce it for about 250 ms, and start after the
61
- screen settles. Cancel the timer if the owner closes first. The complete code
62
- is in the [guide](guide.md#lifecycle).
104
+ Do not start the engine during the first layout. Add the `postlayout` listener before opening the window, debounce it for about 250 ms, and start after the screen settles. Cancel the timer if the owner closes first. The complete code is in the [guide](guide.md#lifecycle).
63
105
 
64
- If startup remains noisy, temporarily remove other launch work and increase the
65
- quiet period. Ads, animations, remote configuration and another audio module
66
- can all compete during the same short interval.
106
+ If startup remains noisy, temporarily remove other launch work and increase the quiet period. Ads, animations, remote configuration and another audio module can all compete during the same short interval.
67
107
 
68
108
  ## The app is silent
69
109
 
70
110
  Check these in order:
71
111
 
72
- 1. `startEngine()` returned `true`.
112
+ 1. `start()` returned `true`.
73
113
  2. The tone, chord or pattern call returned `true`.
74
114
  3. Master and event `volume` are above zero.
75
115
  4. The device media volume is up and the expected route is selected.
76
116
  5. `shutdown()` was not called by another owner.
77
117
  6. The note is within the current frequency range.
78
- 7. The app is not relying on a pattern that another `playPattern()` call
79
- replaced.
118
+ 7. The app retained the positive sequence identifier and checked publication acceptance.
80
119
 
81
- On iOS, the module uses a `Playback` session, so the silent switch should not
82
- mute it. Another audio component can change the app-wide session after engine
83
- startup; inspect the order if behavior differs from the simple example.
120
+ On iOS, the module uses a `Playback` session by default, so the silent switch should not mute it. With `audioSession: 'ambient'` the silent switch mutes it by design. Another audio component can change the app-wide session after engine startup; inspect the order if behavior differs from the simple example.
84
121
 
85
- ## A pattern stops or skips steps
122
+ ## A sequence stops or skips steps
86
123
 
87
- Only one pattern is pending. A new `playPattern()` call cancels steps from the
88
- previous scheduler that have not fired. Voices already on the audio thread keep
89
- playing.
124
+ Check the positive sequence ID, available `maxSequences` capacity and accepted updates. New sequences do not replace existing ones. All sequences and direct events share the voice pool; higher-priority voices can cause an entire lower-priority chord to drop. Inspect `priorityDropCount`, `rejectedPublicationCount` and output diagnostics separately. A stopped or completed identifier is retired and cannot be resumed by an update.
90
125
 
91
- `stopAll()` fades current voices but does not cancel later scheduled steps. Use
92
- `shutdown()` when both active audio and future scheduling must end, or replace
93
- the pattern deliberately before stopping its current voices.
126
+ ## `sequenceend` never arrives
94
127
 
95
- Make sure every step is an object and has exactly one pitch source:
96
-
97
- ```javascript
98
- steps: [
99
- { note: 'C4' },
100
- { rest: true },
101
- { frequency: 660 }
102
- ]
103
- ```
128
+ The event uses `{ sequenceId, reason }`, where reason is `completed` or `stopped`. Looping sequences complete only after an explicit stop. Check that publication returned a positive ID, the listener remains registered and JavaScript is able to receive events. Delivery happens outside audio and does not time the next attack. Shutdown tears down the owner; do not depend on a future completion callback after cleanup.
104
129
 
105
130
  ## A chord is distorted or pumps
106
131
 
107
- Use one `playChord()` call for notes that should begin together. Several
108
- `playTone()` calls have independent source gain and produce a hotter sum.
132
+ Use one `playChord()` call for notes that should begin together. Several `playTone()` calls have independent source gain and produce a hotter sum.
109
133
 
110
134
  If the limiter engages repeatedly:
111
135
 
112
136
  - lower event volume;
137
+ - lower `filterQ`, because a resonant low-pass or high-pass boosts its cutoff by about Q;
113
138
  - use `conservative` instead of `balanced` or `raw`;
114
139
  - use `speakerSafe` on a small speaker;
115
140
  - avoid retriggering a long event before its previous release ends.
116
141
 
117
- A repeating overlap test is expected to change the summed level. Judge tonal
118
- quality with one chord, then use the loop only to test stress behavior.
142
+ A repeating overlap test is expected to change the summed level. Judge tonal quality with one chord, then use the loop only to test stress behavior.
119
143
 
120
144
  ## The phone speaker buzzes but headphones are clean
121
145
 
122
- That usually points to the physical speaker or its protection system. Try
123
- `speakerSafe`, lower the event level, shorten low-frequency energy, or move the
124
- important pitch above roughly 200 Hz. A digital limiter cannot make a tiny
125
- speaker reproduce bass it cannot move cleanly.
146
+ The physical speaker or its protection system is usually the cause. Try `speakerSafe`, lower the event level, shorten low-frequency energy, or move the important pitch above roughly 200 Hz. A digital limiter cannot make a tiny speaker reproduce bass it cannot move cleanly.
126
147
 
127
- Compare several devices before changing the synthesis globally. A resonance on
128
- one handset may not exist on another.
148
+ Compare several devices before changing the synthesis globally. A resonance on one handset may not exist on another.
129
149
 
130
150
  ## Audio changes after connecting headphones
131
151
 
132
- Route recovery is automatic, but the sound crossing the hardware transition
133
- may end early. The operating system can also mute or fade the new route for a
134
- brief device-dependent interval. Wait for the route to settle and play a new
135
- sound; do not restart the app.
152
+ Route recovery is automatic, but the sound crossing the hardware transition may end early. The operating system can also mute or fade the new route for a brief device-dependent interval. Wait for the route to settle and play a new sound; do not restart the app.
136
153
 
137
- If later sounds remain silent, capture the Android or Xcode log around the route
138
- change. Confirm that no screen lifecycle handler called `shutdown()` at the same
139
- time.
154
+ If later sounds remain silent, capture the Android or Xcode log around the route change. Confirm that no screen lifecycle handler called `shutdown()` at the same time.
140
155
 
141
156
  ## Android-specific checks
142
157
 
@@ -148,15 +163,45 @@ time.
148
163
 
149
164
  ## iOS-specific checks
150
165
 
151
- - Confirm the deployment target is iOS 13 or newer.
166
+ - Confirm the deployment target is iOS 15 or newer.
152
167
  - Check whether another module changes `AVAudioSession` after startup.
153
168
  - Test interruptions, phone calls, Bluetooth and route changes on hardware.
154
169
  - Use the matching device or simulator slice from the 1.0.0 archive.
155
170
 
156
171
  ## What to include in a bug report
157
172
 
158
- Include the platform, OS version, device model, Titanium SDK version, module
159
- version, mixing profile, `maxVoices`, the smallest accepted call that reproduces
160
- the problem, and the native log around startup and playback. For a sound-quality
161
- report, say whether it reproduces through the built-in speaker, wired
162
- headphones, Bluetooth or all routes.
173
+ Include the platform, OS version, device model, Titanium SDK version, module version, mixing profile, `maxVoices`, the smallest accepted call that reproduces the problem, and the native log around startup and playback. For a sound-quality report, say whether it reproduces through the built-in speaker, wired headphones, Bluetooth or all routes.
174
+
175
+ ## Held notes, sequences or effects methods are missing
176
+
177
+ The official release reports API version 1.0.0. Detect `noteOn`/`noteOff`/`updateVoice`, all four sequence methods and `setMasterProcessing` according to the feature needed. Install matching current Android/iOS packages, rebuild and reinstall the consumer app. A stale development binary may report the same version without the complete release API. See [capability detection](guide.md#detect-required-capabilities).
178
+
179
+ ## A held voice does not release or update
180
+
181
+ Use the original positive `voiceId`, not the pitch or an ID that has already been reused. `noteOn` does not accept `duration` or temporal `*End` fields. Source, filter type, table, quantization and ADSR require a new attack. Compatible `updateVoice` controls include live noise clock, one-pole cutoff, spatial position for a spatial voice, stereo pan for a stereo voice, modulation and explicit effect send, in addition to pitch/volume/filter/vibrato/FM/pulse targets. Changed continuous controls ramp for 10 ms while retaining phase, envelope and spatial history; `noiseRate: 0` means white noise and `lowPassHz: 0` bypasses that filter.
182
+
183
+ Check Boolean returns. A full public queue can reject `noteOff`; retry twice at 16 ms outside render, then shut down/report if still rejected. Cancel those retries on owner teardown. The [held motor example](advanced-examples.md#sustained-game-motor) implements this policy. Touch cancellation, pause and close need cleanup as well as normal key up.
184
+
185
+ An ended or stolen ID accepts updates as a no-op, so acceptance does not prove audible continuity. Held voices share capacity with timed sounds and transport voices. Check replacement counts under dense collision load, leave headroom in the pool and use an app-owned renewal policy if needed. Increasing capacity above 32 or enabling reverb does not reserve a voice.
186
+
187
+ ## A native sequence edit seems delayed or does not resume
188
+
189
+ Boolean update acceptance precedes application. Query `getSequenceState({ sequenceId }).revision` when the state is non-null. Structural edits enter at the next step and swing at the next pair. `setTempo` applies globally at the next audio block. Bank pressure rejects the whole publication; retain accepted UI state and retry later. Updates cannot resume retired IDs; create a new sequence and store its new ID. Steps contain MIDI `notes`, `frequencies` or `rest: true`, with optional interval `duration` and independent note `length`.
190
+
191
+ ## Effects are silent, remain audible when disabled or affect other sounds
192
+
193
+ The stream must run and `setMasterProcessing` must accept the configuration. Effects start disabled. Check `applyTo` categories, each event's `bus` and any explicit `effectSend`, which overrides selection. Delay and LFO sync follow global `setTempo`, initially 120 BPM. Free settings retain hertz or milliseconds.
194
+
195
+ Disabling effects closes input smoothly and lets bounded tails finish, then bypasses exactly. It retains input gain. Panic through `stopAll` stops every sequence, fades voices and invalidates effect histories. Shutdown closes audio and frees resources. Saturation changes timbre separately from the limiter.
196
+
197
+ ## A brief level dip is gone before the meter refreshes
198
+
199
+ Enable diagnostics, reset deliberately, then inspect `preLimiterPeakDb` and `maxLimiterReductionDb`. They retain the native pre-limiter peak and greatest attenuation since reset, including brief interventions between UI polls. `limiterReductionDb` is a window measurement and can return to zero sooner. Older packages may omit the accumulated fields; disabled/unmeasured diagnostics return `null`. See [measurement example](advanced-examples.md#measure-peaks-and-limiter-reduction).
200
+
201
+ If accumulated attenuation remains near zero, investigate phase cancellation between repeated same-pitch oscillators, changing filters or the device speaker/protection path. Compatible released public held-note repetitions preserve predecessor phase; simultaneous unisons, timed calls and transport notes retain their existing phase behavior. Extra effects and resonance can consume headroom even when source gain is fixed. Compare matched levels through headphones and the physical speaker before changing the mix globally.
202
+
203
+ ## A wavetable sounds rough
204
+
205
+ `WAVETABLE` repeats the supplied values using a stepped lookup. A short table can sound grainy or buzzy even when its values describe a sine wave and `bitDepth` is 0. Its harmonic character changes with pitch and filtering; this does not require reverb, an LFO or creative saturation to be enabled.
206
+
207
+ Compare one note with `SINE`, at a comfortable matched level, to distinguish the source's texture from the combined sound of overlapping notes. Read `preLimiterPeakDb` and `maxLimiterReductionDb` with diagnostics enabled to investigate mix headroom. No limiter reduction does not prove that the physical speaker, headphones or output processing are clean. Keep a subjective listening observation separate from a confirmed clipping or buffer-loss diagnosis.