@maccesar/titools 5.2.0 → 5.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +69 -0
- package/README.md +80 -72
- package/agents/ti-pro.md +1 -1
- package/commands/ti-audit.md +2 -2
- package/docs/examples.md +91 -0
- package/docs/knowledge-index.md +57 -0
- package/lib/downloader.js +1 -1
- package/package.json +4 -2
- package/skills/purgetss/references/multi-density-images.md +1 -1
- package/skills/ti-admob-unified/SKILL.md +21 -7
- package/skills/ti-admob-unified/assets/example/app.js +229 -25
- package/skills/ti-admob-unified/assets/example/lib/ads.js +30 -2
- package/skills/ti-admob-unified/assets/example/library-usage.js +33 -1
- package/skills/ti-admob-unified/references/api-reference.md +39 -16
- package/skills/ti-admob-unified/references/banners.md +9 -9
- package/skills/ti-admob-unified/references/contributing.md +14 -9
- package/skills/ti-admob-unified/references/dependencies.md +31 -25
- package/skills/ti-admob-unified/references/fullscreen.md +43 -28
- package/skills/ti-admob-unified/references/game-monetization.md +138 -7
- package/skills/ti-admob-unified/references/getting-started.md +75 -31
- package/skills/ti-admob-unified/references/index.md +5 -2
- package/skills/ti-admob-unified/references/integration.md +8 -6
- package/skills/ti-admob-unified/references/library.md +41 -10
- package/skills/ti-admob-unified/references/mediation-parity.md +17 -0
- package/skills/ti-admob-unified/references/mediation.md +22 -9
- package/skills/ti-admob-unified/references/migration.md +11 -7
- package/skills/ti-admob-unified/references/module-changelog.md +41 -11
- package/skills/ti-admob-unified/references/privacy.md +35 -8
- package/skills/ti-admob-unified/references/production.md +67 -0
- package/skills/ti-admob-unified/references/rewarded-interstitial.md +101 -0
- package/skills/ti-admob-unified/references/roadmap.md +28 -31
- package/skills/ti-admob-unified/references/source-notes.md +51 -4
- package/skills/ti-admob-unified/references/source-snapshot.json +249 -45
- package/skills/ti-admob-unified/references/third-party-notices.md +4 -4
- package/skills/ti-game/SKILL.md +23 -6
- package/skills/ti-game/references/api.md +34 -30
- package/skills/ti-game/references/debugging-performance.md +18 -9
- package/skills/ti-game/references/examples.md +103 -20
- package/skills/ti-game/references/input.md +101 -0
- package/skills/ti-game/references/patterns.md +39 -15
- package/skills/ti-game/references/physics.md +80 -52
- package/skills/ti-game/references/project-setup.md +118 -56
- package/skills/ti-game/references/recipes-action.md +107 -8
- package/skills/ti-game/references/recipes-adventure-effects.md +41 -9
- package/skills/ti-game/references/roadmap.md +10 -3
- package/skills/ti-game/references/source-notes.md +81 -0
- package/skills/ti-game/references/tilemaps.md +12 -4
- package/skills/ti-synthengine/SKILL.md +81 -95
- package/skills/ti-synthengine/assets/example/README.md +84 -0
- package/skills/ti-synthengine/assets/example/app.js +1178 -0
- package/skills/ti-synthengine/assets/example/lib/sequenceOwner.js +83 -0
- package/skills/ti-synthengine/assets/example/lib/sequenceScore.js +25 -0
- package/skills/ti-synthengine/references/advanced-examples.md +174 -0
- package/skills/ti-synthengine/references/android-sim80-correction-evidence.zip +0 -0
- package/skills/ti-synthengine/references/android-sim80-correction.json +162 -0
- package/skills/ti-synthengine/references/api.md +434 -380
- package/skills/ti-synthengine/references/audio-engine.md +157 -230
- package/skills/ti-synthengine/references/bypass-physical-recheck-evidence.zip +0 -0
- package/skills/ti-synthengine/references/examples.md +123 -253
- package/skills/ti-synthengine/references/frontier-android-evidence.zip +0 -0
- package/skills/ti-synthengine/references/frontier-ipad-evidence.zip +0 -0
- package/skills/ti-synthengine/references/frontier-physical-validation.json +1918 -0
- package/skills/ti-synthengine/references/guide.md +188 -156
- package/skills/ti-synthengine/references/performance-review-evidence.zip +0 -0
- package/skills/ti-synthengine/references/performance-review.json +1146 -0
- package/skills/ti-synthengine/references/physical-validation.json +1457 -0
- package/skills/ti-synthengine/references/recipes-interaction.md +549 -0
- package/skills/ti-synthengine/references/recipes.md +423 -599
- package/skills/ti-synthengine/references/recommendations.md +63 -113
- package/skills/ti-synthengine/references/sound-design.md +134 -258
- package/skills/ti-synthengine/references/source-notes.md +93 -105
- package/skills/ti-synthengine/references/source-snapshot.json +379 -32
- package/skills/ti-synthengine/references/stats-performance.md +64 -20
- package/skills/ti-synthengine/references/studio-validation.json +6202 -0
- package/skills/ti-synthengine/references/troubleshooting.md +109 -121
- package/skills/ti-synthengine/references/unified-bypass-performance.json +22425 -0
- package/skills/ti-synthengine/references/unified-validation.json +314 -0
- package/AGENTS-VERCEL-RESEARCH.md +0 -175
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Source provenance and audit limits
|
|
2
|
+
|
|
3
|
+
Reviewed on 2026-10-23. This skill is a curated reference, not a bundled module
|
|
4
|
+
binary or an assertion that a fork build has been published.
|
|
5
|
+
|
|
6
|
+
## Reviewed sources
|
|
7
|
+
|
|
8
|
+
- Upstream: `m1ga/ti.game@88e181cb85526d8146d0be6e09b2b90c2551baad`.
|
|
9
|
+
Remote `refs/heads/main` was checked with `git ls-remote` during this audit.
|
|
10
|
+
- Fork documentation snapshot: `macCesar/ti.game@2bf5f828a3bb8028eed20d6ba27b97dd3aa9a753`
|
|
11
|
+
(`docs/update-current-features`). Its source tree contains the current
|
|
12
|
+
upstream engine, not merely the older `3bea2f4` baseline.
|
|
13
|
+
- Fork delta from upstream: README/tutorial/TODO/Apple build documentation,
|
|
14
|
+
Xcode SDK selection, Camera example key binding, demo generation and
|
|
15
|
+
example-input regression checks, plus maintainer instructions.
|
|
16
|
+
- The documentation snapshot is the exact head of
|
|
17
|
+
[upstream PR #39](https://github.com/m1ga/ti.game/pull/39), branch
|
|
18
|
+
`docs/update-current-features`. PR metadata and the remote branch both matched
|
|
19
|
+
`2bf5f82` when checked. Its Camera Z/X binding correction and diagnostic
|
|
20
|
+
launcher discovery/SDK/indirect-input fixes were included in this audit.
|
|
21
|
+
- Only `AGENTS.md` was dirty when the audit started; that instruction-file
|
|
22
|
+
edit is not a native/API modification. Audited module documentation and
|
|
23
|
+
native files were committed. No module files were edited by this audit.
|
|
24
|
+
- Both manifests: `1.0.0`, minimum Titanium `13.4.0`. Builds documented at
|
|
25
|
+
Titanium `13.4.1.GA`; Apple minimum iOS 15. Release/nightly artifact versions
|
|
26
|
+
do not identify a source commit or prove these fork clarifications shipped.
|
|
27
|
+
|
|
28
|
+
Sources are the root README, `tutorial.md`, `ios/README.md`, TODO, the complete
|
|
29
|
+
35-demo launcher/catalog and helpers, plus both platforms' proxies, simulation,
|
|
30
|
+
input and renderer implementation where contracts require them. Maintainer
|
|
31
|
+
plans, personal project state and issue drafts are excluded from public API
|
|
32
|
+
requirements; they are not additional supported APIs.
|
|
33
|
+
|
|
34
|
+
## Source fingerprints
|
|
35
|
+
|
|
36
|
+
SHA-256 of the reviewed committed documents/configuration:
|
|
37
|
+
|
|
38
|
+
| Source path | SHA-256 |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| `README.md` | `a1970c35c56880d7722d9397b968502b8357c9c3b0b83ee2dd2be4e18df02dd6` |
|
|
41
|
+
| `tutorial.md` | `a57e609935a92b6efb0513a9ddc271d4a9d1f7ead5188612d1014533ec801d7d` |
|
|
42
|
+
| `ios/README.md` | `89ab286034acdfed05627316cfd93b4b019cc44a99e7c5a46c8d2b38f564fd4b` |
|
|
43
|
+
| `TODO.md` | `a9c3b3ce25883bdc4472a908f2bcd955dcd415ec37f8d8c6b9129a7a505f4cd3` |
|
|
44
|
+
| `android/manifest` | `4c20ea79fb9ccb87581b37a2b8450a635f84e5f2ff53bf5c6d574faa0260340d` |
|
|
45
|
+
| `ios/manifest` | `472f4f0d572416b0df739ca8fcdc03febd4e20a3ecedcb99c6e494925c3ea6c0` |
|
|
46
|
+
|
|
47
|
+
## Current corrections and unresolved source conflicts
|
|
48
|
+
|
|
49
|
+
- Apple is Metal/CAMetalLayer; Android retains OpenGL ES. No public Apple
|
|
50
|
+
backend selector or app-provided `default.metallib` is required.
|
|
51
|
+
- Configurable digital actions, keyboard/mouse focus, GameController fanout
|
|
52
|
+
and cancellation are current contracts; see [input.md](input.md).
|
|
53
|
+
- Assigning Sprite `frame` stops its animation and queued chain. Android's
|
|
54
|
+
optional animation completion `frame` is not portable to Apple. Set animation
|
|
55
|
+
definitions at creation for portable code. See [api.md](api.md).
|
|
56
|
+
- Damping now lets effective unopposed acceleration build speed from rest; zero-delta rope updates
|
|
57
|
+
freeze initialized geometry. Historical contrary guidance from `3bea2f4`
|
|
58
|
+
must not be applied to this source pin. See [physics.md](physics.md).
|
|
59
|
+
- README Draw text retains an obsolete ASCII-only sentence. Its Font section
|
|
60
|
+
and both native maps include precomposed accented Latin glyphs; the skill
|
|
61
|
+
follows the implementation and lists the actual repertoire.
|
|
62
|
+
- Telemetry reports CPU drawable acquisition/presentation submission, not GPU
|
|
63
|
+
duration or proof of display. Missing drawables/slot pressure preserve elapsed
|
|
64
|
+
simulation up to the documented recovery cap; pause/suspension resets clocks.
|
|
65
|
+
- App orientation/launch policy belongs to Titanium, not the module. The older
|
|
66
|
+
`ti-ui` orientation guide is not a fully audited multi-activity setup; that
|
|
67
|
+
dependency remains explicitly limited in [project-setup.md](project-setup.md).
|
|
68
|
+
|
|
69
|
+
## Verification boundaries
|
|
70
|
+
|
|
71
|
+
The audit reconciles current reference guidance with source and focused host
|
|
72
|
+
regressions. Native resolver tests exercise Java/Objective-C binding validation,
|
|
73
|
+
aggregation and state transitions. Physics fixtures execute extracted production
|
|
74
|
+
methods with controlled collaborators. JavaScript demo/layout tests use mocked
|
|
75
|
+
Titanium/game objects. These do not establish GPU behavior or physical keyboard,
|
|
76
|
+
mouse, controller, navigation or audio acceptance.
|
|
77
|
+
|
|
78
|
+
Apple's own README records renderer acceptance on Apple Silicon Catalyst and a
|
|
79
|
+
physical iPad (18 tests on 2026-10-22). This audit does not rerun or extend that
|
|
80
|
+
evidence. Physical iPhone, Intel execution, complete interactive demo acceptance
|
|
81
|
+
and controlled performance comparisons remain pending in the module source.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Native tile maps
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Reviewed on 2026-10-23 against upstream native `88e181c` and
|
|
4
|
+
`macCesar/ti.game@2bf5f82` documentation: `README.md` § Tile maps, `example/tilemap.js`, both `TileLayerProxy` implementations, both native `TileLayer` engines, scene collision, and `Pathfinder`.
|
|
4
5
|
|
|
5
6
|
Use `Game.createTileLayer()` for a large or mostly static grid. The engine stores the whole map but renders only cells inside the camera, batches the layer through one sheet, checks only collision cells under a mover, and feeds solid cells into `findPath`. A small map whose tiles need independent sprite behavior can still use sprites; `topdown.js` is a 16×12 example of that older pattern.
|
|
6
7
|
|
|
@@ -40,7 +41,7 @@ For Tiled JSON, pass the layer data with `cols: map.width`, `rows: map.height`,
|
|
|
40
41
|
|
|
41
42
|
## Portable property timing
|
|
42
43
|
|
|
43
|
-
The
|
|
44
|
+
The reviewed README documents the same creation-time portability
|
|
44
45
|
boundary as the native bindings. Use this contract:
|
|
45
46
|
|
|
46
47
|
| Timing | Properties |
|
|
@@ -52,6 +53,8 @@ boundary as the native bindings. Use this contract:
|
|
|
52
53
|
iOS rebuilds the grid when `legend`, `firstGid`, `cols`, or `rows` is assigned later. Android exposes no setters for those four. Supplying them in the factory keeps both platforms aligned.
|
|
53
54
|
|
|
54
55
|
`opacity`, `scrollFactor`, and `restitution` accept ratio numbers or percentage strings. `tileWidth`/`tileHeight`, coordinates, and dimensions do not.
|
|
56
|
+
`data` is a write-only input; inspect individual cells with `getTile()` or
|
|
57
|
+
`cellAt()` instead of expecting the original input shape to read back.
|
|
55
58
|
|
|
56
59
|
## Collision cells
|
|
57
60
|
|
|
@@ -116,13 +119,18 @@ function walkTo(player, destination, tileLayer, gameView) {
|
|
|
116
119
|
}
|
|
117
120
|
```
|
|
118
121
|
|
|
119
|
-
Bound the per-query A* search to the useful neighborhood.
|
|
122
|
+
Bound the per-query A* search to the useful neighborhood. Increasing the grid consumes more memory even though drawing only visits visible cells; `findPath()` still builds a grid for the requested bounds on the calling thread.
|
|
120
123
|
|
|
121
124
|
## Layering and performance
|
|
122
125
|
|
|
123
126
|
- Stack separate layers for ground, decoration, and foreground. Layers draw below sprites at the same `zIndex`.
|
|
124
127
|
- Share one sheet when layers use the same tileset.
|
|
125
128
|
- Use `scrollFactor` for parallax layers; collision remains in world coordinates, just as with sprites.
|
|
129
|
+
- In a circular `worldWrapX` scene, the layer repeats drawing and solid cells
|
|
130
|
+
across the seam only when `x` equals the interval's `minX` and `width` equals
|
|
131
|
+
`maxX - minX`. This does not make `findPath()` or `raycast()` periodic.
|
|
126
132
|
- Use `visible: false` to exclude the layer from drawing and collision.
|
|
127
|
-
- Toggle `layer.debug` for one layer or `gameView.debug = { hitbox: true }` for
|
|
133
|
+
- Toggle `layer.debug` for one layer or `gameView.debug = { hitbox: true }` for
|
|
134
|
+
every layer's collision cells: green outlines fully solid cells; yellow
|
|
135
|
+
draws the top face of one-way cells.
|
|
128
136
|
- Use the performance HUD while scrolling: map dimensions should not change visible-cell draw cost.
|
|
@@ -1,116 +1,102 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ti-synthengine
|
|
3
|
-
description: "Use when a Titanium app declares ti.synthengine in tiapp.xml, imports require('ti.synthengine'), or
|
|
3
|
+
description: "Use when a Titanium app declares ti.synthengine in tiapp.xml, imports require('ti.synthengine'), or needs generated tones, chords, native sequences, sustained game motors, ADSR, sweeps, FM, resonant filters, noise, binaural spatialX/spatialY, held noteOn/noteOff/updateVoice, shared tempo, selective music/effects/ui/ambience processing, effectSend, priorities, chorus/delay/reverb/saturation, LFOs, sequenceend events, gain staging, statistics or render-load diagnosis. Covers the published Android/iOS 1.0.0 contract. Not for audio-file decoding, sample streaming or unrelated synthesizers."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# ti.synthengine — sound synthesis for Titanium
|
|
6
|
+
# ti.synthengine — native sound synthesis for Titanium
|
|
7
7
|
|
|
8
|
-
Act as an audio engineer and mobile sound designer
|
|
8
|
+
Act as an audio engineer and mobile sound designer. Translate the requested sound into acoustically reasoned JavaScript using the exact public contract.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
These references describe the **public 1.0.0 release** at
|
|
11
|
+
`e7cbbe8a6f9ab38088fd8029c7b43cef6501101f` (reviewed 2026-10-24).
|
|
12
|
+
Download matching [Android](https://github.com/macCesar/TiSynthEngine/releases/tag/android-1.0.0)
|
|
13
|
+
and [iOS](https://github.com/macCesar/TiSynthEngine/releases/tag/ios-1.0.0)
|
|
14
|
+
packages from the public [repository](https://github.com/macCesar/TiSynthEngine).
|
|
15
|
+
Source/mirror hashes are in [source-snapshot.json](references/source-snapshot.json);
|
|
16
|
+
artifact checksums and native findings are in [source notes](references/source-notes.md).
|
|
17
|
+
The current [interactive example](assets/example/README.md) includes both helpers.
|
|
18
|
+
Earlier private packages also used version 1.0.0: require current methods and
|
|
19
|
+
install the official platform ZIPs rather than inferring capabilities from that
|
|
20
|
+
version string or adding a second JavaScript audio scheduler.
|
|
15
21
|
|
|
16
22
|
## Required workflow
|
|
17
23
|
|
|
18
|
-
Read the
|
|
24
|
+
Read the relevant references before writing or reviewing code. When updating the module or its documentation, compare with both native platforms and the shared DSP before synchronizing these mirrors; a snapshot is not an independent correctness oracle.
|
|
19
25
|
|
|
20
26
|
| Task | Read first |
|
|
21
27
|
| --- | --- |
|
|
22
|
-
| Any
|
|
23
|
-
|
|
|
24
|
-
| Design
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
28
|
+
| Any public method, option, default, return value or limit | [API](references/api.md) |
|
|
29
|
+
| Download public releases, install, initialize, own or clean up an engine | [Guide](references/guide.md) |
|
|
30
|
+
| Design an effect, instrument, reward, alarm or game motor | [Sound design](references/sound-design.md), [recipes](references/recipes.md), [examples](references/examples.md) |
|
|
31
|
+
| Xylophone, memory pads, layered chords, FM instruments and interaction ownership | [Interaction recipes](references/recipes-interaction.md) |
|
|
32
|
+
| Hold, edit, release or position a sustained voice | [API](references/api.md#noteonoptions), [advanced examples](references/advanced-examples.md#sustained-game-motor) |
|
|
33
|
+
| Schedule simultaneous sequences, tempo, swing, edits and cancellation | [API transport](references/api.md#native-sequence-transport), [advanced examples](references/advanced-examples.md#native-sequence-with-chords-and-edits) |
|
|
34
|
+
| Select categories, sends, shared effects and synchronized LFOs | [Processing API](references/api.md#setmasterprocessingoptions), [engine](references/audio-engine.md), [advanced examples](references/advanced-examples.md) |
|
|
35
|
+
| Map headphone coordinates and stereo bypass | [Guide](references/guide.md#integrate-binaural-in-a-2d-app), [API](references/api.md) |
|
|
36
|
+
| Interpret gain, clipping, statistics or render performance | [Recommendations](references/recommendations.md), [statistics](references/stats-performance.md), [engine](references/audio-engine.md) |
|
|
37
|
+
| Diagnose rejection, silence, interruptions or glitches | [Troubleshooting](references/troubleshooting.md), [source notes](references/source-notes.md) |
|
|
38
|
+
| Accepted optimizations, rejected Apple runtime and physical performance limits | [Current performance review](references/performance-review.json), [engine](references/audio-engine.md), [source notes](references/source-notes.md) |
|
|
39
|
+
| Android binaural performance correction and its listening/load limits | [Current Sim80 correction](references/android-sim80-correction.json), [source notes](references/source-notes.md), [unified host validation](references/unified-validation.json), [bypass comparison](references/unified-bypass-performance.json) |
|
|
40
|
+
| Audit provenance and acceptance boundaries | [Snapshot](references/source-snapshot.json), [source notes](references/source-notes.md), [historical Studio report](references/studio-validation.json), [physical evidence](references/physical-validation.json), [Frontier measurements](references/frontier-physical-validation.json) |
|
|
41
|
+
|
|
42
|
+
Cite factual guidance with `[source: references/<file>.md]`. If the relevant source cannot be read, prefix the claim with `FROM_MEMORY (unverified):`; do not invent Web Audio or other synthesizer option names.
|
|
43
|
+
|
|
44
|
+
## Response contract
|
|
45
|
+
|
|
46
|
+
Explain the waveform, envelope, pitch/filter motion and stereo choice briefly in the user's language. Include checked initialization if no engine owner exists, followed by focused production code. Comments and controls should explain meaningful sound choices. Obtain constants from the runtime:
|
|
47
|
+
|
|
48
|
+
```javascript
|
|
49
|
+
const synth = require('ti.synthengine')
|
|
50
|
+
const contract = synth.getDefaults()
|
|
51
|
+
const WAVE = contract.waveTypes
|
|
52
|
+
if (!synth.start({maxVoices: 32, maxSequences: 4,
|
|
53
|
+
mixingProfile: 'conservative', audioSession: 'ambient'})) {
|
|
54
|
+
throw new Error('Audio engine rejected startup')
|
|
55
|
+
}
|
|
56
|
+
```
|
|
31
57
|
|
|
32
|
-
|
|
58
|
+
The current iOS `getDefaults()` omits some capability and limit metadata reported by Android. Detect required methods and use the API ranges; a missing metadata flag is not proof of a missing method. [source: references/api.md]
|
|
33
59
|
|
|
34
|
-
|
|
60
|
+
Choose the actual required sequence capacity, 1–4; the snippet's four slots suit games with simultaneous music, effects and cues. One engine and render callback share up to 32 voices. Start after screen layout settles; the owning service/window shuts down on teardown. On iOS, `ambient` respects silent mode and mixes with other apps; `playback` is the default and ignores silent mode. Profile, voice/sequence capacity and session require shutdown before changing them. [source: references/api.md]
|
|
35
61
|
|
|
36
|
-
|
|
62
|
+
## Scheduling contract
|
|
37
63
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
64
|
+
- `playTone` is one timed event, `playChord` one simultaneous atomic chord, and `noteOn`/`noteOff`/`updateVoice` own sustained voices. `playSequence` is the only successive-sound scheduler. Do not add aliases or JavaScript note timers.
|
|
65
|
+
- `playSequence(options)` returns a positive identifier or `0`. `updateSequence({sequenceId,...changes})`, `stopSequence({sequenceId})` and `setTempo({bpm})` return Boolean acceptance. `getSequenceState({sequenceId})` returns applied revision/position or `null` for unknown/retired IDs. Acceptance can precede callback application.
|
|
66
|
+
- Sequence IDs do not repeat over module lifetime, including shutdown/start. Keep the accepted ID and cancel only the owner's sequence. An accepted stop does not immediately free capacity: coalesce replacement requests and publish the latest complete score after its matching `sequenceend`. A delayed event for an old ID must not change the new owner.
|
|
67
|
+
- `setTempo({bpm})` accepts 20–300, initially 120. It changes on the next block while conserving musical position. Synced delays/LFOs follow this tempo; free controls keep milliseconds/hertz.
|
|
68
|
+
- `timeUnit` is fixed for a sequence: `beats` by default, or `ms`. `stepDuration` defaults to 0.25 beats or 100 ms. `loop` defaults to false; circular Studio patterns explicitly pass true.
|
|
69
|
+
- Up to 512 steps each carry exactly one of MIDI `notes` (12–119), `frequencies`, or `rest:true`. Pitch arrays hold 1–32 values and permit duplicates for unison. Root shaping belongs in `voice`; per-step shaping belongs in `overrides`.
|
|
70
|
+
- Step `duration` changes the interval until the next attack. `gate`, initially 0.8, places release within that effective interval. Explicit `length` replaces gate and may overlap later attacks. Intervals and lengths follow the sequence time unit; ADSR remains in milliseconds without a sequence interval budget. Sweeps reach their target at note length and hold it during release.
|
|
71
|
+
- Swing −0.75…0.75 shifts `swing * min(A,B)` within a pair and preserves its total. Structural edits enter next step; swing next pair. Modes are normal/up/down/updown; rests participate only in normal mode.
|
|
72
|
+
- `sequenceend` carries `{sequenceId,reason:'completed'|'stopped'}` outside audio render. It does not establish audible silence: voice release and effect tails may remain.
|
|
41
73
|
|
|
42
|
-
|
|
74
|
+
Preserve migrated score timing deliberately: a former total envelope of 150 ms with 25 ms release becomes `length:125` in a millisecond sequence, with `release:25`. Keep onset intervals separate. [source: references/api.md]
|
|
43
75
|
|
|
44
|
-
##
|
|
76
|
+
## Voices, routes and continuous controls
|
|
45
77
|
|
|
46
|
-
|
|
78
|
+
`bus` selects `music`, `effects` (default), `ui` or `ambience`. `setMasterProcessing({applyTo:[...]})` selects processed categories, initially all four; an empty array selects none. An explicit `effectSend:0…1` overrides the category selection for that voice. There is one shared chorus/delay/reverb/saturation chain. Input gain and master volume remain global. Selected audio receives processing, rejoins dry audio, and passes one final limiter. Effects and saturation start disabled. Disable closes input and retains bounded tails up to 30 seconds; panic invalidates histories. [source: references/api.md]
|
|
47
79
|
|
|
48
|
-
|
|
49
|
-
var synth = require('ti.synthengine')
|
|
50
|
-
var contract = synth.getDefaults()
|
|
51
|
-
var WAVE = contract.waveTypes
|
|
52
|
-
```
|
|
80
|
+
Sustained IDs are positive app-owned integers. Release on key up, touch cancellation, pause and teardown. Handle rejected release by retrying twice at 16 ms, then shut down/report if it still fails. These retry timers are lifecycle/error recovery, not a musical clock. Ended/stolen IDs accept edits as no-ops. [source: references/api.md]
|
|
53
81
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
- FM
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
Use these as starting regions, then keep every explicit value inside the API limits and the envelope intersection:
|
|
77
|
-
|
|
78
|
-
| Intent | Starting design |
|
|
79
|
-
| --- | --- |
|
|
80
|
-
| Clean UI click or feedback | `SINE` or `TRIANGLE`, roughly 30–120 ms, 1–5 ms attack, short fitted release |
|
|
81
|
-
| Retro pickup or melody | `SQUARE`, short notes or a rising `playPattern()`; a narrow `pulseWidth` or a `pulseWidthEnd` sweep thins it, `bitDepth` adds grit |
|
|
82
|
-
| Retro bass | `TRIANGLE`, lower pitch, short attack and controlled release |
|
|
83
|
-
| Hit, hat, explosion texture | `NOISE`, immediate attack and short-to-medium release; lower `noiseRate` or `lowPassHz` darkens it; layer only when the overlap budget allows |
|
|
84
|
-
| Coarse DAC-like or buzzy custom voice | `WAVETABLE` with a short asymmetric `waveTable`, optionally with `bitDepth` |
|
|
85
|
-
| Alarm or urgent cue | `SAWTOOTH`, repeated pitches, a sweep, or vibrato around 4–7 Hz; use larger `lfoDepth` only for an obvious effect |
|
|
86
|
-
| Laser or sci-fi movement | One `frequency` plus `frequencyEnd`, short attack, fitted release, optional `pan` → `panEnd` |
|
|
87
|
-
| Headphone cue above/right or below/left | Use `spatialX`/`spatialY` on a broadband sound, without stereo pan fields; verify perceived direction with headphones |
|
|
88
|
-
| Pad or atmosphere | One `playChord()` with `SINE` or `TRIANGLE`, 2000 ms or longer, 300–600 ms attack, 800–1500 ms release when it fits |
|
|
89
|
-
| Plucked string, marimba or keyboard note | `TRIANGLE` or `SINE`, 2 ms attack, `decay` 120–400 ms, `sustain` 0 to 0.3, release that fits |
|
|
90
|
-
| Electric piano, bell or metallic hit | `SINE` with `fmDepth` that falls to `fmDepthEnd: 0`; `fmRatio` 1, 2 or 3.5 for tine-like tones, a non-integer ratio for bells; add `decay` and a low `sustain` |
|
|
91
|
-
| Wah, wind or filter sweep | `SAWTOOTH` or `NOISE` through `filterType: 'bandpass'` or `'lowpass'`, `filterHz` to `filterHzEnd`, `filterQ` 2 to 6 |
|
|
92
|
-
| Thick unison pad or supersaw | `playChord()` with the same pitch repeated and `detunes` of ±5 to ±12 cents; keep the gain staging in mind |
|
|
93
|
-
|
|
94
|
-
A4 is 440 Hz under twelve-tone equal temperament; each octave doubles or halves frequency. Upward sweeps tend to read as activation, reward, or energy gain; downward sweeps tend to read as dismissal, power-down, or impact. Treat pan as supporting detail because many phone speakers collapse the stereo image.
|
|
95
|
-
|
|
96
|
-
For playable controls, trigger one event when the finger enters a new key, not on every `touchmove`. For simultaneous musical voices, prefer one atomic `playChord()` call; use `detunes` (cents per pitch) when a layered sound needs beating. Cancel app-owned timers before stopping voices or shutting down the engine. [source: references/recipes.md]
|
|
97
|
-
|
|
98
|
-
## Mixing and lifecycle defaults
|
|
99
|
-
|
|
100
|
-
- Begin with `mixingProfile: 'conservative'`; use `balanced` mainly for one or two voices, `speakerSafe` for demanding small speakers, and `raw` only when the app owns gain staging.
|
|
101
|
-
- Size `maxVoices` for the largest real overlap, including release tails. Capacity is not loudness.
|
|
102
|
-
- On iOS, the default `audioSession: 'playback'` ignores the silent switch and interrupts other apps' audio. Pass `audioSession: 'ambient'` to `startEngine()` when a game should respect the switch and mix with other apps; Android validates the value and ignores it. Profile, voice count, and session are fixed until `shutdown()`.
|
|
103
|
-
- Use one engine owner. On a Titanium screen, start after layout settles and call `shutdown()` when the owner closes.
|
|
104
|
-
- Test on the actual output path. Headphones expose noise and stereo detail; small phone speakers expose weak bass, resonance, and acoustic distortion that a digital limiter cannot repair.
|
|
105
|
-
|
|
106
|
-
## Before returning code
|
|
107
|
-
|
|
108
|
-
- Re-read the exact method table in `references/api.md`; remove every unsupported property.
|
|
109
|
-
- Confirm pitch fields are mutually exclusive and numeric values are finite and in range.
|
|
110
|
-
- Compute the envelope intersection explicitly, including `attack + decay <= duration`.
|
|
111
|
-
- Check the cross-field rules: `sustain` below 1 needs a `decay`, filter fields need a `filterType`, FM needs a sine and a depth.
|
|
112
|
-
- Check installed spatial limits before using binaural coordinates; remove conflicting stereo fields at both pattern root and step. Omit coordinates when the app switch is off.
|
|
113
|
-
- Use `WAVE` constants from `getDefaults()`.
|
|
114
|
-
- Use `playChord()` for one simultaneous musical event instead of several hotter independent tones.
|
|
115
|
-
- Include startup and cleanup only at the ownership level relevant to the request.
|
|
116
|
-
- Cite the references that support the acoustic and API choices.
|
|
82
|
+
Compatible `updateVoice` fields include frequency, volume, vibrato, resonant filter targets, pulse width, FM, modulations, `noiseRate`, `lowPassHz`, stereo/spatial position and `effectSend`. Transitions take 10 ms and preserve phase, spatial history and the current envelope. `noiseRate:0` is white noise; `lowPassHz:0` bypasses its one-pole filter. Spatial updates require a voice started spatially; stereo `pan` applies to a stereo voice. Do not combine spatial coordinates with stereo pan fields. [source: references/api.md]
|
|
83
|
+
|
|
84
|
+
`priority:0…3`, initially 0, controls eligible replacement under the shared voice pool. Higher priorities remain protected. Chords are admitted or discarded completely; there are no reserved per-category quotas. Gain is fixed per event, with initial chord compensation. Starting unrelated voices does not normalize earlier voices. [source: references/api.md]
|
|
85
|
+
|
|
86
|
+
## Sound and validation rules
|
|
87
|
+
|
|
88
|
+
- Closed option dictionaries reject unknown keys, wrong types, non-finite/out-of-range values and fractional integer fields. Check acceptance at meaningful boundaries; never silently clamp native options.
|
|
89
|
+
- A tone uses at most one of note/frequency; a chord uses exactly one notes/frequencies array. Tone/chord note names differ from sequence MIDI integers.
|
|
90
|
+
- Timed tone/chord `duration` includes release: explicit attack must be shorter, release must fit after attack, and attack+decay must fit. `sustain < 1` requires decay. Held/sequence ADSR has its own documented rules.
|
|
91
|
+
- FM requires sine; enabled filter fields require a filter type. `fmDepthEnd:0` is a real target, so omit it to disable a sweep. Plain tone FM ratio requires active depth; held/sequence FM-target modulation can start at zero depth.
|
|
92
|
+
- WAVETABLE needs 2–64 samples in −1…1. `bitDepth` is 0 or integer 2–16. Pulse width shapes square voices. Read the exact discontinuous ranges and source rules in the API.
|
|
93
|
+
- Up to two native sine/triangle LFOs target filterHz, pulseWidth or fmDepth. Free rates and tempo sync are distinct. Empty modulations disables them; omission on update preserves them.
|
|
94
|
+
- Use noise for impacts/wind, square for retro rewards, triangle for bass/plucks, sine FM for bells/keys, and filtered saw/noise for moving textures. Keep gains modest enough for release overlap and coherent unison. Listen on the actual speaker/headphones before approving timbre.
|
|
95
|
+
|
|
96
|
+
Binaural coordinates span a headphone front plane. Omit both spatial keys to bypass; two zeros still enable binaural center. Map app percentages explicitly and preserve pitch/envelope recipes. Height perception depends on the listener and sound spectrum; output remains stereo without rear sources, room reflections or head tracking. [source: references/api.md]
|
|
97
|
+
|
|
98
|
+
Timed zero attack/release and rejection diagnostics currently differ between native platforms. Check API acceptance directly; do not infer sample-identical envelopes or a complete rejection tally from validator parity. Read [source notes](references/source-notes.md) for independently rechecked findings. [source: references/api.md]
|
|
99
|
+
|
|
100
|
+
Diagnostics are opt-in. Preserve unavailable/null readings; poll UI slowly and clean up its timer. Render load is callback work divided by deadline, not app CPU. Historical host reports, validator parity and hash equality do not establish current physical real-time or listening acceptance. Keep technical results and César's auditory acceptance separate. [source: references/audio-engine.md] [source: references/source-notes.md]
|
|
101
|
+
|
|
102
|
+
Use `ti-game` for native movement/physics and `ti-game-assets` for related visual/audio asset production. Audio scheduling remains in TiSynthEngine; do not change gameplay or install on physical devices without the task's authorization.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
> Source snapshot: official TiSynthEngine 1.0.0 documentation at release source commit `e7cbbe8a6f9ab38088fd8029c7b43cef6501101f` (2026-10-24). Upstream `example/README.md` SHA-256: `c3c5041be11c3addfab7fb1248c0aaba81b311c1720c2861e47974412d743bcf`.
|
|
2
|
+
|
|
3
|
+
# Interactive example
|
|
4
|
+
|
|
5
|
+
The Classic Titanium app in [app.js](app.js) demonstrates the timed sounds, native sequences and statistics with the `sequenceend` event on Android and iOS. It uses the current 1.0.0 module packages, including binaural and statistics support. Held voices, master processing and voice LFOs have copyable examples in the [advanced documentation](../../references/advanced-examples.md#sustained-game-motor); this reference app does not expose those newer controls. The default engine configuration is 16 voices, `conservative` mixing and the `playback` session; master volume starts at 100% and optional diagnostics start off.
|
|
6
|
+
|
|
7
|
+
## Run it
|
|
8
|
+
|
|
9
|
+
1. Create a Classic Titanium application with Android and/or iOS support. If the app uses Alloy, create a separate Classic test project and leave the Alloy-generated files in place.
|
|
10
|
+
2. Download matching official [Android 1.0.0](https://github.com/macCesar/TiSynthEngine/releases/tag/android-1.0.0) and [iOS 1.0.0](https://github.com/macCesar/TiSynthEngine/releases/tag/ios-1.0.0) packages, or build the matching module source. Source builds produce `android/dist/ti.synthengine-android-1.0.0.zip` and `ios/dist/ti.synthengine-iphone-1.0.0.zip`.
|
|
11
|
+
3. Put the archive for each target platform in the test app root. Add these entries inside its `tiapp.xml`:
|
|
12
|
+
|
|
13
|
+
```xml
|
|
14
|
+
<modules>
|
|
15
|
+
<module platform="android" version="1.0.0">ti.synthengine</module>
|
|
16
|
+
<module platform="iphone" version="1.0.0">ti.synthengine</module>
|
|
17
|
+
</modules>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
4. Copy the entire `example/` folder into the test app's `Resources/`, including [app.js](app.js), [sequenceScore.js](lib/sequenceScore.js) and [sequenceOwner.js](lib/sequenceOwner.js). It needs no images or audio files.
|
|
21
|
+
5. Build and run the test app with the Titanium CLI or your existing Titanium launch configuration. Use Titanium SDK 13.2.0.GA or newer, Android compile API 35 or newer, and iOS 15 or newer. See the [module installation guide](../../references/guide.md#install-the-module).
|
|
22
|
+
|
|
23
|
+
The example checks the installed API version, spatial limits and all three statistics methods before constructing the screen. If it requests current packages, replace the native module, then rebuild and reinstall the app; copying module files alone does not update an app already on a device.
|
|
24
|
+
|
|
25
|
+
Audio starts after the first layout settles. Sound controls report native rejections. If startup fails, the session buttons remain available to retry. Closing the window removes its sequence listener, clears startup/statistics timers, disables diagnostics and shuts down the engine. The example plays finite sounds in the foreground and does not demonstrate background audio. Turn diagnostics off before leaving it in the background.
|
|
26
|
+
|
|
27
|
+
## Synthesis and sequencing
|
|
28
|
+
|
|
29
|
+
- Compare all six waveforms and equivalent English/solfege note names.
|
|
30
|
+
- Try stereo pan, pitch sweep, vibrato, variable-rate noise, pulse width, custom wavetable and quantization.
|
|
31
|
+
- Compare atomic chords with explicit pans, matched arpeggios, tempo/swing and noise percussion.
|
|
32
|
+
- Hear decay/sustain, resonant filtering, FM bell/electric piano and detuned voices.
|
|
33
|
+
|
|
34
|
+
Keep system volume moderate while comparing sounds. Master BOOST intentionally raises the bus above unity; use the 100% control to restore it. Repeated taps overlap events and may cause limiting or voice replacement.
|
|
35
|
+
|
|
36
|
+
## Headphone positioning
|
|
37
|
+
|
|
38
|
+
Use stereo headphones. In the binaural section, compare each of the nine noise positions one at a time: left/right runs from -1 to 1, above/below from 1 to -1. The center still uses binaural processing. Elevation perception varies with the listener and headphones, so the controls cannot guarantee localization for each person.
|
|
39
|
+
|
|
40
|
+
Select STEREO MODE and repeat points with the same horizontal position. Their height no longer affects placement because both spatial keys are omitted. BINAURAL MODE restores per-event coordinates. These two modes affect this section only; the ordinary stereo demos remain unchanged. An active voice keeps its original position.
|
|
41
|
+
|
|
42
|
+
SPATIAL CHORD places the whole chord above/right. SPATIAL PATTERN places three broadband hits above/left, below/center and above/right using per-step coordinates. Neither sends stereo pan fields while binaural is active. The output remains two channels on a front plane, without rear positioning, distance attenuation or head tracking. See the [app integration guide](../../references/guide.md#integrate-binaural-in-a-2d-app) for source mapping and amplitude sliders.
|
|
43
|
+
|
|
44
|
+
## Audio session
|
|
45
|
+
|
|
46
|
+
On iOS, compare PLAYBACK SESSION and AMBIENT SESSION. Changing the selection shuts down the engine, silently cancels any pending pattern, starts the new policy and restores the selected master volume. It does not resume the previous sound. The policy is fixed while the stream runs; a second `start()` alone cannot change it.
|
|
47
|
+
|
|
48
|
+
On an iOS device, play music from another app and try a short sound in ambient mode; compare with playback. Also compare the device's silent mode where available. Ambient should respect silent mode and mix with other apps; playback ignores silent mode and normally interrupts their audio. Android validates both strings but does not change its output. Simulator behavior does not establish the physical silent-mode, interruption or route behavior.
|
|
49
|
+
|
|
50
|
+
## Sequence completion and cancellation
|
|
51
|
+
|
|
52
|
+
1. Tap PATTERN END and wait for `sequenceend: completed`.
|
|
53
|
+
2. Tap it twice quickly. The example requests stop for its accepted sequence, coalesces repeated taps to the latest complete score, and publishes it only after the matching retirement event frees capacity. Native `sequenceend` events report `{ sequenceId, reason: 'completed' | 'stopped' }`.
|
|
54
|
+
3. Selecting a session shuts down the engine and restarts it with the selected policy. Events already queued for JavaScript can still arrive.
|
|
55
|
+
4. STOP ALL releases active voices and cancels future attacks. Closing the example shuts down its engine.
|
|
56
|
+
|
|
57
|
+
All successive attacks run on the native sample clock. The example compiles its note-name scores to millisecond sequences with explicit `duration` and `length`, preserving the original interval and release onset. Each sequence has one of `frequencies`, MIDI `notes`, or `rest: true` per step, with sound shaping in `voice`/`overrides`. Copy the entire `example/` folder, including `lib/sequenceScore.js` and `lib/sequenceOwner.js`, into a Classic app's Resources folder.
|
|
58
|
+
|
|
59
|
+
Completion marks the final scheduled step; releases and shared effect tails can remain audible. See the [event contract](../../references/api.md#sequenceend-event).
|
|
60
|
+
|
|
61
|
+
## Statistics
|
|
62
|
+
|
|
63
|
+
- READ STATS takes a fresh snapshot without resetting counters or enabling diagnostics.
|
|
64
|
+
- TOGGLE DIAGNOSTICS enables callback timing and signal meters, refreshing at 5 Hz. Toggle it off to stop the timer and optional measurements; basic counters remain available.
|
|
65
|
+
- RESET STATS clears accumulated statistics without stopping voices, cancelling queued work or changing the diagnostic switch. The next callback applies render-owned resets.
|
|
66
|
+
|
|
67
|
+
The panel shows active/peak/spatial/tail voices, pending commands, replacements, request/publication rejections, priority drops, callback load, stereo output peak and backend underruns. It displays `n/a` for unmeasured or unavailable values, keeping them distinct from zero. Signal windows need about 200 ms of output after enabling. Native snapshots also include RMS, limiter reduction, sample rate, buffer and latency fields; consult the [complete field reference](../../references/api.md#getstats) when integrating a full diagnostic view.
|
|
68
|
+
|
|
69
|
+
Render load divides callback elapsed time by the audio budget for that block; it does not measure total app CPU. The panel multiplies the native fraction by 100, so a reading of 1.20% means that fraction of the block budget, not 120%.
|
|
70
|
+
|
|
71
|
+
Even with zero voices, the stream renders silent blocks and runs the output/limiter and any enabled diagnostics. Expect a small, changing baseline. The two decimal places are display formatting and do not guarantee that precision.
|
|
72
|
+
|
|
73
|
+
Compare readings on the same device with the same configuration and load; simulator and phone readings are not equivalent. Android backend metrics are best-effort. This iOS backend has no underrun/buffer/latency measurement, and a clean counter cannot establish sound quality.
|
|
74
|
+
|
|
75
|
+
## Checks and limits
|
|
76
|
+
|
|
77
|
+
Run these focused checks from the module repository root:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
node tests/documentation_regression.js
|
|
81
|
+
node --test tests/example_app_regression.js
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The example regression executes its real action callbacks with simulated Titanium UI/audio boundaries. It covers rejection feedback, placement/bypass, session restart and gain preservation, diagnostic cleanup and close-before-start. It does not render native audio or establish layout, perceived elevation, silent-mode behavior or sound quality. Use the device checklist above, including headphones and an output-route change, before claiming those results.
|