@maccesar/titools 5.2.0 → 5.2.2
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 +82 -0
- package/README.md +83 -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/commands/uninstall.js +19 -16
- package/lib/commands/update.js +1 -1
- package/lib/downloader.js +1 -1
- package/lib/utils.js +2 -0
- 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,62 +1,51 @@
|
|
|
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/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
|
-
|
|
9
|
+
For methods that emit structured validation warnings, inspect logcat or the Xcode console:
|
|
12
10
|
|
|
13
11
|
```text
|
|
14
|
-
event=validation_warning method=
|
|
12
|
+
event=validation_warning method=playTone key=duraton reason=unsupported_option action=rejected value=200
|
|
15
13
|
```
|
|
16
14
|
|
|
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.
|
|
16
|
+
|
|
17
17
|
Common fixes:
|
|
18
18
|
|
|
19
|
-
| Reason
|
|
20
|
-
|
|
|
21
|
-
| `unsupported_option`
|
|
22
|
-
| `invalid_step_type`
|
|
23
|
-
| `conflicting_pitch_fields`
|
|
24
|
-
| `missing_pitch_or_rest`
|
|
25
|
-
| `out_of_range`
|
|
26
|
-
| `not_integer`
|
|
27
|
-
| `invalid_note`
|
|
28
|
-
| `invalid_sample_count`
|
|
29
|
-
| `unsupported_value`
|
|
30
|
-
| `sustain_without_decay`
|
|
31
|
-
| `decay_exceeds_remaining_duration`
|
|
32
|
-
| `filter_type_required`
|
|
33
|
-
| `fm_requires_sine`
|
|
34
|
-
| `fm_depth_required`
|
|
35
|
-
| `conflicting_spatial_fields`
|
|
36
|
-
| `too_many_values`
|
|
37
|
-
| `missing_required` with `waveTable` | Add a table whenever `waveType` is `WAVETABLE`.
|
|
38
|
-
| envelope reason
|
|
39
|
-
|
|
40
|
-
Warnings are deduplicated by method, key and reason. Repeating the same bad
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
root is fine when each step supplies a `decay`, and a root `filterHz` is
|
|
50
|
-
rejected when no step has a `filterType`. A `detune` that pushes the pitch, or
|
|
51
|
-
`frequencyEnd`, outside the frequency range is rejected with `out_of_range`.
|
|
52
|
-
|
|
53
|
-
`fmDepthEnd: 0` is valid. It sweeps the index down to nothing. Omit the key,
|
|
54
|
-
rather than passing 0, when the index should not move.
|
|
55
|
-
|
|
56
|
-
For the shaping controls, check the discontinuous disabled values as well
|
|
57
|
-
as the numeric range: `bitDepth` accepts 0 or 2 through 16, and
|
|
58
|
-
`pulseWidthEnd` accepts 0 or 0.05 through 0.95. A `waveTable` must contain only
|
|
59
|
-
finite values from -1 to 1.
|
|
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.
|
|
60
49
|
|
|
61
50
|
## The installed contract is wrong
|
|
62
51
|
|
|
@@ -69,20 +58,18 @@ if (actual !== '1.0.0') {
|
|
|
69
58
|
}
|
|
70
59
|
```
|
|
71
60
|
|
|
72
|
-
Confirm both entries in `tiapp.xml` pin 1.0.0. Then remove the application's
|
|
73
|
-
build output and rebuild so Titanium does not reuse an archive from an earlier
|
|
74
|
-
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:
|
|
75
62
|
|
|
76
63
|
```text
|
|
77
64
|
modules/android/ti.synthengine/1.0.0/
|
|
78
65
|
modules/iphone/ti.synthengine/1.0.0/
|
|
79
66
|
```
|
|
80
67
|
|
|
81
|
-
For binaural, also inspect `getDefaults().limits.spatialX` and `.spatialY`.
|
|
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.
|
|
82
69
|
|
|
83
70
|
## Binaural does not change the position
|
|
84
71
|
|
|
85
|
-
|
|
72
|
+
Inspect the options sent to the native method as well as the settings screen:
|
|
86
73
|
|
|
87
74
|
- Every effect that should be spatial sends `spatialX` and/or `spatialY`. A switch alone does not modify existing playback calls.
|
|
88
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.
|
|
@@ -90,110 +77,81 @@ Check the actual object sent to the native method, not only the settings screen:
|
|
|
90
77
|
- No stereo placement fields remain, even with value 0 or through pattern inheritance. Handle the Boolean return value.
|
|
91
78
|
- The installed contract reports both spatial limits and the device has the rebuilt app.
|
|
92
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.
|
|
93
|
-
-
|
|
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.
|
|
94
81
|
|
|
95
82
|
The [integration guide](guide.md#integrate-binaural-in-a-2d-app) contains the JavaScript conversion and explains switch/slider behavior.
|
|
96
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
|
+
|
|
97
102
|
## The first sound glitches
|
|
98
103
|
|
|
99
|
-
Do not start the engine during the first layout. Add the `postlayout` listener
|
|
100
|
-
before opening the window, debounce it for about 250 ms, and start after the
|
|
101
|
-
screen settles. Cancel the timer if the owner closes first. The complete code
|
|
102
|
-
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).
|
|
103
105
|
|
|
104
|
-
If startup remains noisy, temporarily remove other launch work and increase the
|
|
105
|
-
quiet period. Ads, animations, remote configuration and another audio module
|
|
106
|
-
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.
|
|
107
107
|
|
|
108
108
|
## The app is silent
|
|
109
109
|
|
|
110
110
|
Check these in order:
|
|
111
111
|
|
|
112
|
-
1. `
|
|
112
|
+
1. `start()` returned `true`.
|
|
113
113
|
2. The tone, chord or pattern call returned `true`.
|
|
114
114
|
3. Master and event `volume` are above zero.
|
|
115
115
|
4. The device media volume is up and the expected route is selected.
|
|
116
116
|
5. `shutdown()` was not called by another owner.
|
|
117
117
|
6. The note is within the current frequency range.
|
|
118
|
-
7. The app
|
|
119
|
-
replaced.
|
|
120
|
-
|
|
121
|
-
On iOS, the module uses a `Playback` session by default, so the silent switch
|
|
122
|
-
should not mute it. With `audioSession: 'ambient'` the silent switch mutes it by
|
|
123
|
-
design. Another audio component can change the app-wide session after engine
|
|
124
|
-
startup; inspect the order if behavior differs from the simple example.
|
|
125
|
-
|
|
126
|
-
## A pattern stops or skips steps
|
|
127
|
-
|
|
128
|
-
Only one pattern is pending. A new `playPattern()` call cancels steps from the
|
|
129
|
-
previous scheduler that have not fired. Voices already on the audio thread keep
|
|
130
|
-
playing.
|
|
118
|
+
7. The app retained the positive sequence identifier and checked publication acceptance.
|
|
131
119
|
|
|
132
|
-
`
|
|
133
|
-
`shutdown()` when both active audio and future scheduling must end, or replace
|
|
134
|
-
the pattern deliberately before stopping its current voices.
|
|
135
|
-
|
|
136
|
-
Make sure every step is an object and has exactly one pitch source:
|
|
137
|
-
|
|
138
|
-
```javascript
|
|
139
|
-
steps: [
|
|
140
|
-
{ note: 'C4' },
|
|
141
|
-
{ rest: true },
|
|
142
|
-
{ frequency: 660 }
|
|
143
|
-
]
|
|
144
|
-
```
|
|
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.
|
|
145
121
|
|
|
146
|
-
##
|
|
122
|
+
## A sequence stops or skips steps
|
|
147
123
|
|
|
148
|
-
|
|
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.
|
|
149
125
|
|
|
150
|
-
|
|
151
|
-
2. The listener is on the module (`synth.addEventListener`), registered before
|
|
152
|
-
the pattern started and not removed by a cleanup that already ran.
|
|
153
|
-
3. `shutdown()` was not called first. It discards a pending pattern silently.
|
|
154
|
-
4. The pattern was not replaced. A newer accepted pattern delivers
|
|
155
|
-
`completed: false` for the old one instead of a natural end.
|
|
126
|
+
## `sequenceend` never arrives
|
|
156
127
|
|
|
157
|
-
The event
|
|
158
|
-
lengths, not when you call. A 30 second pattern reports after 30 seconds.
|
|
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.
|
|
159
129
|
|
|
160
130
|
## A chord is distorted or pumps
|
|
161
131
|
|
|
162
|
-
Use one `playChord()` call for notes that should begin together. Several
|
|
163
|
-
`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.
|
|
164
133
|
|
|
165
134
|
If the limiter engages repeatedly:
|
|
166
135
|
|
|
167
136
|
- lower event volume;
|
|
168
|
-
- lower `filterQ`, because a resonant low-pass or high-pass boosts its cutoff
|
|
169
|
-
by about Q;
|
|
137
|
+
- lower `filterQ`, because a resonant low-pass or high-pass boosts its cutoff by about Q;
|
|
170
138
|
- use `conservative` instead of `balanced` or `raw`;
|
|
171
139
|
- use `speakerSafe` on a small speaker;
|
|
172
140
|
- avoid retriggering a long event before its previous release ends.
|
|
173
141
|
|
|
174
|
-
A repeating overlap test is expected to change the summed level. Judge tonal
|
|
175
|
-
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.
|
|
176
143
|
|
|
177
144
|
## The phone speaker buzzes but headphones are clean
|
|
178
145
|
|
|
179
|
-
|
|
180
|
-
`speakerSafe`, lower the event level, shorten low-frequency energy, or move the
|
|
181
|
-
important pitch above roughly 200 Hz. A digital limiter cannot make a tiny
|
|
182
|
-
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.
|
|
183
147
|
|
|
184
|
-
Compare several devices before changing the synthesis globally. A resonance on
|
|
185
|
-
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.
|
|
186
149
|
|
|
187
150
|
## Audio changes after connecting headphones
|
|
188
151
|
|
|
189
|
-
Route recovery is automatic, but the sound crossing the hardware transition
|
|
190
|
-
may end early. The operating system can also mute or fade the new route for a
|
|
191
|
-
brief device-dependent interval. Wait for the route to settle and play a new
|
|
192
|
-
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.
|
|
193
153
|
|
|
194
|
-
If later sounds remain silent, capture the Android or Xcode log around the route
|
|
195
|
-
change. Confirm that no screen lifecycle handler called `shutdown()` at the same
|
|
196
|
-
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.
|
|
197
155
|
|
|
198
156
|
## Android-specific checks
|
|
199
157
|
|
|
@@ -212,8 +170,38 @@ time.
|
|
|
212
170
|
|
|
213
171
|
## What to include in a bug report
|
|
214
172
|
|
|
215
|
-
Include the platform, OS version, device model, Titanium SDK version, module
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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.
|