@maccesar/titools 5.2.5 → 5.4.0
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 +1 -1
- package/README.md +58 -97
- package/agents/ti-pro.md +4 -2
- package/commands/ti-audit.md +7 -5
- package/docs/examples.md +24 -13
- package/docs/knowledge-index.md +2 -1
- package/lib/config.js +1 -0
- package/package.json +1 -1
- package/skills/alloy-guides/SKILL.md +18 -179
- package/skills/alloy-guides/references/CLI_TASKS.md +17 -216
- package/skills/alloy-guides/references/CONCEPTS.md +27 -162
- package/skills/alloy-guides/references/CONTROLLERS.md +38 -236
- package/skills/alloy-guides/references/MODELS.md +47 -723
- package/skills/alloy-guides/references/MODELS_ADVANCED.md +21 -482
- package/skills/alloy-guides/references/VIEWS_DYNAMIC.md +12 -222
- package/skills/alloy-guides/references/VIEWS_STYLES.md +39 -358
- package/skills/alloy-guides/references/VIEWS_XML.md +36 -552
- package/skills/alloy-guides/references/WIDGETS.md +49 -127
- package/skills/alloy-howtos/SKILL.md +14 -169
- package/skills/alloy-howtos/references/best_practices.md +9 -113
- package/skills/alloy-howtos/references/cli_reference.md +18 -223
- package/skills/alloy-howtos/references/config_files.md +50 -133
- package/skills/alloy-howtos/references/debugging_troubleshooting.md +19 -63
- package/skills/alloy-howtos/references/samples.md +21 -138
- package/skills/ti-api/SKILL.md +10 -2
- package/skills/ti-api/references/api-android.md +36 -2
- package/skills/ti-api/references/api-app-platform.md +39 -3
- package/skills/ti-api/references/api-core.md +50 -18
- package/skills/ti-api/references/api-data-network.md +49 -35
- package/skills/ti-api/references/api-media.md +45 -27
- package/skills/ti-api/references/api-services.md +39 -9
- package/skills/ti-api/references/api-ui-android.md +33 -13
- package/skills/ti-api/references/api-ui-extras.md +41 -15
- package/skills/ti-api/references/api-ui-ios-animator.md +42 -26
- package/skills/ti-api/references/api-ui-ios.md +74 -2
- package/skills/ti-api/references/api-ui-lists.md +32 -16
- package/skills/ti-api/references/api-ui-text-input.md +34 -17
- package/skills/ti-api/references/api-ui-views.md +27 -1
- package/skills/ti-api/references/api-ui-windows-navigation.md +32 -18
- package/skills/ti-api/references/api-xml-global.md +66 -16
- package/skills/ti-create-release/SKILL.md +98 -0
- package/skills/ti-create-release/references/module-discovery.md +69 -0
- package/skills/ti-expert/references/adaptive-layouts.md +1 -1
- package/skills/ti-guides/SKILL.md +37 -76
- package/skills/ti-guides/references/advanced-data-and-images.md +122 -126
- package/skills/ti-guides/references/android-manifest.md +24 -83
- package/skills/ti-guides/references/app-distribution.md +31 -377
- package/skills/ti-guides/references/application-frameworks.md +127 -335
- package/skills/ti-guides/references/cli-reference.md +184 -633
- package/skills/ti-guides/references/commonjs-advanced.md +81 -231
- package/skills/ti-guides/references/compatibility-matrix.md +36 -75
- package/skills/ti-guides/references/hello-world.md +95 -70
- package/skills/ti-guides/references/hyperloop-native-access.md +52 -448
- package/skills/ti-guides/references/resources.md +174 -142
- package/skills/ti-guides/references/sdk-release-notes.md +28 -71
- package/skills/ti-guides/references/tiapp-config.md +222 -598
- package/skills/ti-howtos/SKILL.md +23 -123
- package/skills/ti-howtos/references/cross-platform-development.md +119 -324
- package/skills/ti-howtos/references/debugging-profiling.md +77 -445
- package/skills/ti-howtos/references/extending-titanium.md +199 -673
- package/skills/ti-howtos/references/local-data-sources.md +87 -300
- package/skills/ti-howtos/references/location-and-maps.md +86 -213
- package/skills/ti-howtos/references/media-apis.md +103 -223
- package/skills/ti-howtos/references/notification-services.md +86 -506
- package/skills/ti-howtos/references/remote-data-sources.md +97 -316
- package/skills/ti-howtos/references/using-modules.md +77 -133
- package/skills/ti-synthengine/SKILL.md +62 -111
- package/skills/ti-synthengine/assets/example/README.md +50 -59
- package/skills/ti-synthengine/assets/example/app.js +67 -65
- package/skills/ti-synthengine/assets/example/lib/sequenceOwner.js +39 -40
- package/skills/ti-synthengine/assets/example/lib/soundPreset.js +34 -0
- package/skills/ti-synthengine/assets/index.d.ts +122 -2
- package/skills/ti-synthengine/references/advanced-examples.md +4 -4
- package/skills/ti-synthengine/references/api.md +40 -18
- package/skills/ti-synthengine/references/audio-engine.md +15 -57
- package/skills/ti-synthengine/references/examples.md +63 -6
- package/skills/ti-synthengine/references/guide.md +61 -57
- package/skills/ti-synthengine/references/instruments-and-effects.md +15 -15
- package/skills/ti-synthengine/references/native-variation.md +53 -14
- package/skills/ti-synthengine/references/recipes-interaction.md +25 -20
- package/skills/ti-synthengine/references/recipes.md +19 -16
- package/skills/ti-synthengine/references/recommendations.md +12 -12
- package/skills/ti-synthengine/references/sound-api.md +197 -0
- package/skills/ti-synthengine/references/sound-design.md +7 -7
- package/skills/ti-synthengine/references/source-notes.md +62 -172
- package/skills/ti-synthengine/references/troubleshooting.md +17 -19
- package/skills/ti-synthengine/references/upgrade-2.0.0.md +40 -0
- package/skills/ti-ui/SKILL.md +28 -143
- package/skills/ti-ui/references/icons-and-splash-screens.md +74 -403
- package/skills/ti-ui/references/layouts-and-positioning.md +175 -402
- package/skills/ti-ui/references/listviews-and-performance.md +100 -703
- package/skills/ti-ui/references/platform-conventions.md +180 -0
- package/skills/ti-ui/references/user-interface.md +43 -0
- package/skills/alloy-guides/references/VIEWS_WITHOUT_CONTROLLERS.md +0 -102
- package/skills/alloy-howtos/references/custom_tags.md +0 -148
- package/skills/ti-guides/references/coding-best-practices.md +0 -149
- package/skills/ti-guides/references/javascript-primer.md +0 -414
- package/skills/ti-guides/references/reserved-words.md +0 -36
- package/skills/ti-guides/references/style-and-conventions.md +0 -103
- package/skills/ti-howtos/references/android-platform-deep-dives.md +0 -624
- package/skills/ti-howtos/references/automation-fastlane-appium.md +0 -96
- package/skills/ti-howtos/references/buffer-codec-streams.md +0 -162
- package/skills/ti-howtos/references/google-maps-v2.md +0 -172
- package/skills/ti-howtos/references/ios-map-kit.md +0 -149
- package/skills/ti-howtos/references/ios-platform-deep-dives.md +0 -611
- package/skills/ti-howtos/references/tutorials.md +0 -565
- package/skills/ti-howtos/references/web-content-integration.md +0 -287
- package/skills/ti-howtos/references/webpack-build-pipeline.md +0 -124
- package/skills/ti-synthengine/references/android-sim80-correction-evidence.zip +0 -0
- package/skills/ti-synthengine/references/android-sim80-correction.json +0 -162
- package/skills/ti-synthengine/references/audio-pipeline-validation.md +0 -19
- package/skills/ti-synthengine/references/bypass-physical-recheck-evidence.zip +0 -0
- 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 +0 -1918
- package/skills/ti-synthengine/references/native-tone-repetition-validation.md +0 -59
- package/skills/ti-synthengine/references/native-variation-proposal.md +0 -182
- package/skills/ti-synthengine/references/native-variation-validation.md +0 -63
- package/skills/ti-synthengine/references/performance-review-evidence.zip +0 -0
- package/skills/ti-synthengine/references/performance-review.json +0 -1146
- package/skills/ti-synthengine/references/physical-validation.json +0 -1457
- package/skills/ti-synthengine/references/source-snapshot.json +0 -542
- package/skills/ti-synthengine/references/stats-performance.json +0 -2992
- package/skills/ti-synthengine/references/stats-performance.md +0 -82
- package/skills/ti-synthengine/references/studio-validation.json +0 -6202
- package/skills/ti-synthengine/references/unified-bypass-performance.json +0 -22425
- package/skills/ti-synthengine/references/unified-validation.json +0 -314
- package/skills/ti-ui/references/accessibility-deep-dive.md +0 -288
- package/skills/ti-ui/references/animation-and-matrices.md +0 -569
- package/skills/ti-ui/references/application-structures.md +0 -626
- package/skills/ti-ui/references/custom-fonts-styling.md +0 -549
- package/skills/ti-ui/references/event-handling.md +0 -401
- package/skills/ti-ui/references/gestures.md +0 -448
- package/skills/ti-ui/references/orientation.md +0 -374
- package/skills/ti-ui/references/platform-ui-android.md +0 -727
- package/skills/ti-ui/references/platform-ui-ios.md +0 -576
- package/skills/ti-ui/references/scrolling-views.md +0 -288
- package/skills/ti-ui/references/tableviews.md +0 -542
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
> Source snapshot: official TiSynthEngine documentation at commit `
|
|
1
|
+
> Source snapshot: official TiSynthEngine documentation at commit `9d74aa45f84d3f2822d4aab76874efe37d81257f` (2026-11-03). Module 2.0.0. Upstream `documentation/audio-engine.md` SHA-256: `d5cabb81a1f36d4f32d13d8a03bd492a73c3e34c1c0888bb8af9dfa15a4e4d41`.
|
|
2
2
|
|
|
3
3
|
# Audio engine
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This reference explains how the native signal path, mixing profiles and voice capacity affect the output. Use it to choose those settings or investigate device behavior. It is optional for basic playback.
|
|
6
6
|
|
|
7
7
|
<!-- TOC-START -->
|
|
8
8
|
## Contents
|
|
@@ -29,7 +29,7 @@ The native signal path explains how mixing profiles and voice capacity affect th
|
|
|
29
29
|
- [Sustained voices](#sustained-voices)
|
|
30
30
|
- [Native transport and processing](#native-transport-and-processing)
|
|
31
31
|
- [Unified transport acceptance boundaries](#unified-transport-acceptance-boundaries)
|
|
32
|
-
- [Native finite-tone repetition
|
|
32
|
+
- [Native finite-tone repetition](#native-finite-tone-repetition)
|
|
33
33
|
|
|
34
34
|
<!-- TOC-END -->
|
|
35
35
|
|
|
@@ -79,7 +79,7 @@ The source is optionally quantized to the selected `bitDepth` (2 to 16 bits) and
|
|
|
79
79
|
|
|
80
80
|
A `SINE` voice with a positive `fmDepth`, or with `fmDepthEnd`, is phase modulated: the carrier computes `sin(2 * pi * phase + depth * sin(2 * pi * modPhase))`. The modulator phase advances by the carrier's instantaneous phase increment times `fmRatio`, so pitch sweeps and vibrato keep the ratio. The index moves linearly from `fmDepth` to `fmDepthEnd` over the event. With a depth of exactly 0 and no end, the voice takes the plain sine path.
|
|
81
81
|
|
|
82
|
-
The modulated sine has constant amplitude, so event gain is unchanged.
|
|
82
|
+
The modulated sine has constant amplitude, so event gain is unchanged. The sidebands are not band-limited; a high carrier with a large index aliases.
|
|
83
83
|
|
|
84
84
|
### State-variable filter
|
|
85
85
|
|
|
@@ -177,11 +177,11 @@ Both ports use a 128-slot single-consumer ring buffer. Producers are serialized
|
|
|
177
177
|
|
|
178
178
|
## Shared DSP core
|
|
179
179
|
|
|
180
|
-
The envelope,
|
|
180
|
+
The envelope, state-variable filter, sweep helpers, FM sine and cents conversion share one implementation in `shared/synth_core.h`. It is plain C, header-only and allocation-free. The Android renderer includes it from `android/jni/SynthOboeEngine.cpp` and the iOS renderer from `ios/Classes/TiSynthengineModule.m`, so both platforms run the same code. Backend voice integration and mixing remain separate per platform. Master ramps and final stereo protection share `shared/synth_output.h`. Held envelopes/ramps, transport, master effects, extra modulation and compatible retrigger support also have shared C cores.
|
|
181
181
|
|
|
182
182
|
## Native per-attack variation
|
|
183
183
|
|
|
184
|
-
|
|
184
|
+
TiSynth supports optional `sound.variation` on new attacks. Check both `capabilities.variation === true` and `variationSchemaVersion === 1`, then select bounded values at admitted attacks. The chosen configuration stays stable during that voice; existing sweeps, envelopes and explicit live edits keep their normal roles. Parsing prepares fixed-size state outside audio; the callback uses bounded shared arithmetic without allocation or locks. See [native variation](native-variation.md) for supported locations, source constraints, inheritance and seeds, and [technical verification](https://github.com/macCesar/TiSynthEngine/blob/9d74aa45f84d3f2822d4aab76874efe37d81257f/documentation/native-variation-validation.md) for measured compatibility and limits.
|
|
185
185
|
|
|
186
186
|
## Android implementation
|
|
187
187
|
|
|
@@ -201,7 +201,7 @@ The module targets iOS 15 or newer. The module archive contains device, simulato
|
|
|
201
201
|
|
|
202
202
|
## Latency
|
|
203
203
|
|
|
204
|
-
The final output stage retains zero samples
|
|
204
|
+
The final output stage retains zero samples. End-to-end latency still includes the hardware and operating-system output buffers, route transport (including Bluetooth), and JavaScript publication plus callback-boundary latency for a newly submitted event. Accepted sequence steps then follow the sample clock. Attack envelopes and spatial/effect processing retain their existing timing.
|
|
205
205
|
|
|
206
206
|
Android reports a valid timestamp-based stream-to-DAC estimate without adding the former lookahead. Unavailable estimates remain `null`; this iOS backend continues to report `null`.
|
|
207
207
|
|
|
@@ -296,53 +296,11 @@ Android ARM64 reuses coefficients across eight consecutive samples, with four-sa
|
|
|
296
296
|
|
|
297
297
|
## Own-platform performance verification
|
|
298
298
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
The [performance review](performance-review.json) separates measured host improvements, exact compatibility checks and pending device acceptance. Its [raw evidence](performance-review-evidence.zip) retains rejected prototypes and the investigation of idle/stereo regressions. The Apple FIR, stable-control cache and exact idle-effects bypass were evaluated as one atomic candidate and then rejected after physical 32-stereo timing regressed. All three production changes were removed together; the full-score publication and control-memory fixes remain.
|
|
302
|
-
|
|
303
|
-
Matched 48 kHz/1024-frame iPad full-load runs completed 600 audio seconds without callback deadline misses, with p95 load upper bounds 0.427 for the reference and 0.383 for the rejected initial candidate. The original Apple callback was restored because 32-stereo bypass p95 regressed reproducibly, including continuous-voice windows. Android Sim20/Sim80 frame presentation remains near 60 FPS, while occasional Sim80 output underruns persist in both versions. Compact 48 kHz iPad memory growth is about 18.2 MiB in both versions; no material RAM saving or physical 192 kHz acceptance is claimed. These results and qualified listening observations are recorded separately in the review.
|
|
304
|
-
|
|
305
|
-
`tools/build_ios_render_host.py` compiles the actual Objective-C render-block body and voice/transport helpers on macOS. It replaces hardware/session/Titanium startup and fixes only the noise-seed/disabled-diagnostic clock. Output and semantic state are compared against a separately archived reference from the same platform. This is an Apple renderer test; it does not execute AVAudioEngine or establish iPad scheduling, route recovery, footprint or listening acceptance.
|
|
306
|
-
|
|
307
|
-
The commands below reproduce the historical pre-pipeline performance review. Use its archived candidate source when requiring exact PCM/state equality with `7ab3110`; the renderer since 1.0.2 intentionally removes the old final-output delay and changes overload behavior, so it cannot satisfy that earlier exact-output comparison. For the later correction, use the [audio pipeline validation](audio-pipeline-validation.md) protocol: align only the former output delay, compare no-overload PCM within the declared tolerance, and retain overload differences separately. The module's `tools/compare_output_pcm.py` checks the corresponding matched Android/Apple capture sets; host comparisons do not establish physical output latency.
|
|
308
|
-
|
|
309
|
-
```sh
|
|
310
|
-
mkdir -p /tmp/synth-reference
|
|
311
|
-
git archive 7ab3110 | tar -x -C /tmp/synth-reference
|
|
312
|
-
python3 tools/build_ios_render_host.py --source /tmp/synth-reference --output /tmp/apple-reference
|
|
313
|
-
python3 tools/build_ios_render_host.py --output /tmp/apple-candidate
|
|
314
|
-
python3 tools/compare_ios_render.py /tmp/apple-reference /tmp/apple-candidate
|
|
315
|
-
python3 tools/benchmark_performance_review.py --baseline /tmp/apple-reference --candidate /tmp/apple-candidate --output /tmp/apple-performance.json
|
|
316
|
-
/tmp/apple-candidate --metadata
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
The build tool defaults to the module's Apple Release `-Os` optimization. The comparator streams PCM for every fixture block and full original voice/tail, FIR/filter, limiter, effect-buffer and transport state at fixture checkpoints. Cases include five engine rates, zero/short/irregular blocks, all sources, held updates, replacements, send and position ramps, four sequences, effects, panic, drain and later re-enabling. A deliberately changed phase increment was rejected as a negative control.
|
|
320
|
-
|
|
321
|
-
Finish compilation and fidelity checks before timing. The benchmark uses fixed matched warmups and at least ten alternating pairs; CPU and elapsed totals, p95, maxima and process high-water memory remain separate. Investigate repeatable total regressions above 2% or p95 regressions above 5%. Short-process or single-kernel gains do not establish whole-app performance. The Android producer harness exercises the actual JNI publication with supplied JVM array accessors, so its numbers exclude Java validation and VM allocation time.
|
|
322
|
-
|
|
323
|
-
Full-score producers reserve a free bank without copying the previous score. Generic partial-bank callers still inherit the latest accepted bank, and publication retains its ownership, validation and mailbox checks. The iOS producer commits an already prepared score once; Android prepares its complete packet at native publication. Empty completion polls and empty metadata pruning avoid transient objects. Accepted edits of unknown iOS IDs do not create retained spatial metadata. Sequence capacity, diagnostics, event delivery cadence and public defaults are unchanged.
|
|
324
|
-
|
|
325
|
-
The shared processor check is `cc -std=c99 -O2 -Wall -Wextra -Wpedantic tests/spatial_regression.c -lm -o /tmp/spatial_regression` followed by `/tmp/spatial_regression`. `tests/spatial_engine_host.cpp` uses the same compile flags as `engine_render_host.cpp` and verifies native left/right rendering, elevation changes, stealing and stopping. Java spatial validation is checked by `SynthSpatialContractRegression`; the common Java/iOS corpus also covers spatial acceptance and conflicts.
|
|
326
|
-
|
|
327
|
-
### Reproduce a host CPU comparison
|
|
328
|
-
|
|
329
|
-
Compile `tests/spatial_benchmark_host.cpp` with the same Oboe/JDK includes and definitions as `engine_render_host.cpp` above, replacing the source filename and choosing an output such as `/tmp/spatial_benchmark`. Supply a whitespace-separated timeline, one event per line, with these 25 columns in order:
|
|
330
|
-
|
|
331
|
-
```text
|
|
332
|
-
timeMs frequency frequencyEnd durationMs attackMs releaseMs decayMs sustain waveType volume noiseRate noiseRateEnd lowPassHz pulseWidth lfoFreq lfoDepth filterTypeIndex filterHz filterHzEnd filterQ fmRatio fmDepth fmDepthEnd pan panEnd
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
The filter indices are 0=none, 1=lowpass, 2=highpass and 3=bandpass. This internal harness bypasses public contract validation, so only feed valid event recipes. In binaural mode every event uses its `pan` column as spatialX and a synthetic moving elevation `0.8 * sin(timeMs / 1000)`; the other pan column is irrelevant to that mode. This tests CPU, not the localization of the original timeline.
|
|
336
|
-
|
|
337
|
-
```sh
|
|
338
|
-
python3 tools/benchmark_spatial.py /tmp/spatial_benchmark /path/to/timeline.txt
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
The script compares stereo and binaural using a warmup and five measured trials, reporting the median by audio processing time. There is no hardware stream or JavaScript bridge. Results include peak level, non-finite/clipped frames, voice replacements and processing time; they do not measure device CPU, latency, underruns, heat or battery.
|
|
299
|
+
Source-specific measurements and reproduction commands are preserved in the [historical engine validation record](https://github.com/macCesar/TiSynthEngine/blob/9d74aa45f84d3f2822d4aab76874efe37d81257f/documentation/audio-engine-validation.md). Current Sound-interface acoustic and runtime checks are recorded in [Sound validation](https://github.com/macCesar/TiSynthEngine/blob/9d74aa45f84d3f2822d4aab76874efe37d81257f/documentation/sound-api-validation.md).
|
|
342
300
|
|
|
343
301
|
## Engine statistics
|
|
344
302
|
|
|
345
|
-
The [statistics API](api.md#getstats) has the same shape on both platforms. `shared/synth_stats.h` owns telemetry math and publication. Voice transitions update render-owned occupancy and maxima, including primary FIR draining and external replacement/stop tails.
|
|
303
|
+
The [statistics API](api.md#getstats) has the same shape on both platforms. `shared/synth_stats.h` owns telemetry math and publication. Voice transitions update render-owned occupancy and maxima, including primary FIR draining and external replacement/stop tails. The renderer can then skip whole empty groups without changing the signal. Producers are serialized separately from the renderer; querying queue depth does not include future scheduled pattern steps.
|
|
346
304
|
|
|
347
305
|
The callback publishes atomic words behind a sequence counter. Readers retry a snapshot if publication overlaps their read; the callback never waits for them. Eight-byte alignment and a compile-time lock-free assertion also cover Android's 32-bit ABIs. Reset/enable requests are consumed at callback boundaries. A new control generation hides stale optional measurements immediately. Shutdown waits for the backend callback to stop before clearing occupancy. Queries allocate result objects on the calling thread. Pattern publication and shutdown share a control monitor; that monitor is never taken by the audio callback.
|
|
348
306
|
|
|
@@ -358,7 +316,7 @@ python3 tests/run_stats_java.py
|
|
|
358
316
|
|
|
359
317
|
`tests/stats_engine_host.cpp` uses the Oboe/JDK host flags shown above. It tests native occupancy, reset while playing, saturated queues, binaural drain, shutdown and exact output equality with diagnostics enabled/disabled. CI obtains Oboe 1.11.0 headers and runs this native integration harness alongside the portable shared tests and stopped-engine Java API tests. iOS builds use the same telemetry core, but host Android renders do not execute the iOS audio callback.
|
|
360
318
|
|
|
361
|
-
`tests/stats_benchmark_host.cpp` extends the spatial replay harness with silence, one/32 voices, replacement pressure, chords, scheduled note publications and short FIR drains in stereo/binaural. Build it twice with identical `-O3` flags: once against the previous engine using `-DSTATS_BASELINE`, and once against the current engine. Run `python3 tools/benchmark_stats.py BASELINE CURRENT` for one warmup and ten alternating trials/configuration, including current snapshots at 5 Hz. The harness verifies identical output hashes across all modes. The [measured comparison and limitations](stats-performance.md) explain what the host percentages establish and which results still require device tests.
|
|
319
|
+
`tests/stats_benchmark_host.cpp` extends the spatial replay harness with silence, one/32 voices, replacement pressure, chords, scheduled note publications and short FIR drains in stereo/binaural. Build it twice with identical `-O3` flags: once against the previous engine using `-DSTATS_BASELINE`, and once against the current engine. Run `python3 tools/benchmark_stats.py BASELINE CURRENT` for one warmup and ten alternating trials/configuration, including current snapshots at 5 Hz. The harness verifies identical output hashes across all modes. The [measured comparison and limitations](https://github.com/macCesar/TiSynthEngine/blob/9d74aa45f84d3f2822d4aab76874efe37d81257f/documentation/stats-performance.md) explain what the host percentages establish and which results still require device tests.
|
|
362
320
|
|
|
363
321
|
## Sustained voices
|
|
364
322
|
|
|
@@ -379,18 +337,18 @@ Pre-limiter peak and maximum limiter reduction accumulate natively until reset,
|
|
|
379
337
|
|
|
380
338
|
Portable checks: compile and run `tests/sequence_core_regression.c`, `tests/effects_core_regression.c` and `tests/modulation_core_regression.c` with C11, optimization and libm. The transport test checks ten minutes at five sample rates against calculated event times, plus edits, swing, rests, chords and publication pressure. Effects tests check bypass, tails, panic, automation, memory and stability at 16, 44.1, 48, 96 and 192 kHz. On macOS, `tests/studio_contract_ios.m` validates the iOS configuration contract without Titanium.
|
|
381
339
|
|
|
382
|
-
`tools/calibrate_studio.py --studio-root PATH` measures the production Android callback; add `--platform ios` for the production Apple callback. The report covers each preset/scenario at 1, 2, 4, 8, 16 and 32 voices, including independent low/mid/high notes, grouped chords, coherent unisons and overlapping releases. Recommendations target −6 dBFS before protection (with 0.01 dB margin) using the maximum measured peak of the declared usual 1-8-voice configuration and the public voice-volume limit. Larger workloads are separate stress diagnostics. The tool reports fixed scalar recommendations and never edits Studio. Effects and additional LFOs are disabled, so recommendations do not guarantee headroom for other configurations. See [audio pipeline validation](audio-pipeline-validation.md).
|
|
340
|
+
`tools/calibrate_studio.py --studio-root PATH` measures the production Android callback; add `--platform ios` for the production Apple callback. The report covers each preset/scenario at 1, 2, 4, 8, 16 and 32 voices, including independent low/mid/high notes, grouped chords, coherent unisons and overlapping releases. Recommendations target −6 dBFS before protection (with 0.01 dB margin) using the maximum measured peak of the declared usual 1-8-voice configuration and the public voice-volume limit. Larger workloads are separate stress diagnostics. The tool reports fixed scalar recommendations and never edits Studio. Effects and additional LFOs are disabled, so recommendations do not guarantee headroom for other configurations. See [audio pipeline validation](https://github.com/macCesar/TiSynthEngine/blob/9d74aa45f84d3f2822d4aab76874efe37d81257f/documentation/audio-pipeline-validation.md).
|
|
383
341
|
|
|
384
342
|
Device feedback superseded that headroom target for Studio's initial Cristal preset: its fixed gain is restored to 1 because the calibrated setting made a fresh Android installation barely audible. This adds 10.83 dB without saturation or voice-count normalization. Three coherent factory notes remain below the limiter ceiling at maximum master; eight independent coherent notes can require limiting. The calibration recommendations remain recorded separately from this active preset exception.
|
|
385
343
|
|
|
386
|
-
The [Studio technical validation report](studio-validation.json) records the calibration and corrected full-chain host benchmark, including failed deadline acceptance and pending device checks. Its host performance result must not be presented as hardware realtime acceptance.
|
|
344
|
+
The [Studio technical validation report](https://github.com/macCesar/TiSynthEngine/blob/9d74aa45f84d3f2822d4aab76874efe37d81257f/docs/validation/studio-validation.json) records the calibration and corrected full-chain host benchmark, including failed deadline acceptance and pending device checks. Its host performance result must not be presented as hardware realtime acceptance.
|
|
387
345
|
|
|
388
346
|
## Unified transport acceptance boundaries
|
|
389
347
|
|
|
390
|
-
|
|
348
|
+
Source-specific measurements and reproduction commands are preserved in the [historical engine validation record](https://github.com/macCesar/TiSynthEngine/blob/9d74aa45f84d3f2822d4aab76874efe37d81257f/documentation/audio-engine-validation.md). Current Sound-interface acoustic and runtime checks are recorded in [Sound validation](https://github.com/macCesar/TiSynthEngine/blob/9d74aa45f84d3f2822d4aab76874efe37d81257f/documentation/sound-api-validation.md).
|
|
391
349
|
|
|
392
|
-
## Native finite-tone repetition
|
|
350
|
+
## Native finite-tone repetition
|
|
393
351
|
|
|
394
352
|
The shared C scheduler owns 32 repetition slots independently of sequence capacity. It retains fractional sample deadlines across normal and spatial render blocks. Each `repeatTone` attack emits the same finite-tone command used by a standalone `playTone`. The first attack starts at the first render opportunity, independent of tempo. Preallocated publication banks carry complete validated configurations; the callback allocates no memory, takes no producer locks and runs no JavaScript. Stop publication has a separate atomic path, so a full ordinary command queue cannot prevent cancellation at the next block.
|
|
395
353
|
|
|
396
|
-
Each repetition owns its variation stream and admitted-attack counter. Admission failure skips that attack without advancing variation or queuing catch-up work. Updates preserve the pending deadline and affect its attack; a new interval controls the subsequent gap. `stopTone` cancels only future attacks, leaving admitted finite tones to complete. Global stop, shutdown and destruction invalidate slots and pending edits.
|
|
354
|
+
Each repetition owns its variation stream and admitted-attack counter. Admission failure skips that attack without advancing variation or queuing catch-up work. Updates preserve the pending deadline and affect its attack; a new interval controls the subsequent gap. `stopTone` cancels only future attacks, leaving admitted finite tones to complete. Global stop, shutdown and destruction invalidate slots and pending edits. Historical measurements elsewhere on this page do not measure this scheduler. See [the public contract](api.md#finite-tone-repetition).
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
> Source snapshot: official TiSynthEngine documentation at commit `
|
|
1
|
+
> Source snapshot: official TiSynthEngine documentation at commit `9d74aa45f84d3f2822d4aab76874efe37d81257f` (2026-11-03). Published module 2.0.0. Upstream `documentation/examples.md` SHA-256: `ee8aed566a63062ae63ae78f0b96fa8d73c70ab2f50aed81081c26acc24718af`.
|
|
2
2
|
|
|
3
3
|
# Examples
|
|
4
4
|
|
|
5
|
-
Every snippet on this page uses the TiSynthEngine 1.1.0 contract. Unless a snippet includes startup code, it assumes the engine is already running.
|
|
6
|
-
|
|
7
5
|
Additional [curated recipes](recipes.md) provide application sound and interaction variants.
|
|
8
6
|
|
|
7
|
+
Every snippet on this page uses TiSynthEngine 2.0.0 (including its retained direct playback methods). Unless a snippet includes startup code, it assumes the engine is already running.
|
|
8
|
+
|
|
9
9
|
For interactive instruments and native processing, begin with [held motors](advanced-examples.md#sustained-game-motor), [native sequences](advanced-examples.md#native-sequence-with-chords-and-edits), [master processing](advanced-examples.md#chorus-delay-reverb-and-creative-saturation) or [two LFOs](advanced-examples.md#two-voice-lfos). Use matching official packages and check method availability before enabling a feature.
|
|
10
10
|
|
|
11
11
|
```javascript
|
|
@@ -13,14 +13,18 @@ var synth = require('ti.synthengine')
|
|
|
13
13
|
var contract = synth.getDefaults()
|
|
14
14
|
var WAVE = contract.waveTypes
|
|
15
15
|
|
|
16
|
-
if (contract.
|
|
17
|
-
throw new Error('TiSynthEngine
|
|
16
|
+
if (contract.version !== '2.0.0') {
|
|
17
|
+
throw new Error('TiSynthEngine 2.0.0 is required')
|
|
18
18
|
}
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
<!-- TOC-START -->
|
|
22
22
|
## Contents
|
|
23
23
|
|
|
24
|
+
- [Reuse a sound with different notes](#reuse-a-sound-with-different-notes)
|
|
25
|
+
- [Hold a note and release its control](#hold-a-note-and-release-its-control)
|
|
26
|
+
- [Repeat finite attacks](#repeat-finite-attacks)
|
|
27
|
+
- [Direct native parameter examples](#direct-native-parameter-examples)
|
|
24
28
|
- [Start once after layout](#start-once-after-layout)
|
|
25
29
|
- [Built-in waveforms](#built-in-waveforms)
|
|
26
30
|
- [Variable-rate filtered noise](#variable-rate-filtered-noise)
|
|
@@ -52,6 +56,59 @@ if (contract.apiVersion !== '1.1.0') {
|
|
|
52
56
|
|
|
53
57
|
<!-- TOC-END -->
|
|
54
58
|
|
|
59
|
+
## Reuse a sound with different notes
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
var bell = synth.createSound({
|
|
63
|
+
sound: { waveType: WAVE.SINE, volume: 0.25, attack: 5, release: 120 },
|
|
64
|
+
playback: { type: 'tone', notes: ['A4'], duration: 400 }
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
bell.play()
|
|
68
|
+
bell.play({ notes: ['C5'], volume: 0.15 })
|
|
69
|
+
bell.set({ sound: { volume: 0.2 } })
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Execution overrides leave the stored definition unchanged. `set()` validates an atomic revision for future executions. For an atomic chord, declare `playback.type: 'chord'` and supply a pitch array.
|
|
73
|
+
|
|
74
|
+
## Hold a note and release its control
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
var instrument = synth.createSound({
|
|
78
|
+
sound: { waveType: WAVE.TRIANGLE, volume: 0.2, attack: 8, release: 180 },
|
|
79
|
+
playback: { type: 'held', notes: ['C4'] }
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
var note = instrument.noteOn({ notes: ['E4'] })
|
|
83
|
+
if (note) {
|
|
84
|
+
note.update({ notes: ['G4'], volume: 0.15 })
|
|
85
|
+
note.noteOff()
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Keep each note control with its interaction owner. On a rejected release, retain it for bounded retry or owner shutdown. A control cannot act on a restarted engine.
|
|
90
|
+
|
|
91
|
+
## Repeat finite attacks
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
var shot = synth.createSound({
|
|
95
|
+
sound: { waveType: WAVE.SQUARE, volume: 0.1, attack: 2, release: 40 },
|
|
96
|
+
playback: { type: 'repeat', frequencies: [880], duration: 105, interval: 150 }
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
var firing = shot.play()
|
|
100
|
+
if (firing) {
|
|
101
|
+
firing.update({ interval: 120 })
|
|
102
|
+
firing.stop()
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The native clock schedules attacks. `stop()` cancels future attacks; admitted 105 ms attacks finish naturally. See [patterns](sound-api.md#patterns) for ordered scores, chords and rests, and [processing](sound-api.md#units-and-processing) for shared effects in milliseconds.
|
|
107
|
+
|
|
108
|
+
## Direct native parameter examples
|
|
109
|
+
|
|
110
|
+
The remaining recipes use the supported direct methods and their native parameter dictionaries. For reusable application sounds, store synthesis fields under `sound`, pitches/timing under `playback`, and use the controls above. The [Sound reference](sound-api.md) lists interpretation-specific restrictions; the [upgrade guide](upgrade-2.0.0.md) maps direct names and units.
|
|
111
|
+
|
|
55
112
|
## Start once after layout
|
|
56
113
|
|
|
57
114
|
```javascript
|
|
@@ -430,7 +487,7 @@ synth.playTone({
|
|
|
430
487
|
})
|
|
431
488
|
```
|
|
432
489
|
|
|
433
|
-
A fractional `fmRatio` puts the overtones between harmonics,
|
|
490
|
+
A fractional `fmRatio` puts the overtones between harmonics, giving the sound a metallic timbre. `fmDepthEnd: 0` lets the brightness die away completely.
|
|
434
491
|
|
|
435
492
|
## Wah and filtered laser
|
|
436
493
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
> Source snapshot: official TiSynthEngine documentation at commit `
|
|
1
|
+
> Source snapshot: official TiSynthEngine documentation at commit `9d74aa45f84d3f2822d4aab76874efe37d81257f` (2026-11-03). Published module 2.0.0. Upstream `documentation/guide.md` SHA-256: `873379c35afe13d947eaf3262e942884e7d1e6b572a7a7867e646f89c7fd1e0f`.
|
|
2
2
|
|
|
3
3
|
# Guide
|
|
4
4
|
|
|
@@ -28,40 +28,40 @@ Install TiSynthEngine, start it after layout settles, and release its native aud
|
|
|
28
28
|
- [Read engine statistics](#read-engine-statistics)
|
|
29
29
|
- [Next steps](#next-steps)
|
|
30
30
|
- [Diagnose mix headroom](#diagnose-mix-headroom)
|
|
31
|
-
- [Variation support
|
|
31
|
+
- [Variation support](#variation-support)
|
|
32
32
|
|
|
33
33
|
<!-- TOC-END -->
|
|
34
34
|
|
|
35
35
|
## Install the module
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Use matching Android/iOS 2.0.0 packages. Source builds produce these archives under `android/dist` and `ios/dist`:
|
|
38
38
|
|
|
39
|
-
- `ti.synthengine-android-
|
|
40
|
-
- `ti.synthengine-iphone-
|
|
39
|
+
- `ti.synthengine-android-2.0.0.zip`
|
|
40
|
+
- `ti.synthengine-iphone-2.0.0.zip`
|
|
41
41
|
|
|
42
42
|
Put the archives in the Titanium project root or install them through the Titanium CLI. Pin the same version for both platforms:
|
|
43
43
|
|
|
44
44
|
```xml
|
|
45
45
|
<modules>
|
|
46
|
-
<module platform="android" version="
|
|
47
|
-
<module platform="iphone" version="
|
|
46
|
+
<module platform="android" version="2.0.0">ti.synthengine</module>
|
|
47
|
+
<module platform="iphone" version="2.0.0">ti.synthengine</module>
|
|
48
48
|
</modules>
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
TiSynthEngine requires Titanium SDK 13.2.0.GA or newer. Android projects must compile against API 35 or newer. The iOS module requires iOS 15 or newer.
|
|
52
52
|
|
|
53
|
-
These declarations select version
|
|
53
|
+
These declarations select version 2.0.0. Check the [variation metadata](#variation-support) before using native attack variation.
|
|
54
54
|
|
|
55
55
|
## Load and verify the contract
|
|
56
56
|
|
|
57
|
-
Require the module once in the code that owns audio
|
|
57
|
+
Require the module once in the code that owns audio, and check the installed module `version` before starting. Check the [spatial limits](#detect-the-installed-feature) if the app needs spatial audio, and the [statistics methods](#read-engine-statistics) if it needs statistics. For held voices, musical transport and master processing, check [required capabilities](#detect-required-capabilities).
|
|
58
58
|
|
|
59
59
|
```javascript
|
|
60
60
|
var synth = require('ti.synthengine')
|
|
61
|
-
var contract = synth.
|
|
61
|
+
var contract = synth.getContract()
|
|
62
62
|
|
|
63
|
-
if (contract.
|
|
64
|
-
throw new Error('TiSynthEngine
|
|
63
|
+
if (contract.version !== '2.0.0') {
|
|
64
|
+
throw new Error('TiSynthEngine 2.0.0 is required; found ' + contract.version)
|
|
65
65
|
}
|
|
66
66
|
```
|
|
67
67
|
|
|
@@ -115,47 +115,52 @@ Use one owner for the engine. Start it once, pass a small audio service to the s
|
|
|
115
115
|
|
|
116
116
|
## Detect required capabilities
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
TiSynth 2.0.0 supplies reusable sounds, held notes, patterns, repetitions and shared processing. Inspect `getContract().capabilities.soundObjects` and the documented property limits. The variation dictionary also uses `capabilities.variation` and `variationSchemaVersion`.
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
function hasMethods (names) {
|
|
122
|
-
return names.every(function (name) { return typeof synth[name] === 'function' })
|
|
123
|
-
}
|
|
124
|
-
var supportsHeld = hasMethods(['noteOn', 'noteOff', 'updateNote'])
|
|
125
|
-
var supportsSequence = hasMethods(['playSequence', 'updateSequence', 'stopSequence', 'getSequenceState'])
|
|
126
|
-
var supportsProcessing = hasMethods(['setMasterProcessing'])
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
Start the engine successfully before publishing held notes, sequence edits or processing. `getDefaults` and feature checks do not open the stream. Install matching packages for Android/iOS and rebuild the application when replacing a native module. Additional LFOs require the documented modulation contract; check acceptance of the complete configuration. Treat rejected configurations as unavailable. Do not silently drop their keys.
|
|
120
|
+
Start the engine successfully before publishing audio. Reading metadata and creating definitions do not open the stream. Rebuild the app after replacing a native module.
|
|
130
121
|
|
|
131
122
|
## Hold and edit a voice
|
|
132
123
|
|
|
133
|
-
|
|
124
|
+
Create a held definition when duration follows interaction. Each call returns its own control; keep it with the contact that started it.
|
|
134
125
|
|
|
135
|
-
|
|
126
|
+
```javascript
|
|
127
|
+
var instrument = synth.createSound({
|
|
128
|
+
sound: { waveType: contract.waveTypes.TRIANGLE, volume: 0.2, attack: 8, release: 180 },
|
|
129
|
+
playback: { type: 'held', notes: ['C4'] }
|
|
130
|
+
})
|
|
136
131
|
|
|
137
|
-
|
|
132
|
+
var note = instrument.noteOn({ notes: ['E4'] })
|
|
133
|
+
if (note) {
|
|
134
|
+
note.update({ volume: 0.15 })
|
|
135
|
+
note.noteOff()
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
Release on key up, touch cancellation, pause and owner close. Keep a rejected release retryable: retry at most twice at 16 ms, then shut down/report if it still fails. These timers recover lifecycle operations; they do not schedule musical attacks. Shutdown invalidates the control.
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
Compatible live updates use 10 ms transitions and retain phase and envelope. Waveform, table, filter type, ADSR, variation, bus and priority are fixed at attack. See [held fields](sound-api.md#held-notes). Chords played as independent held notes have independent gain and admission; use the chord interpretation for an atomic finite group.
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
## Choose the musical transport
|
|
144
|
+
|
|
145
|
+
Use `playback.type: 'tone'` or `'chord'` for finite events, `'held'` for interaction, `'repeat'` for repeated finite attacks and `'pattern'` for ordered scores. All share the configured pool of up to 32 voices. Startup `maxSequences` reserves one through four pattern slots.
|
|
144
146
|
|
|
145
147
|
```javascript
|
|
146
|
-
synth.setTempo(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
148
|
+
synth.setTempo(112)
|
|
149
|
+
|
|
150
|
+
var melody = synth.createSound({
|
|
151
|
+
sound: { waveType: contract.waveTypes.SQUARE, volume: 0.2, bus: 'music' },
|
|
152
|
+
playback: {
|
|
153
|
+
type: 'pattern', interval: 0.5, swing: 0.12,
|
|
154
|
+
steps: [{ notes: [60] }, { notes: [64], sound: { pan: -0.4, panEnd: 0.4 } },
|
|
155
|
+
{ rest: true }, { notes: [67], interval: 1, length: 0.8 }]
|
|
156
|
+
}
|
|
152
157
|
})
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
158
|
+
|
|
159
|
+
var pattern = melody.play()
|
|
160
|
+
if (pattern) pattern.stop()
|
|
156
161
|
```
|
|
157
162
|
|
|
158
|
-
|
|
163
|
+
Pattern controls provide `update()`, `stop()`, `getState()` and an `end` event. Updates preserve native revision scheduling. Beat patterns follow global tempo; millisecond patterns keep fixed times. Stopping releases that pattern's voices and leaves processing tails. A repetition's `stop()` cancels future attacks while admitted finite attacks finish. See [controls and timing](sound-api.md#patterns).
|
|
159
164
|
|
|
160
165
|
## Add master effects
|
|
161
166
|
|
|
@@ -163,26 +168,25 @@ The native chain is voices, fixed input gain, chorus, ping-pong delay, stereo Sc
|
|
|
163
168
|
|
|
164
169
|
Chorus adds stereo movement, delay adds free or synchronized echoes, and reverb adds a damped tail. Saturation is optional creative drive. Select processed categories with `applyTo: ['music', 'ambience']`; a voice's explicit `effectSend` overrides that selection. One chain processes the selected share and one final limiter protects the recombined output.
|
|
165
170
|
|
|
166
|
-
`
|
|
171
|
+
`setProcessing()` merges partial updates, validates the entire result and returns publication acceptance. Delay `time` and reverb `decay` use milliseconds. Continuous controls ramp over 10 ms. Disabling an effect closes input gradually and keeps its tail, bounded to 30 seconds with a final fade, then restores exact bypass. It does not undo a non-unity input gain. `stopAll` invalidates histories and stops every native sequence; `shutdown` stops the stream and frees its buffers. See the [processing example](advanced-examples.md#chorus-delay-reverb-and-creative-saturation) and [field ranges](api.md#setmasterprocessingoptions).
|
|
167
172
|
|
|
168
173
|
Delay and LFO sync follow global `setTempo` (initially 120); free settings retain milliseconds or hertz. The two extra voice LFOs target filter cutoff, square PWM or sine FM, with sine/triangle waves. They are independent of `lfoFreq`/`lfoDepth` pitch vibrato. See [two LFOs](advanced-examples.md#two-voice-lfos).
|
|
169
174
|
|
|
170
175
|
## Play the first sound
|
|
171
176
|
|
|
172
177
|
```javascript
|
|
173
|
-
var
|
|
174
|
-
|
|
175
|
-
duration: 300
|
|
176
|
-
attack: 8,
|
|
177
|
-
release: 80,
|
|
178
|
-
volume: 0.8,
|
|
179
|
-
waveType: contract.waveTypes.SINE
|
|
178
|
+
var bell = synth.createSound({
|
|
179
|
+
sound: { waveType: contract.waveTypes.SINE, volume: 0.25, attack: 8, release: 80 },
|
|
180
|
+
playback: { type: 'tone', notes: ['A4'], duration: 300 }
|
|
180
181
|
})
|
|
181
182
|
|
|
182
|
-
|
|
183
|
+
bell.play()
|
|
184
|
+
bell.play({ notes: ['C5'] })
|
|
183
185
|
```
|
|
184
186
|
|
|
185
|
-
|
|
187
|
+
A finite tone returns acceptance and finishes naturally. The same reusable definition can receive temporary pitch or synthesis overrides. Use `bell.set({ sound: { volume: 0.2 } })` to change future executions; `bell.getPreset()` returns an independent copy.
|
|
188
|
+
|
|
189
|
+
The sections below explain the direct native parameter dictionaries for shaping and spatial conversion. Those methods remain supported in 2.0.0. New application code can use the same synthesis fields under `sound` and pitches/timing under `playback`; see [Sound properties](sound-api.md#property-allowlists).
|
|
186
190
|
|
|
187
191
|
## Choose a pitch
|
|
188
192
|
|
|
@@ -323,7 +327,7 @@ synth.playTone({
|
|
|
323
327
|
})
|
|
324
328
|
```
|
|
325
329
|
|
|
326
|
-
For a caller-defined repeating shape, select `WAVETABLE` and provide 2 to 64 samples from -1 to 1. The table
|
|
330
|
+
For a caller-defined repeating shape, select `WAVETABLE` and provide 2 to 64 samples from -1 to 1. The table uses stepped lookup without interpolation.
|
|
327
331
|
|
|
328
332
|
```javascript
|
|
329
333
|
synth.playTone({
|
|
@@ -552,7 +556,7 @@ Measure CPU cost on the intended device with realistic event overlap. The cost d
|
|
|
552
556
|
|
|
553
557
|
## Read engine statistics
|
|
554
558
|
|
|
555
|
-
Basic counters are available without enabling optional diagnostics. Reads do not start audio or reset counters.
|
|
559
|
+
Basic counters are available without enabling optional diagnostics. Reads do not start audio or reset counters. The diagnostic controls are:
|
|
556
560
|
|
|
557
561
|
```javascript
|
|
558
562
|
var statsTimer = null
|
|
@@ -590,7 +594,7 @@ if (statsSupported) readStats()
|
|
|
590
594
|
|
|
591
595
|
Integrate `stopDiagnostics()` into the existing owner's hide/background/close handlers, before shutdown. Resume polling only while the diagnostic view is active; do not add a second engine owner. Timing and output meters stay `null` until enabled and measured. Basic counters remain available when diagnostics are off. Android backend underrun/buffer/latency fields are best-effort and independent of that switch; iOS returns `null` for those backend fields. A zero underrun count does not prove clean sound.
|
|
592
596
|
|
|
593
|
-
See the [complete field contract](api.md#getstats), [measurement limits](stats-performance.md) and [interactive statistics controls](../assets/example/README.md#statistics).
|
|
597
|
+
See the [complete field contract](api.md#getstats), [measurement limits](https://github.com/macCesar/TiSynthEngine/blob/9d74aa45f84d3f2822d4aab76874efe37d81257f/documentation/stats-performance.md) and [interactive statistics controls](../assets/example/README.md#statistics).
|
|
594
598
|
|
|
595
599
|
## Next steps
|
|
596
600
|
|
|
@@ -608,15 +612,15 @@ Fixed event/input gain does not normalize continuously by active voice count. Co
|
|
|
608
612
|
|
|
609
613
|
<a id="local-native-variation-candidate"></a>
|
|
610
614
|
|
|
611
|
-
## Variation support
|
|
615
|
+
## Variation support
|
|
612
616
|
|
|
613
|
-
Source builds produce archives at `android/dist/ti.synthengine-android-
|
|
617
|
+
Source builds produce archives at `android/dist/ti.synthengine-android-2.0.0.zip` and `ios/dist/ti.synthengine-iphone-2.0.0.zip`. Install both matching 2.0.0 packages in the consumer app and select them explicitly:
|
|
614
618
|
|
|
615
619
|
```xml
|
|
616
620
|
<modules>
|
|
617
|
-
<module platform="android" version="
|
|
618
|
-
<module platform="iphone" version="
|
|
621
|
+
<module platform="android" version="2.0.0">ti.synthengine</module>
|
|
622
|
+
<module platform="iphone" version="2.0.0">ti.synthengine</module>
|
|
619
623
|
</modules>
|
|
620
624
|
```
|
|
621
625
|
|
|
622
|
-
Rebuild and reinstall the application after replacing the native modules.
|
|
626
|
+
Rebuild and reinstall the application after replacing the native modules. TiSynth 2.0.0 retains native finite-tone repetition. Check the variation announcements directly as well. Send a `variation` dictionary only when `getDefaults().capabilities.variation === true` and `getDefaults().variationSchemaVersion === 1`. If either announcement is absent, omit the property completely, including at amount zero. See [native attack variation](native-variation.md) for accepted locations, bounded ranges and seed behavior.
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
> Source snapshot: official TiSynthEngine documentation at commit `
|
|
1
|
+
> Source snapshot: official TiSynthEngine documentation at commit `9d74aa45f84d3f2822d4aab76874efe37d81257f` (2026-11-03). Published module 2.0.0. Upstream `documentation/instruments-and-effects.md` SHA-256: `3796589dd6b3ac23ad1b9808a17bc1302187b5de980b5b234521246bba745b3c`.
|
|
2
2
|
|
|
3
3
|
# Instruments, sound effects and complete sequences
|
|
4
4
|
|
|
5
|
-
A playable instrument and a missile sound can use the same oscillator. Their behavior depends on the complete recipe: pitch, envelope, pitch/filter movement, layers, timing
|
|
5
|
+
A playable instrument and a missile sound can use the same oscillator. Their behavior depends on the complete recipe: pitch, envelope, pitch/filter movement, layers, timing and how the app starts and ends the sound. This guide explains which public API to use and how to preserve that recipe.
|
|
6
6
|
|
|
7
7
|
These are application roles built on the same native synthesizer and output chain. They are not different audio engines, quality modes, or guarantees against distortion. An instrument can be noisy or inharmonic; an effect can be a single pitched tone, a chord, or a musical phrase.
|
|
8
8
|
|
|
9
9
|
## Choose the playback contract
|
|
10
10
|
|
|
11
|
-
| Intention
|
|
12
|
-
|
|
|
13
|
-
| Play a key until the finger lifts
|
|
14
|
-
| Fire one finite sound
|
|
15
|
-
| Repeat one finite tone
|
|
16
|
-
| Fire a simultaneous chord
|
|
17
|
-
| Play
|
|
18
|
-
| Add chorus, delay, reverb or
|
|
11
|
+
| Intention | Sound interface | Who ends the sound? |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| Play a key until the finger lifts | Held definition's `play()` or `sound.noteOn()` | The owner calls its note control's `noteOff()` |
|
|
14
|
+
| Fire one finite sound | Tone definition's `play()` | Finite duration includes release |
|
|
15
|
+
| Repeat one finite tone or independent layer | Repeat definition's `play()` | Control `stop()` cancels future attacks; admitted attacks finish |
|
|
16
|
+
| Fire a simultaneous chord | Chord definition's `play()` | Native duration and release |
|
|
17
|
+
| Play an ordered score, alarm or pattern | Pattern definition's `play()` | Native clock; control `stop()` releases its voices |
|
|
18
|
+
| Add chorus, delay, reverb or saturation | `synth.setProcessing()` | Shared processor retains bounded tails |
|
|
19
19
|
|
|
20
20
|
The last row describes audio processing effects. Those processors are different from an authored sound effect, such as a laser or an explosion. A laser may use no reverb or delay at all.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
The detailed recipes below use supported direct native calls to explain the rendering parameters. Reusable application code uses the Sound controls above; see the [Sound reference](sound-api.md). All examples assume successful startup:
|
|
23
23
|
|
|
24
24
|
```javascript
|
|
25
25
|
var synth = require('ti.synthengine')
|
|
@@ -56,7 +56,7 @@ Store the returned ID with that contact. Sliding to another key must release the
|
|
|
56
56
|
|
|
57
57
|
`noteOn` does not accept timed-event endpoint sweeps such as `frequencyEnd`. A held voice can use its supported vibrato/LFOs and compatible `updateNote` edits. Removing a timed sweep, replacing the original frequency with the key's pitch, and holding indefinitely changes the sound's meaning: that is a new playable timbre, not an exact audition of the original effect.
|
|
58
58
|
|
|
59
|
-
A short envelope
|
|
59
|
+
A short envelope does not automatically end a held voice. With `sustain: 0`, it can become silent while still requiring release of its ID. Choose a timed event for a self-contained strike when contact ownership is unnecessary.
|
|
60
60
|
|
|
61
61
|
### Instrument demonstrations are musical performances
|
|
62
62
|
|
|
@@ -112,7 +112,7 @@ function missileSequence() {
|
|
|
112
112
|
|
|
113
113
|
Timed and sequence routes are not automatically interchangeable. In the current native implementation, a `playTone` endpoint sweep progresses across the total timed duration, including release. A sequence endpoint sweep progresses across its explicit `length`, then holds the endpoint during release. Thus the timed 350 ms example and the sequence with `length: 300` do not have the same pitch trajectory, even though both finish after 350 ms and use the same endpoints. Sequence voices also use the held envelope's minimum 3 ms attack/release edges; very short or zero timed edges can differ. This matters most for short weapon/noise effects and is not corrected by merely copying the option names.
|
|
114
114
|
|
|
115
|
-
For consistent manual and repeated auditions, use the same native interpretation for both. Preserve the original attack length when changing only the repetition interval; each new attack may overlap the prior voice. Do not claim exact timed-to-sequence fidelity from field equality or validator acceptance. Use
|
|
115
|
+
For consistent manual and repeated auditions, use the same native interpretation for both. Preserve the original attack length when changing only the repetition interval; each new attack may overlap the prior voice. Do not claim exact timed-to-sequence fidelity from field equality or validator acceptance. Use the retained `repeatTone({ intervalMs, ... })` method to repeat the original finite-tone renderer directly. A JavaScript adapter that simply renames `duration` to `length` does not preserve that rendering contract.
|
|
116
116
|
|
|
117
117
|
For a sequence-owned burst, `stopSequence` also releases emitted voices. To stop repetitions while preserving those attacks, publish a finite traversal with `loop: false`, retain its current effect steps and suppress later variant attacks as appropriate. Natural completion leaves emitted voices to their own lengths/releases. Retain the first attack in an update that can arrive before the initial callback. Handle publication rejection explicitly, with bounded control retries if necessary; those retries must not trigger notes or queue new sound requests.
|
|
118
118
|
|
|
@@ -143,7 +143,7 @@ Each layer consumes one of 32 repetition slots, independently of the four sequen
|
|
|
143
143
|
|
|
144
144
|
`updateTone` merges changes with the last accepted recipe and validates it as a whole. It changes the next scheduled attack without advancing it. `note` and `frequency` replace each other. A supplied variation dictionary replaces the previous one, and `{ amount: 0 }` disables future variation. Each repetition advances its reproducible native stream only for admitted attacks; parameter edits retain its counter, while changing seed restarts the succession. Sounding attacks keep their original recipe. See [the complete repetition contract](api.md#finite-tone-repetition).
|
|
145
145
|
|
|
146
|
-
Native sequences remain appropriate for complete ordered scores. Keep every positive sequence ID and wait for matching `sequenceend` retirement when replacing a sequence. `stopSequence` releases that sequence's emitted voices, whereas `stopTone` lets admitted finite attacks finish. Application recipe functions remain ordinary JavaScript; there is no built-in named-recipe registry.
|
|
146
|
+
Native sequences remain appropriate for complete ordered scores. Keep every positive sequence ID and wait for matching `sequenceend` retirement when replacing a sequence. `stopSequence` releases that sequence's emitted voices, whereas `stopTone` lets admitted finite attacks finish. Application recipe functions remain ordinary JavaScript; there is no built-in named-recipe registry.
|
|
147
147
|
|
|
148
148
|
## 4. Polyphony, gain and output protection
|
|
149
149
|
|
|
@@ -157,7 +157,7 @@ Both musical notes and effects share the voice pool and output chain. Either can
|
|
|
157
157
|
- Keep headroom at voice, processor input and master stages. Preserve source gains when importing a known recipe; changing the overlap pattern still needs new validation.
|
|
158
158
|
- Creative `saturation` intentionally changes timbre. Final output limiting protects peaks but is not proof that the earlier mix is clean.
|
|
159
159
|
|
|
160
|
-
Use `getStats` to inspect active/tail voices, pending commands, rejected publications, priority drops and voice steals. Enable diagnostics for `preLimiterPeakDb`, `maxLimiterReductionDb`, output peaks and callback load. See [gain staging](sound-design.md#chords-polyphony-and-gain), [processing](api.md#setmasterprocessingoptions), [statistics](stats-performance.md), and [troubleshooting](troubleshooting.md). Host measurements and successful validation do not replace listening on the target speaker/headphones at the intended overlap and physical volume.
|
|
160
|
+
Use `getStats` to inspect active/tail voices, pending commands, rejected publications, priority drops and voice steals. Enable diagnostics for `preLimiterPeakDb`, `maxLimiterReductionDb`, output peaks and callback load. See [gain staging](sound-design.md#chords-polyphony-and-gain), [processing](api.md#setmasterprocessingoptions), [statistics](https://github.com/macCesar/TiSynthEngine/blob/9d74aa45f84d3f2822d4aab76874efe37d81257f/documentation/stats-performance.md), and [troubleshooting](troubleshooting.md). Host measurements and successful validation do not replace listening on the target speaker/headphones at the intended overlap and physical volume.
|
|
161
161
|
|
|
162
162
|
## Verify the route you actually ship
|
|
163
163
|
|