@maccesar/titools 4.16.3 → 4.17.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.
@@ -0,0 +1,162 @@
1
+ > Source snapshot: official TiSynthEngine 1.0.0 documentation at commit `6685b81` (2026-08-29).
2
+
3
+ # Troubleshooting
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.
8
+
9
+ ## A call returns `false`
10
+
11
+ Look for a structured warning in logcat or the Xcode console:
12
+
13
+ ```text
14
+ event=validation_warning method=playPattern key=steps reason=invalid_step_type action=rejected value=C4
15
+ ```
16
+
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. |
29
+
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.
32
+
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.
36
+
37
+ ## The installed contract is wrong
38
+
39
+ Check the native binary at startup:
40
+
41
+ ```javascript
42
+ var actual = synth.getDefaults().apiVersion
43
+ if (actual !== '1.0.0') {
44
+ throw new Error('Expected TiSynthEngine 1.0.0, found ' + actual)
45
+ }
46
+ ```
47
+
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:
51
+
52
+ ```text
53
+ modules/android/ti.synthengine/1.0.0/
54
+ modules/iphone/ti.synthengine/1.0.0/
55
+ ```
56
+
57
+ ## The first sound glitches
58
+
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).
63
+
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.
67
+
68
+ ## The app is silent
69
+
70
+ Check these in order:
71
+
72
+ 1. `startEngine()` returned `true`.
73
+ 2. The tone, chord or pattern call returned `true`.
74
+ 3. Master and event `volume` are above zero.
75
+ 4. The device media volume is up and the expected route is selected.
76
+ 5. `shutdown()` was not called by another owner.
77
+ 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.
80
+
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.
84
+
85
+ ## A pattern stops or skips steps
86
+
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.
90
+
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.
94
+
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
+ ```
104
+
105
+ ## A chord is distorted or pumps
106
+
107
+ Use one `playChord()` call for notes that should begin together. Several
108
+ `playTone()` calls have independent source gain and produce a hotter sum.
109
+
110
+ If the limiter engages repeatedly:
111
+
112
+ - lower event volume;
113
+ - use `conservative` instead of `balanced` or `raw`;
114
+ - use `speakerSafe` on a small speaker;
115
+ - avoid retriggering a long event before its previous release ends.
116
+
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.
119
+
120
+ ## The phone speaker buzzes but headphones are clean
121
+
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.
126
+
127
+ Compare several devices before changing the synthesis globally. A resonance on
128
+ one handset may not exist on another.
129
+
130
+ ## Audio changes after connecting headphones
131
+
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.
136
+
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.
140
+
141
+ ## Android-specific checks
142
+
143
+ - Force-stop stale builds and other audio-heavy apps before comparing runs.
144
+ - Confirm the device ABI exists in the installed module archive.
145
+ - Capture logcat for Oboe stream errors and reopen messages.
146
+ - Test the release build as well as a debug build; startup load can differ.
147
+ - Treat background and screen-off playback as a product-specific device test.
148
+
149
+ ## iOS-specific checks
150
+
151
+ - Confirm the deployment target is iOS 13 or newer.
152
+ - Check whether another module changes `AVAudioSession` after startup.
153
+ - Test interruptions, phone calls, Bluetooth and route changes on hardware.
154
+ - Use the matching device or simulator slice from the 1.0.0 archive.
155
+
156
+ ## What to include in a bug report
157
+
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.