@maccesar/titools 5.2.3 → 5.2.5
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/README.md +96 -87
- package/docs/examples.md +10 -3
- package/package.json +2 -2
- package/skills/ti-synthengine/SKILL.md +50 -18
- package/skills/ti-synthengine/assets/example/README.md +19 -6
- package/skills/ti-synthengine/assets/example/app.js +69 -12
- package/skills/ti-synthengine/assets/index.d.ts +106 -0
- package/skills/ti-synthengine/references/advanced-examples.md +34 -9
- package/skills/ti-synthengine/references/api.md +327 -246
- package/skills/ti-synthengine/references/audio-engine.md +28 -14
- package/skills/ti-synthengine/references/audio-pipeline-validation.md +1 -1
- package/skills/ti-synthengine/references/examples.md +5 -5
- package/skills/ti-synthengine/references/guide.md +40 -21
- package/skills/ti-synthengine/references/instruments-and-effects.md +164 -0
- package/skills/ti-synthengine/references/native-tone-repetition-validation.md +59 -0
- package/skills/ti-synthengine/references/native-variation-proposal.md +182 -0
- package/skills/ti-synthengine/references/native-variation-validation.md +63 -0
- package/skills/ti-synthengine/references/native-variation.md +285 -0
- package/skills/ti-synthengine/references/recipes-interaction.md +3 -1
- package/skills/ti-synthengine/references/recipes.md +3 -2
- package/skills/ti-synthengine/references/recommendations.md +5 -5
- package/skills/ti-synthengine/references/sound-design.md +18 -16
- package/skills/ti-synthengine/references/source-notes.md +54 -37
- package/skills/ti-synthengine/references/source-snapshot.json +188 -144
- package/skills/ti-synthengine/references/stats-performance.md +1 -1
- package/skills/ti-synthengine/references/troubleshooting.md +43 -35
|
@@ -1,24 +1,28 @@
|
|
|
1
|
-
> Source snapshot: official TiSynthEngine
|
|
1
|
+
> Source snapshot: official TiSynthEngine documentation at commit `ec04f4e634075c41b55f66279eabcd78b9652d58` (2026-11-02). Published module 1.1.0; public API 1.1.0. Upstream `documentation/api.md` SHA-256: `b58d60cf38a96157e523722d1f9cb9508f785cc2de9c2c1ff306e328c77df9dc`.
|
|
2
2
|
|
|
3
3
|
# API reference
|
|
4
4
|
|
|
5
5
|
Module id: `ti.synthengine`
|
|
6
6
|
|
|
7
|
-
Public API version: `1.
|
|
7
|
+
Public API version: `1.1.0`
|
|
8
8
|
|
|
9
|
-
Android and iOS expose the same
|
|
9
|
+
Android and iOS expose the same public methods, one event and waveform values. Option objects are strict: an unknown key is rejected with `unsupported_option`. Reported metadata and rejection diagnostics have platform differences; this reference does not promise sample-identical rendering between Android and iOS.
|
|
10
10
|
|
|
11
11
|
<!-- TOC-START -->
|
|
12
12
|
## Contents
|
|
13
13
|
|
|
14
|
+
- [Native attack variation (package 1.1.0)](#native-attack-variation-package-110)
|
|
14
15
|
- [Return values](#return-values)
|
|
15
16
|
- [`getDefaults()`](#getdefaults)
|
|
16
17
|
- [Limits](#limits)
|
|
17
18
|
- [`start(options)`](#startoptions)
|
|
18
19
|
- [`noteOn(options)`](#noteonoptions)
|
|
19
20
|
- [`noteOff(options)`](#noteoffoptions)
|
|
20
|
-
- [`
|
|
21
|
+
- [`updateNote(options)`](#updatenoteoptions)
|
|
22
|
+
- [`updateVoice(options)` (deprecated)](#updatevoiceoptions-deprecated)
|
|
21
23
|
- [`playTone(options)`](#playtoneoptions)
|
|
24
|
+
- [`repeatTone(options)`](#repeattoneoptions)
|
|
25
|
+
- [Finite-tone repetition](#finite-tone-repetition)
|
|
22
26
|
- [Native sequence transport](#native-sequence-transport)
|
|
23
27
|
- [`setMasterProcessing(options)`](#setmasterprocessingoptions)
|
|
24
28
|
- [Additional voice modulation](#additional-voice-modulation)
|
|
@@ -31,17 +35,22 @@ Android and iOS expose the same nineteen methods, one event and waveform values.
|
|
|
31
35
|
- [Strict validation](#strict-validation)
|
|
32
36
|
- [Binaural front-plane positioning](#binaural-front-plane-positioning)
|
|
33
37
|
- [`getStats()`](#getstats)
|
|
34
|
-
- [`
|
|
38
|
+
- [`enableStats()` and `disableStats()`](#enablestats-and-disablestats)
|
|
39
|
+
- [`setStatsEnabled(enabled)` (deprecated)](#setstatsenabledenabled-deprecated)
|
|
35
40
|
- [`resetStats()`](#resetstats)
|
|
36
41
|
- [Routing and voice priority](#routing-and-voice-priority)
|
|
37
42
|
|
|
38
43
|
<!-- TOC-END -->
|
|
39
44
|
|
|
45
|
+
## Native attack variation (package 1.1.0)
|
|
46
|
+
|
|
47
|
+
The optional `variation` dictionary is accepted by `playTone`, `repeatTone`, `playChord`, `noteOn`, sequence `voice` and step `overrides`. Version 1.1.0 reports public API `1.1.0`. Both platforms advertise `capabilities.variation: true` and `variationSchemaVersion: 1`; consumers must require both before sending the dictionary. The published 1.0.2 packages do not support it. See [native variation](native-variation.md) for fields, source restrictions, seeds and examples. Native `amount` is linear; Studio divides its displayed percentage by 100. `updateNote` rejects the dictionary. An override replaces the whole inherited dictionary, and an amount-zero dictionary still validates its ranges.
|
|
48
|
+
|
|
40
49
|
## Return values
|
|
41
50
|
|
|
42
|
-
`start`, `playTone`, `playChord`, `noteOn`, `noteOff`, `updateVoice`, `setVolume`, `setTempo`, `updateSequence`, `stopSequence` and `setMasterProcessing` return a Boolean. `playSequence` returns a positive sequence identifier, or 0 when rejected. `true` means the request was accepted. `false` means validation failed, the engine was unavailable, or the native command queue was full.
|
|
51
|
+
`start`, `playTone`, `playChord`, `noteOn`, `noteOff`, `updateNote`, `updateVoice`, `updateTone`, `stopTone`, `setVolume`, `setTempo`, `updateSequence`, `stopSequence` and `setMasterProcessing` return a Boolean. `repeatTone` returns a positive tone identifier, or 0 when rejected. Its required `intervalMs` is an integer from 1 to 60,000 ms. `playSequence` returns a positive sequence identifier, or 0 when rejected. `true` means the request was accepted. `false` means validation failed, the engine was unavailable, or the native command queue was full.
|
|
43
52
|
|
|
44
|
-
`setStatsEnabled` also
|
|
53
|
+
`enableStats`, `disableStats` and the deprecated `setStatsEnabled` also return Boolean acceptance. `stopAll`, `resetStats` and `shutdown` do not return a value. `getDefaults` returns the contract object described below. `getStats` returns a new statistics snapshot. `getSequenceState` returns the applied sequence state or `null`.
|
|
45
54
|
|
|
46
55
|
## `getDefaults()`
|
|
47
56
|
|
|
@@ -51,11 +60,13 @@ Returns the installed contract without starting the audio stream.
|
|
|
51
60
|
var contract = synth.getDefaults()
|
|
52
61
|
```
|
|
53
62
|
|
|
54
|
-
The shared result has this shape; Android adds the platform metadata described below:
|
|
63
|
+
The shared result in version 1.1.0 has this shape; Android adds the platform metadata described below. Published 1.0.2 packages retain the core contract but omit the variation capability/schema fields:
|
|
55
64
|
|
|
56
65
|
```javascript
|
|
57
66
|
{
|
|
58
|
-
apiVersion: '1.
|
|
67
|
+
apiVersion: '1.1.0',
|
|
68
|
+
capabilities: { variation: true, toneRepetition: true },
|
|
69
|
+
variationSchemaVersion: 1,
|
|
59
70
|
defaults: {
|
|
60
71
|
maxVoices: 8,
|
|
61
72
|
maxSequences: 1,
|
|
@@ -116,49 +127,51 @@ The shared result has this shape; Android adds the platform metadata described b
|
|
|
116
127
|
|
|
117
128
|
`fmDepthEnd`, `detunes`, `spatialX` and `spatialY` have no reported default: their presence changes how the call is interpreted. Supplying a spatial coordinate enables binaural; the other coordinate then defaults to 0 internally. The maximum frequency is `sampleRate * 0.45`. Before the stream opens, the reported fallback is 19,845 Hz. Read the object again after `start()` if the precise device limit matters.
|
|
118
129
|
|
|
119
|
-
|
|
130
|
+
In version 1.1.0, both platforms report `capabilities.variation: true` and `variationSchemaVersion: 1`. Android also reports `nativeSequence`, `masterProcessing` and `modulations` capability flags and `limits.stepDurationMs`. iOS omits those three older flags and `limits.stepDurationMs` while implementing the corresponding methods and millisecond sequences. Published 1.0.2 packages do not advertise variation; their iOS metadata has no `capabilities` map. Detect a required core method with `typeof synth.playSequence === 'function'` (and the other methods your feature needs); require the capability/schema pair specifically for variation. Both platforms report `limits.maxSequences`, `limits.priority` and `limits.effectSend`. `limits.stepDuration` is in beats on both platforms; millisecond sequences accept `4000 / sampleRate` through 60,000 even when `limits.stepDurationMs` is absent.
|
|
120
131
|
|
|
121
132
|
## Limits
|
|
122
133
|
|
|
123
134
|
All ranges include their endpoints. `getDefaults().limits` uses `{ min, max }` objects. Sweep targets and array elements share the corresponding base range: `panEnd`/`pans[]` use `pan`, `frequencyEnd` accepts 0 through the frequency maximum, but only targets of at least 1 Hz enable a sweep (values below 1 disable it), `noiseRateEnd` uses `noiseRate`, `filterHzEnd` uses `filterHz` plus disabled value 0, `fmDepthEnd` uses `fmDepth`, and `detunes[]` uses `detune`. The sample-count key is `waveTableSamples`; there is no `limits.waveTable` object.
|
|
124
135
|
|
|
125
|
-
| Field |
|
|
126
|
-
| --------------------------- |
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
| `
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
| `
|
|
150
|
-
| `
|
|
151
|
-
| `
|
|
152
|
-
| `
|
|
153
|
-
| `
|
|
154
|
-
| `
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
157
|
-
| `
|
|
158
|
-
| `
|
|
159
|
-
| `
|
|
160
|
-
| `
|
|
161
|
-
| `
|
|
136
|
+
| Field | Minimum | Maximum | Unit or rule |
|
|
137
|
+
| --------------------------- | ------------------: | ------------------: | ------------------------------------------------------------------------- |
|
|
138
|
+
| `maxToneRepetitions` | 1 | 32 | fixed independent repetition capacity |
|
|
139
|
+
| `intervalMs` | 1 | 60,000 | integer milliseconds between finite-tone attacks |
|
|
140
|
+
| `maxSequences` | 1 | 4 | preallocated sequence capacity |
|
|
141
|
+
| `priority` | 0 | 3 | integer admission priority |
|
|
142
|
+
| `effectSend` | 0 | 1 | explicit processed share |
|
|
143
|
+
| `maxVoices` | 1 | 32 | integer voices |
|
|
144
|
+
| `frequency` | 1 | `sampleRate * 0.45` | Hz |
|
|
145
|
+
| `duration` | 1 | 60,000 | integer ms, including timed-event duration |
|
|
146
|
+
| `attack` | 0 | 2,000 | integer ms; must be less than duration |
|
|
147
|
+
| `release` | 0 | 4,000 | integer ms; must fit after attack |
|
|
148
|
+
| `volume` | 0 | 2 | event or master multiplier |
|
|
149
|
+
| `waveType` | 0 | 5 | integer waveform value |
|
|
150
|
+
| `sequenceSteps` | 1 | 512 | object steps |
|
|
151
|
+
| `pan`, `panEnd`, `pans[]` | -1 | 1 | left to right |
|
|
152
|
+
| `spatialX`, `spatialY` | -1 | 1 | initial binaural direction; omitted unless enabled |
|
|
153
|
+
| `panSpread` | 0 | 1 | chord stereo width |
|
|
154
|
+
| `frequencyEnd` | 0 | `sampleRate * 0.45` | Hz; values below 1 disable the sweep |
|
|
155
|
+
| `lfoFreq` | 0 | 20,000 | Hz; 0 disables vibrato |
|
|
156
|
+
| `lfoDepth` | 0 | 20,000 | Hz |
|
|
157
|
+
| `noiseRate`, `noiseRateEnd` | 0 | `sampleRate * 0.45` | Hz; 0 selects white noise or disables the sweep |
|
|
158
|
+
| `lowPassHz` | 0 | `sampleRate * 0.45` | Hz; 0 disables the filter |
|
|
159
|
+
| `pulseWidth` | 0.05 | 0.95 | fraction of a square-wave cycle |
|
|
160
|
+
| `pulseWidthEnd` | 0 or 0.05 | 0.95 | 0 disables the sweep |
|
|
161
|
+
| `waveTable` | 2 samples | 64 samples | each value must be from -1 to 1; count range is `limits.waveTableSamples` |
|
|
162
|
+
| `bitDepth` | 0 or 2 | 16 | integer bits; 0 disables quantization |
|
|
163
|
+
| `bpm` | 20 | 300 | beats per minute |
|
|
164
|
+
| `swing` | -0.75 | 0.75 | alternating timing offset |
|
|
165
|
+
| `stepDuration` | `20 / sampleRate` | 300 | beats; returned by both platforms |
|
|
166
|
+
| `stepDurationMs` | `4000 / sampleRate` | 60,000 | ms; returned by Android only, accepted in ms sequences on both |
|
|
167
|
+
| `decay` | 0 | 4,000 | integer ms; `attack` plus `decay` must fit in the event |
|
|
168
|
+
| `sustain` | 0 | 1 | level held after the decay |
|
|
169
|
+
| `filterHz` | 20 | `sampleRate * 0.45` | Hz |
|
|
170
|
+
| `filterHzEnd` | 0 or 20 | `sampleRate * 0.45` | Hz; 0 disables the sweep |
|
|
171
|
+
| `filterQ` | 0.5 | 10 | resonance |
|
|
172
|
+
| `fmRatio` | 0.1 | 16 | modulator frequency divided by carrier frequency |
|
|
173
|
+
| `fmDepth`, `fmDepthEnd` | 0 | 10 | modulation index in radians |
|
|
174
|
+
| `detune`, `detunes[]` | -1200 | 1200 | cents |
|
|
162
175
|
|
|
163
176
|
## `start(options)`
|
|
164
177
|
|
|
@@ -166,7 +179,7 @@ Starts the native stream. Calling it again while the engine is running returns `
|
|
|
166
179
|
|
|
167
180
|
| Key | Type | Default | Description |
|
|
168
181
|
| --------------- | ------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
169
|
-
| `maxSequences`
|
|
182
|
+
| `maxSequences` | integer | `1` | Preallocated simultaneous sequence capacity, from 1 to 4. |
|
|
170
183
|
| `maxVoices` | integer | `8` | Size of the voice pool, from 1 to 32. |
|
|
171
184
|
| `mixingProfile` | string | `conservative` | `conservative`, `balanced`, `speakerSafe` or `raw`. Matching is case-insensitive. |
|
|
172
185
|
| `audioSession` | string | `playback` | iOS session category: `playback` or `ambient`. Matching is case-insensitive. Android validates the value and does not change its output. |
|
|
@@ -179,30 +192,31 @@ On iOS, `playback` ignores the silent switch and interrupts other apps' audio. `
|
|
|
179
192
|
|
|
180
193
|
## `noteOn(options)`
|
|
181
194
|
|
|
182
|
-
Starts a sustained native voice. Detect `typeof synth.noteOn === 'function'`, `noteOff` and `
|
|
195
|
+
Starts a sustained native voice. Detect `typeof synth.noteOn === 'function'`, `noteOff` and `updateNote` before enabling their controls; the current `apiVersion` is `1.1.0`. There is no duration limit and no JavaScript timer holds the note.
|
|
183
196
|
|
|
184
|
-
| Field
|
|
185
|
-
|
|
|
186
|
-
| `voiceId`
|
|
187
|
-
| `frequency`, `note`
|
|
197
|
+
| Field | Rule |
|
|
198
|
+
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
199
|
+
| `voiceId` | Required positive integer, 1-2,147,483,647, supplied by the app. |
|
|
200
|
+
| `frequency`, `note` | Optional mutually exclusive pitch; default 440 Hz, same ranges as playTone. |
|
|
188
201
|
| `attack`, `decay`, `sustain`, `release` | ADSR configuration for this attack; release begins only on noteOff. Same individual ranges as playTone, without a duration budget. |
|
|
189
|
-
| `volume`
|
|
190
|
-
| `waveType`
|
|
191
|
-
| `pan`
|
|
192
|
-
| `lfoFreq`, `lfoDepth`
|
|
193
|
-
| `noiseRate`, `lowPassHz`
|
|
194
|
-
| `pulseWidth`
|
|
195
|
-
| `waveTable`
|
|
196
|
-
| `bitDepth`
|
|
197
|
-
| `filterType`
|
|
198
|
-
| `filterHz`, `filterQ`
|
|
199
|
-
| `fmRatio`, `fmDepth`
|
|
200
|
-
| `detune`
|
|
201
|
-
| `spatialX`, `spatialY`
|
|
202
|
-
| `modulations`
|
|
203
|
-
| `bus`
|
|
204
|
-
| `effectSend`
|
|
205
|
-
| `priority`
|
|
202
|
+
| `volume` | Initial voice level, 0-2; default 1. |
|
|
203
|
+
| `waveType` | One of the six waveTypes; fixed for this attack. |
|
|
204
|
+
| `pan` | Initial stereo position, −1…1. Conflicts with spatial coordinates. |
|
|
205
|
+
| `lfoFreq`, `lfoDepth` | Initial vibrato, 0-20,000 Hz; default 0. |
|
|
206
|
+
| `noiseRate`, `lowPassHz` | Initial noise clock / one-pole cutoff, 0 through the frequency maximum; default 0. |
|
|
207
|
+
| `pulseWidth` | Initial square-wave duty cycle, 0.05-0.95; default 0.5. |
|
|
208
|
+
| `waveTable` | Fixed table of 2-64 samples in −1…1; required for WAVETABLE. |
|
|
209
|
+
| `bitDepth` | Fixed amplitude quantization, 0 or integer 2-16; default 0. |
|
|
210
|
+
| `filterType` | Fixed none/lowpass/highpass/bandpass; default none. |
|
|
211
|
+
| `filterHz`, `filterQ` | Initial cutoff and Q; a non-none filter type is required. |
|
|
212
|
+
| `fmRatio`, `fmDepth` | Initial sine FM; same rules and ranges as playTone. |
|
|
213
|
+
| `detune` | Initial pitch offset in cents, −1200…1200; default 0. |
|
|
214
|
+
| `spatialX`, `spatialY` | Initial binaural position in −1…1; omitted for stereo. |
|
|
215
|
+
| `modulations` | Up to two native LFOs; see Additional voice modulation. |
|
|
216
|
+
| `bus` | Category: music, effects (default), ui or ambience. |
|
|
217
|
+
| `effectSend` | Optional explicit processed share 0-1, replacing category selection. |
|
|
218
|
+
| `priority` | Integer admission priority 0-3, default 0. |
|
|
219
|
+
| `variation` | Optional attack-only ranges; see Native attack variation. |
|
|
206
220
|
|
|
207
221
|
No `duration` or temporal `*End` targets are accepted. Source, table, filter type and envelope configuration require a new attack; compatible position controls can be updated. Other initial defaults and cross-field validation rules match `playTone`.
|
|
208
222
|
|
|
@@ -214,28 +228,28 @@ Repeating a public sustained note can inherit the oscillator phase and pre-envel
|
|
|
214
228
|
|
|
215
229
|
## `noteOff(options)`
|
|
216
230
|
|
|
217
|
-
| Field
|
|
218
|
-
|
|
|
231
|
+
| Field | Rule |
|
|
232
|
+
| --------- | ------------------------------------------- |
|
|
219
233
|
| `voiceId` | Required positive integer, 1-2,147,483,647. |
|
|
220
234
|
|
|
221
235
|
Begins release from the current level, including during attack or decay. Repeated release requests never restart or lengthen a release. An ended or stolen ID is a no-op. `true` reports validation and queue publication, not proof of an audible voice. On `false` from a full queue, an instrument should retry twice at 16 ms intervals, then shut down and report failure if release still cannot be published.
|
|
222
236
|
|
|
223
|
-
## `
|
|
224
|
-
|
|
225
|
-
| Field
|
|
226
|
-
|
|
|
227
|
-
| `voiceId`
|
|
228
|
-
| `frequency`, `note`
|
|
229
|
-
| `volume`
|
|
230
|
-
| `filterHz`, `filterQ`
|
|
231
|
-
| `lfoFreq`, `lfoDepth`
|
|
232
|
-
| `pulseWidth`
|
|
233
|
-
| `fmRatio`, `fmDepth`
|
|
234
|
-
| `modulations`
|
|
235
|
-
| `noiseRate`, `lowPassHz` | Live noise clock/one-pole cutoff; 0 means white noise/bypass.
|
|
236
|
-
| `pan`
|
|
237
|
-
| `spatialX`, `spatialY`
|
|
238
|
-
| `effectSend`
|
|
237
|
+
## `updateNote(options)`
|
|
238
|
+
|
|
239
|
+
| Field | Rule |
|
|
240
|
+
| ------------------------ | -------------------------------------------------------------------------------- |
|
|
241
|
+
| `voiceId` | Required positive integer, 1-2,147,483,647. |
|
|
242
|
+
| `frequency`, `note` | Mutually exclusive target pitch. Same frequency/note ranges as playTone. |
|
|
243
|
+
| `volume` | Target voice level, 0-2. |
|
|
244
|
+
| `filterHz`, `filterQ` | Target cutoff/Q; only for a voice that started with a resonant filter. |
|
|
245
|
+
| `lfoFreq`, `lfoDepth` | Target vibrato rate/deviation, 0-20,000 Hz. |
|
|
246
|
+
| `pulseWidth` | Target duty cycle, 0.05-0.95; only for a square voice. |
|
|
247
|
+
| `fmRatio`, `fmDepth` | Target FM ratio 0.1-16 / depth 0-10; only for a sine voice. |
|
|
248
|
+
| `modulations` | Replace up to two native LFOs; empty array disables them while preserving phase. |
|
|
249
|
+
| `noiseRate`, `lowPassHz` | Live noise clock/one-pole cutoff; 0 means white noise/bypass. |
|
|
250
|
+
| `pan` | Target stereo position for a voice started without spatial coordinates. |
|
|
251
|
+
| `spatialX`, `spatialY` | Target position for a spatial held voice; omitted coordinate stays unchanged. |
|
|
252
|
+
| `effectSend` | Explicit processed share, 0-1, overriding category selection. |
|
|
239
253
|
|
|
240
254
|
At least one change is required. An incompatible change rejects the entire request when the ID is known; unknown/ended IDs accept publication as a no-op. The callback also checks source compatibility before applying a command. Changed continuous parameters ramp linearly from their current values over 10 ms. New targets retarget that ramp without restarting oscillator phase or the envelope. Unchanged parameters retain their current ramps. This also works during release.
|
|
241
255
|
|
|
@@ -243,68 +257,130 @@ Pitch updates are absolute: an initial `detune` is already included in the note'
|
|
|
243
257
|
|
|
244
258
|
```javascript
|
|
245
259
|
if (typeof synth.noteOn !== 'function' || typeof synth.noteOff !== 'function' ||
|
|
246
|
-
typeof synth.
|
|
260
|
+
typeof synth.updateNote !== 'function') throw new Error('Sustained voices unavailable')
|
|
247
261
|
if (!synth.noteOn({ voiceId: 1, note: 'C4', attack: 8, decay: 180, sustain: 0.6,
|
|
248
262
|
release: 300, filterType: 'lowpass', filterHz: 1200, volume: 0.25 })) {
|
|
249
263
|
throw new Error('Note rejected')
|
|
250
264
|
}
|
|
251
|
-
synth.
|
|
265
|
+
synth.updateNote({ voiceId: 1, filterHz: 3600 })
|
|
252
266
|
synth.noteOff({ voiceId: 1 })
|
|
253
267
|
```
|
|
254
268
|
|
|
255
|
-
Use `stopAll()` for panic: it stops every sequence, fades sounding voices and invalidates effect histories. Owner close should call `shutdown()` after cancelling app-owned UI/retry timers.
|
|
269
|
+
Use `stopAll()` for panic: it stops every sequence, cancels finite-tone repetitions, fades sounding voices and invalidates effect histories. Owner close should call `shutdown()` after cancelling app-owned UI/retry timers.
|
|
256
270
|
|
|
257
271
|
|
|
272
|
+
## `updateVoice(options)` (deprecated)
|
|
273
|
+
|
|
274
|
+
Compatibility alias of [`updateNote(options)`](#updatenoteoptions), with identical validation, partial updates, 10 ms transitions, `voiceId` ownership and ended/stolen-ID behavior. Use `updateNote` in new code. The alias remains available without repeated runtime warnings or a scheduled removal date.
|
|
275
|
+
|
|
258
276
|
## `playTone(options)`
|
|
259
277
|
|
|
278
|
+
`playTone` always plays one finite pitch and returns Boolean acceptance. Its closed options reject `intervalMs` with `false`. Use `repeatTone` for native repetition.
|
|
279
|
+
|
|
260
280
|
Plays one pitch. It uses 440 Hz when neither pitch field is present. Note names accept C through B or DO, RE, MI, FA, SOL, LA, SI and TI, followed by optional `#` or lowercase `b` and one octave digit from 0 to 9. Letters are case-insensitive, the omitted octave is 4, and A4 is 440 Hz. A valid named pitch is limited to the active frequency ceiling when rendered; an out-of-range numeric `frequency` is rejected.
|
|
261
281
|
|
|
262
|
-
| Key | Type
|
|
263
|
-
| --------------- |
|
|
264
|
-
| `frequency` | number
|
|
265
|
-
| `note` | string
|
|
266
|
-
| `duration` | integer
|
|
267
|
-
| `attack` | integer
|
|
268
|
-
| `release` | integer
|
|
269
|
-
| `volume` | number
|
|
270
|
-
| `waveType` | integer
|
|
271
|
-
| `pan` | number
|
|
272
|
-
| `panEnd` | number
|
|
273
|
-
| `frequencyEnd` | number
|
|
274
|
-
| `lfoFreq` | number
|
|
275
|
-
| `lfoDepth` | number
|
|
276
|
-
| `noiseRate` | number
|
|
277
|
-
| `noiseRateEnd` | number
|
|
278
|
-
| `lowPassHz` | number
|
|
279
|
-
| `pulseWidth` | number
|
|
280
|
-
| `pulseWidthEnd` | number
|
|
281
|
-
| `waveTable` | number[]
|
|
282
|
-
| `bitDepth` | integer
|
|
283
|
-
| `decay` | integer
|
|
284
|
-
| `sustain` | number
|
|
285
|
-
| `filterType` | string
|
|
286
|
-
| `filterHz` | number
|
|
287
|
-
| `filterHzEnd` | number
|
|
288
|
-
| `filterQ` | number
|
|
289
|
-
| `fmRatio` | number
|
|
290
|
-
| `fmDepth` | number
|
|
291
|
-
| `fmDepthEnd` | number
|
|
292
|
-
| `detune` | number
|
|
293
|
-
| `spatialX` | number
|
|
294
|
-
| `spatialY` | number
|
|
295
|
-
| `bus`
|
|
296
|
-
| `effectSend`
|
|
297
|
-
| `priority`
|
|
282
|
+
| Key | Type | Default | Description |
|
|
283
|
+
| --------------- | ---------- | ------------: | ------------------------------------------------------------------------------------------ |
|
|
284
|
+
| `frequency` | number | `440` | Starting frequency in Hz. Cannot be combined with `note`. |
|
|
285
|
+
| `note` | string | none | Note name. Cannot be combined with `frequency`. |
|
|
286
|
+
| `duration` | integer | `500` | Total event length in ms. |
|
|
287
|
+
| `attack` | integer | `50` | Fade-in time in ms. |
|
|
288
|
+
| `release` | integer | `50` | Fade-out time in ms. |
|
|
289
|
+
| `volume` | number | `1` | Event level multiplier. |
|
|
290
|
+
| `waveType` | integer | `SINE` | One of the six waveform values. |
|
|
291
|
+
| `pan` | number | `0` | Starting stereo position. |
|
|
292
|
+
| `panEnd` | number | same as `pan` | Ending stereo position; omission keeps the position fixed. |
|
|
293
|
+
| `frequencyEnd` | number | `0` | Ending frequency; values below 1 keep the starting pitch. |
|
|
294
|
+
| `lfoFreq` | number | `0` | Vibrato rate in Hz. |
|
|
295
|
+
| `lfoDepth` | number | `0` | Vibrato depth in Hz. |
|
|
296
|
+
| `noiseRate` | number | `0` | Noise update rate; 0 produces a fresh value per sample. |
|
|
297
|
+
| `noiseRateEnd` | number | `0` | Ending noise update rate; 0 disables the sweep. |
|
|
298
|
+
| `lowPassHz` | number | `0` | Per-voice low-pass cutoff; 0 bypasses it. |
|
|
299
|
+
| `pulseWidth` | number | `0.5` | Duty cycle for `SQUARE`. |
|
|
300
|
+
| `pulseWidthEnd` | number | `0` | Ending duty cycle; 0 disables the sweep. |
|
|
301
|
+
| `waveTable` | number[] | none | Required for `WAVETABLE`; 2 to 64 normalized samples. |
|
|
302
|
+
| `bitDepth` | integer | `0` | Amplitude quantization from 2 to 16 bits; 0 disables it. |
|
|
303
|
+
| `decay` | integer | `0` | Milliseconds to fall from full level to `sustain` after the attack. |
|
|
304
|
+
| `sustain` | number | `1` | Level held after the decay, from 0 to 1. |
|
|
305
|
+
| `filterType` | string | `none` | `none`, `lowpass`, `highpass` or `bandpass`. Case-insensitive. |
|
|
306
|
+
| `filterHz` | number | `1000` | Cutoff, or center for `bandpass`, in Hz. |
|
|
307
|
+
| `filterHzEnd` | number | `0` | Ending cutoff; 0 disables the sweep. |
|
|
308
|
+
| `filterQ` | number | `0.7071` | Resonance, from 0.5 to 10. |
|
|
309
|
+
| `fmRatio` | number | `1` | Modulator frequency as a multiple of the carrier. |
|
|
310
|
+
| `fmDepth` | number | `0` | Modulation index; 0 leaves FM off unless `fmDepthEnd` is set. |
|
|
311
|
+
| `fmDepthEnd` | number | none | Ending index. Omit it for no sweep; 0 is a valid target. |
|
|
312
|
+
| `detune` | number | `0` | Pitch offset in cents, applied to `frequency` and `frequencyEnd`. |
|
|
313
|
+
| `spatialX` | number | omitted | Fixed left/right binaural direction; see [positioning](#binaural-front-plane-positioning). |
|
|
314
|
+
| `spatialY` | number | omitted | Fixed below/above binaural direction. |
|
|
315
|
+
| `bus` | string | `effects` | Category: music, effects, ui or ambience. |
|
|
316
|
+
| `effectSend` | number | omitted | Explicit processed share 0-1; replaces category selection. |
|
|
317
|
+
| `priority` | integer | `0` | Admission priority 0-3; higher voices are protected. |
|
|
318
|
+
| `variation` | dictionary | omitted | Optional attack-only ranges; see Native attack variation. |
|
|
298
319
|
|
|
299
320
|
Omitted attack/release values are shortened to fit an event smaller than the default envelope. Explicit values must satisfy the documented envelope rules. `getDefaults()` reports the baseline defaults, not these per-event adjustments.
|
|
300
321
|
|
|
301
|
-
|
|
302
|
-
zero attack/release values to
|
|
303
|
-
|
|
304
|
-
zero-edge rendering. Held notes
|
|
322
|
+
In the current 1.0.2/1.1.0 implementations, the iOS timed tone/chord command builder
|
|
323
|
+
initially rounds accepted zero attack/release values to one sample, before
|
|
324
|
+
trimming them to the event duration budget. Android retains zero samples.
|
|
325
|
+
Validator acceptance does not imply identical zero-edge rendering. Held notes
|
|
326
|
+
have the separately documented 3 ms minimum.
|
|
305
327
|
|
|
306
328
|
The controls from `decay` to `detune` are described in [Expressive controls](#expressive-controls), including the rules that tie them together.
|
|
307
329
|
|
|
330
|
+
## `repeatTone(options)`
|
|
331
|
+
|
|
332
|
+
Returns a positive `toneId`, or 0 on rejection. Requires integer `intervalMs` from 1 to 60,000 ms; missing or invalid intervals return 0. All remaining options use the same finite-tone contract as `playTone`, with the same admission, envelope, sweeps, gain and routes. Repetition uses neither sustained nor sequence voices.
|
|
333
|
+
|
|
334
|
+
Always supply exact integer milliseconds. The current Apple validator tolerates extremely near-integer values: for example, `1.0000000001` is accepted and converted to `1`, while Android rejects it. This is a native validation discrepancy, not an additional supported interval format; do not rely on that tolerance.
|
|
335
|
+
|
|
336
|
+
| Key | Type | Rule |
|
|
337
|
+
| ----------------- | -------- | ------------------------------------------------- |
|
|
338
|
+
| `intervalMs` | integer | Required; 1-60,000 ms |
|
|
339
|
+
| Other tone fields | as above | Same fields and validation as `playTone(options)` |
|
|
340
|
+
|
|
341
|
+
## Finite-tone repetition
|
|
342
|
+
|
|
343
|
+
Both platforms advertise `capabilities.toneRepetition: true`, `limits.maxToneRepetitions: { min: 1, max: 32 }` and `limits.intervalMs: { min: 1, max: 60000 }`. These 32 repetition slots are independent of the four sequence slots; attacks still share the configured voice pool. Reserve for overlaps, active voices and release tails if the application promises no stealing. Native priority policy remains in force. A positive `toneId` accepts the repeating recipe; it does not guarantee admission of every future attack.
|
|
344
|
+
|
|
345
|
+
The first attack occurs at the first render opportunity. Later attacks use the audio sample clock, retain fractional samples across intervals and blocks, and do not follow `setTempo`. If voice capacity rejects an attack, it is dropped without catch-up and without consuming a variation selection. Every admitted attack finishes its original duration even after `stopTone`.
|
|
346
|
+
|
|
347
|
+
```javascript
|
|
348
|
+
var toneId = synth.repeatTone({ frequency: 1380, frequencyEnd: 340,
|
|
349
|
+
duration: 105, attack: 2, release: 40, waveType: synth.getDefaults().waveTypes.SQUARE,
|
|
350
|
+
volume: 0.1, intervalMs: 150 })
|
|
351
|
+
if (!toneId) throw new Error('Repeating tone rejected')
|
|
352
|
+
// Edits enter at the next scheduled attack, without adding an immediate attack.
|
|
353
|
+
if (!synth.updateTone({ toneId: toneId, intervalMs: 120, volume: 0.08 })) {
|
|
354
|
+
throw new Error('Tone edit rejected')
|
|
355
|
+
}
|
|
356
|
+
// On release/cancel/preset change/owner close:
|
|
357
|
+
if (!synth.stopTone({ toneId: toneId })) throw new Error('Tone stop rejected')
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Independent JavaScript calls remain supported and always keep their Boolean return through `playTone`. A game can fire in response to events or deliberately schedule a fixed count of standalone calls, for example:
|
|
361
|
+
|
|
362
|
+
```javascript
|
|
363
|
+
var recipe = { frequency: 880, duration: 100, attack: 2, release: 30, volume: 0.1 }
|
|
364
|
+
function fireStandalone() {
|
|
365
|
+
if (!synth.playTone(recipe)) Ti.API.warn('Independent tone rejected')
|
|
366
|
+
}
|
|
367
|
+
fireStandalone()
|
|
368
|
+
setTimeout(fireStandalone, 200)
|
|
369
|
+
setTimeout(fireStandalone, 400)
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Those three calls use JavaScript timing and independent attack selection. For an ongoing native repetition, call `repeatTone` with `intervalMs` once and use its tone ID. Owner teardown must cancel any application timers it creates.
|
|
373
|
+
|
|
374
|
+
### `updateTone({ toneId, ...changes })`
|
|
375
|
+
|
|
376
|
+
Returns Boolean acceptance. Requires a known positive repetition identifier and at least one change. Accepts partial finite-tone options, including `intervalMs`, and merges them with the latest accepted recipe before validating the entire result. Supplying `note` replaces an earlier `frequency`; supplying `frequency` replaces an earlier `note`. Supplying both is invalid. Invalid edits leave the last accepted recipe intact.
|
|
377
|
+
|
|
378
|
+
An accepted edit affects the next already scheduled attack, preserving its deadline. The new interval determines separation after that attack. Active attacks retain their original configuration. A supplied `variation` dictionary replaces the whole previous dictionary; `{ amount: 0 }` disables future variation. Each repetition retains its own seed and admitted-attack counter. Edits preserve the stream; changing its seed restarts that succession. Unknown or retired IDs reject edits.
|
|
379
|
+
|
|
380
|
+
### `stopTone({ toneId })`
|
|
381
|
+
|
|
382
|
+
Returns Boolean acceptance. Accepts only a known positive repetition identifier. Cancels future attacks at the next render block, including before the first attack, while admitted finite voices finish completely. Stop publication is independent of the ordinary command queue and remains available when that queue is full. Unknown or retired IDs return `false`. There is no `toneend` event. Identifiers are never reused during the module lifetime, including shutdown/start. `stopAll`, shutdown and destruction invalidate all repetitions and their pending edits.
|
|
383
|
+
|
|
308
384
|
## Native sequence transport
|
|
309
385
|
|
|
310
386
|
`start({ maxSequences: 1 })` preallocates capacity for 1-4 independent sequences; the default is 1. All sequences, timed sounds and held notes share one renderer and the same pool of at most 32 voices. No sequence or category reserves voices.
|
|
@@ -317,23 +393,23 @@ Returns Boolean acceptance. BPM is 20-300, initially 120. The change applies at
|
|
|
317
393
|
|
|
318
394
|
Returns a positive `sequenceId` on accepted atomic publication, or 0 on rejection. Identifiers never repeat during the module's lifetime, including across shutdown/start. Publication acceptance precedes application by the callback. Capacity exhaustion, unavailable banks or invalid options reject the complete operation.
|
|
319
395
|
|
|
320
|
-
| Root field
|
|
321
|
-
|
|
|
322
|
-
| `steps`
|
|
323
|
-
| `timeUnit`
|
|
324
|
-
| `stepDuration`
|
|
325
|
-
| `gate`
|
|
326
|
-
| `loop`
|
|
327
|
-
| `swing`
|
|
328
|
-
| `mode`
|
|
329
|
-
| `tuning`
|
|
330
|
-
| `detune`
|
|
331
|
-
| `voice`
|
|
332
|
-
| `bus`, `effectSend`, `priority` | Inherited routing/admission settings; may also appear in `voice` or on each step.
|
|
396
|
+
| Root field | Rule |
|
|
397
|
+
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
398
|
+
| `steps` | Required array of 1-512 step objects. |
|
|
399
|
+
| `timeUnit` | `beats` (default) or `ms`, fixed for this sequence. One beat is a quarter note. |
|
|
400
|
+
| `stepDuration` | Default 0.25 beats or 100 ms; maximum 300 beats or 60,000 ms. Minimum is four output samples at the highest tempo and maximum swing: `20 / sampleRate` beats or `4000 / sampleRate` ms. |
|
|
401
|
+
| `gate` | 0.01-1, default 0.8; fraction of the effective interval before note release begins. |
|
|
402
|
+
| `loop` | Boolean, default false. |
|
|
403
|
+
| `swing` | −0.75…0.75, default 0. For intervals A/B, shifts `swing * min(A, B)` from the second interval to the first, preserving the pair's total length. Applies at the next pair. |
|
|
404
|
+
| `mode` | `normal` (default), `up`, `down` or `updown`. Arpeggios traverse sounding steps in pitch order; rests participate only in normal mode. |
|
|
405
|
+
| `tuning` | A4 frequency, 220-880 Hz, default 440. |
|
|
406
|
+
| `detune` | MIDI pitch offset in cents, −1200…1200, default 0. |
|
|
407
|
+
| `voice` | Inherited sound settings, listed below. |
|
|
408
|
+
| `bus`, `effectSend`, `priority` | Inherited routing/admission settings; may also appear in `voice` or on each step. |
|
|
333
409
|
|
|
334
410
|
Each step contains exactly one representation: `notes` (1-32 MIDI integers, 12-119), `frequencies` (1-32 frequencies in Hz), or `rest: true`. Duplicate pitches produce unison voices. Optional `duration` changes the interval until the next attack; `length` explicitly sets note duration until release begins and replaces gate for that step. Both use the sequence's time unit (at most 300 beats or 60,000 ms). Note length is positive, at least 0.000001; intervals use the four-sample scheduling minimum. Notes can overlap later attacks. Step `gate` overrides root gate. `overrides` merges shaping over root `voice`.
|
|
335
411
|
|
|
336
|
-
The `voice` and `overrides` dictionaries accept `attack`, `decay`, `sustain`, `release`, `volume`, `waveType`, `pan`, `panEnd`, `frequencyEnd`, `lfoFreq`, `lfoDepth`, `noiseRate`, `noiseRateEnd`, `lowPassHz`, `pulseWidth`, `pulseWidthEnd`, `waveTable`, `bitDepth`, `filterType`, `filterHz`, `filterHzEnd`, `filterQ`, `fmRatio`, `fmDepth`, `fmDepthEnd`, `spatialX`, `spatialY`, `modulations`, `bus`, `effectSend` and `
|
|
412
|
+
The `voice` and `overrides` dictionaries accept `attack`, `decay`, `sustain`, `release`, `volume`, `waveType`, `pan`, `panEnd`, `frequencyEnd`, `lfoFreq`, `lfoDepth`, `noiseRate`, `noiseRateEnd`, `lowPassHz`, `pulseWidth`, `pulseWidthEnd`, `waveTable`, `bitDepth`, `filterType`, `filterHz`, `filterHzEnd`, `filterQ`, `fmRatio`, `fmDepth`, `fmDepthEnd`, `spatialX`, `spatialY`, `modulations`, `bus`, `effectSend`, `priority` and `variation`. A step variation replaces the entire inherited dictionary. Individual tone parameter ranges and source/filter compatibility rules apply. ADSR remains in milliseconds and has no step-duration budget. Sweeps traverse the note's length and hold their destination throughout release. Chord compensation is fixed at attack; later notes never rescale existing voices.
|
|
337
413
|
|
|
338
414
|
### `updateSequence({ sequenceId, ...changes })`
|
|
339
415
|
|
|
@@ -366,16 +442,16 @@ Selected audio follows fixed input gain → chorus → ping-pong delay → rever
|
|
|
366
442
|
|
|
367
443
|
Requires a running engine and returns Boolean acceptance. Partial updates merge into the last accepted processing configuration, validate the complete result and publish atomically. Continuous controls ramp over 10 ms. Unknown fields, numeric booleans and non-finite values reject the whole edit. Detect method presence before use.
|
|
368
444
|
|
|
369
|
-
| Section
|
|
370
|
-
|
|
|
371
|
-
| Root
|
|
372
|
-
| Root
|
|
373
|
-
| `chorus`
|
|
374
|
-
| `delay`
|
|
375
|
-
| `reverb`
|
|
376
|
-
| `saturation` | `enabled`: false; `drive`: 1-4, initially 1; `mix`: 0-1, initially 1. Creative soft waveshaping that changes timbre.
|
|
445
|
+
| Section | Fields and initial values |
|
|
446
|
+
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
447
|
+
| Root | `applyTo`: array of `music`, `effects`, `ui`, `ambience` initially; empty selects none. |
|
|
448
|
+
| Root | `inputGain`: 0-4, initially 1. |
|
|
449
|
+
| `chorus` | `enabled`: false; `rate`: 0.05-5 Hz, initially 0.8; `depth`: 0-1, initially 0.4; `mix`: 0-1, initially 0.25. Stereo interpolated delay with offset modulation phases. |
|
|
450
|
+
| `delay` | `enabled`: false; `timeMs`: 20-2000, initially 250; `sync`: off; `feedback`: 0-0.85, initially 0.3; `mix`: 0-1, initially 0.25. Ping-pong feedback and crossfade between changed read positions, up to four seconds reserved. |
|
|
451
|
+
| `reverb` | `enabled`: false; `decay`: 0.2-8 seconds, initially 1.5; `damping`: 0-1, initially 0.5; `mix`: 0-1, initially 0.2. Stereo damped comb/allpass Schroeder network. |
|
|
452
|
+
| `saturation` | `enabled`: false; `drive`: 1-4, initially 1; `mix`: 0-1, initially 1. Creative soft waveshaping that changes timbre. |
|
|
377
453
|
|
|
378
|
-
Delay sync accepts `off`, `quarter`, `eighth`, `sixteenth`, `quarterTriplet`, `eighthTriplet` or `sixteenthTriplet`. Sync follows the native transport BPM, initially 120. Disabling an effect gradually closes its input and drains its tail, then restores exact bypass. Tails are bounded to 30 seconds with a final fade. `stopAll()` performs panic: it fades voices, stops the
|
|
454
|
+
Delay sync accepts `off`, `quarter`, `eighth`, `sixteenth`, `quarterTriplet`, `eighthTriplet` or `sixteenthTriplet`. Sync follows the native transport BPM, initially 120. Disabling an effect gradually closes its input and drains its tail, then restores exact bypass. Tails are bounded to 30 seconds with a final fade. `stopAll()` performs panic: it fades voices, stops the transport and invalidates effect histories in bounded work. `shutdown()` stops the stream and frees buffers outside the callback.
|
|
379
455
|
|
|
380
456
|
Processing uses one shared chain for the selected categories. `applyTo` is an array drawn from `music`, `effects`, `ui` and `ambience`; default all four. Each event or held voice uses `bus: 'effects'` by default. Optional `effectSend: 0…1` overrides category selection for that voice. Input gain and master volume remain global. Selected audio receives chorus, delay, reverb and optional saturation, then recombines with dry audio before one final limiter. Send changes ramp over 10 ms.
|
|
381
457
|
|
|
@@ -383,15 +459,15 @@ Defaults keep all effects and saturation disabled, input gain at unity, and pres
|
|
|
383
459
|
|
|
384
460
|
## Additional voice modulation
|
|
385
461
|
|
|
386
|
-
`noteOn` and `
|
|
462
|
+
`noteOn` and `updateNote` accept `modulations`, an array of up to two LFO objects. An empty array disables them. Omission on update preserves the previous configuration. Each object accepts only these fields:
|
|
387
463
|
|
|
388
|
-
| Field
|
|
389
|
-
|
|
|
390
|
-
| `wave`
|
|
464
|
+
| Field | Rule |
|
|
465
|
+
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
466
|
+
| `wave` | `sine` (default) or `triangle`. |
|
|
391
467
|
| `target` | Required: `filterHz`, `pulseWidth` or `fmDepth`. Requires an active resonant filter, square source or sine source respectively. An explicit FM ratio with zero base depth is permitted when an FM-target LFO is enabled. |
|
|
392
|
-
| `rate`
|
|
393
|
-
| `depth`
|
|
394
|
-
| `sync`
|
|
468
|
+
| `rate` | 0-20 Hz, default 1. Zero permits a stationary free-running phase. |
|
|
469
|
+
| `depth` | 0-1, default 0; scales up to four cutoff octaves, 0.45 PWM offset or ten FM-index units. Two contributions sum with safe clamping. |
|
|
470
|
+
| `sync` | Same musical values as delay; default off. Synced rates follow native tempo (up to 30 Hz at 300 BPM in sixteenth-note triplets). |
|
|
395
471
|
|
|
396
472
|
Edits preserve oscillator/LFO phases. Continuous modulation contributions ramp over 10 ms; cutoff stays within 20 Hz and the frequency maximum, PWM within 0.05-0.95, FM index within 0-10. Initial modulations may also be inherited by sequence voices and overridden per step. These two slots coexist with the independent `lfoFreq`/`lfoDepth` pitch vibrato; they are not accepted by timed tones, chords .
|
|
397
473
|
|
|
@@ -399,35 +475,36 @@ Edits preserve oscillator/LFO phases. Continuous modulation contributions ramp o
|
|
|
399
475
|
|
|
400
476
|
Starts 1 to 32 pitches as one atomic event. Exactly one pitch array is required.
|
|
401
477
|
|
|
402
|
-
| Key | Type
|
|
403
|
-
| ------------- |
|
|
404
|
-
| `frequencies` | number[]
|
|
405
|
-
| `notes` | string[]
|
|
406
|
-
| `duration` | integer
|
|
407
|
-
| `attack` | integer
|
|
408
|
-
| `release` | integer
|
|
409
|
-
| `volume` | number
|
|
410
|
-
| `waveType` | integer
|
|
411
|
-
| `panSpread` | number
|
|
412
|
-
| `pans` | number[]
|
|
413
|
-
| `noiseRate` | number
|
|
414
|
-
| `lowPassHz` | number
|
|
415
|
-
| `pulseWidth` | number
|
|
416
|
-
| `waveTable` | number[]
|
|
417
|
-
| `bitDepth` | integer
|
|
418
|
-
| `decay` | integer
|
|
419
|
-
| `sustain` | number
|
|
420
|
-
| `filterType` | string
|
|
421
|
-
| `filterHz` | number
|
|
422
|
-
| `filterQ` | number
|
|
423
|
-
| `fmRatio` | number
|
|
424
|
-
| `fmDepth` | number
|
|
425
|
-
| `detunes` | number[]
|
|
426
|
-
| `spatialX` | number
|
|
427
|
-
| `spatialY` | number
|
|
428
|
-
| `bus`
|
|
429
|
-
| `effectSend`
|
|
430
|
-
| `priority`
|
|
478
|
+
| Key | Type | Default | Description |
|
|
479
|
+
| ------------- | ---------- | -------------------: | -------------------------------------------------------------- |
|
|
480
|
+
| `frequencies` | number[] | required alternative | Frequencies in Hz. |
|
|
481
|
+
| `notes` | string[] | required alternative | Note names. |
|
|
482
|
+
| `duration` | integer | `500` | Total chord length in ms. |
|
|
483
|
+
| `attack` | integer | `50` | Fade-in time in ms. |
|
|
484
|
+
| `release` | integer | `50` | Fade-out time in ms. |
|
|
485
|
+
| `volume` | number | `1` | Chord event level. |
|
|
486
|
+
| `waveType` | integer | `SINE` | Waveform for every voice. |
|
|
487
|
+
| `panSpread` | number | `0` | Even stereo spread from 0 to 1. |
|
|
488
|
+
| `pans` | number[] | none | Per-note pan positions; overrides spread for supplied entries. |
|
|
489
|
+
| `noiseRate` | number | `0` | Fixed update rate for noise voices. |
|
|
490
|
+
| `lowPassHz` | number | `0` | Fixed low-pass cutoff for every voice. |
|
|
491
|
+
| `pulseWidth` | number | `0.5` | Fixed square-wave duty cycle. |
|
|
492
|
+
| `waveTable` | number[] | none | Required when `waveType` is `WAVETABLE`. |
|
|
493
|
+
| `bitDepth` | integer | `0` | Fixed amplitude quantization; 0 disables it. |
|
|
494
|
+
| `decay` | integer | `0` | Fixed decay time shared by every voice. |
|
|
495
|
+
| `sustain` | number | `1` | Fixed sustain level shared by every voice. |
|
|
496
|
+
| `filterType` | string | `none` | Fixed filter type for every voice. |
|
|
497
|
+
| `filterHz` | number | `1000` | Fixed cutoff or center in Hz. |
|
|
498
|
+
| `filterQ` | number | `0.7071` | Fixed resonance. |
|
|
499
|
+
| `fmRatio` | number | `1` | Fixed modulator ratio. |
|
|
500
|
+
| `fmDepth` | number | `0` | Fixed modulation index; sine voices only. |
|
|
501
|
+
| `detunes` | number[] | none | Per-note offsets in cents, matched to the pitch array. |
|
|
502
|
+
| `spatialX` | number | omitted | Shared fixed left/right binaural direction. |
|
|
503
|
+
| `spatialY` | number | omitted | Shared fixed below/above binaural direction. |
|
|
504
|
+
| `bus` | string | `effects` | Category: music, effects, ui or ambience. |
|
|
505
|
+
| `effectSend` | number | omitted | Explicit processed share 0-1; replaces category selection. |
|
|
506
|
+
| `priority` | integer | `0` | Admission priority 0-3; higher voices are protected. |
|
|
507
|
+
| `variation` | dictionary | omitted | Optional attack-only ranges; see Native attack variation. |
|
|
431
508
|
|
|
432
509
|
`pans` and `detunes` cannot contain more entries than the pitch array, and missing detune entries count as 0. Missing `pans` entries use the position computed from `panSpread`, or 0 when no spread is set. `playChord` does not accept sweep, vibrato or `detune` fields.
|
|
433
510
|
|
|
@@ -538,32 +615,32 @@ event=validation_warning method=playTone key=duraton reason=unsupported_option a
|
|
|
538
615
|
|
|
539
616
|
Common reasons include:
|
|
540
617
|
|
|
541
|
-
| Reason | Meaning
|
|
542
|
-
| ---------------------------------------- |
|
|
543
|
-
| `unsupported_option` | The option name is not part of that method or step.
|
|
544
|
-
| `not_object` | A sequence step or options dictionary is not an object.
|
|
545
|
-
| `non_numeric_or_non_finite` | A numeric field is the wrong type, `NaN` or infinite.
|
|
546
|
-
| `not_integer` | An integer field contains a fractional number.
|
|
547
|
-
| `out_of_range` | A number falls outside the documented range.
|
|
548
|
-
| `missing_required` | A required pitch array or `WAVETABLE` sample array is missing.
|
|
549
|
-
| `not_string`, `not_array`, `not_boolean` | A field has the wrong container or primitive type.
|
|
550
|
-
| `invalid_note` | A note name cannot be parsed.
|
|
551
|
-
| `unsupported_note_value` | A note value is not one of the ten supported values.
|
|
552
|
-
| `unsupported_value` | `mixingProfile`, `audioSession` or `filterType` is not one of the listed strings.
|
|
553
|
-
| `invalid_sample_count` | `waveTable` has fewer than 2 or more than 64 samples.
|
|
554
|
-
| `missing_pitch_or_rest` | A sounding event has no pitch and is not a rest.
|
|
555
|
-
| `conflicting_pitch_fields` | A call or step provides more than one pitch source.
|
|
618
|
+
| Reason | Meaning |
|
|
619
|
+
| ---------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
620
|
+
| `unsupported_option` | The option name is not part of that method or step. |
|
|
621
|
+
| `not_object` | A sequence step or options dictionary is not an object. |
|
|
622
|
+
| `non_numeric_or_non_finite` | A numeric field is the wrong type, `NaN` or infinite. |
|
|
623
|
+
| `not_integer` | An integer field contains a fractional number. |
|
|
624
|
+
| `out_of_range` | A number falls outside the documented range. |
|
|
625
|
+
| `missing_required` | A required pitch array or `WAVETABLE` sample array is missing. |
|
|
626
|
+
| `not_string`, `not_array`, `not_boolean` | A field has the wrong container or primitive type. |
|
|
627
|
+
| `invalid_note` | A note name cannot be parsed. |
|
|
628
|
+
| `unsupported_note_value` | A note value is not one of the ten supported values. |
|
|
629
|
+
| `unsupported_value` | `mixingProfile`, `audioSession` or `filterType` is not one of the listed strings. |
|
|
630
|
+
| `invalid_sample_count` | `waveTable` has fewer than 2 or more than 64 samples. |
|
|
631
|
+
| `missing_pitch_or_rest` | A sounding event has no pitch and is not a rest. |
|
|
632
|
+
| `conflicting_pitch_fields` | A call or step provides more than one pitch source. |
|
|
556
633
|
| `conflicting_spatial_fields` | Spatial coordinates are combined with stereo pan fields, including inherited sequence voice values. |
|
|
557
|
-
| `invalid_voice_count` | A chord has fewer than 1 or more than 32 pitches.
|
|
634
|
+
| `invalid_voice_count` | A chord has fewer than 1 or more than 32 pitches. |
|
|
558
635
|
| `invalid_step_count` | The step array has fewer than 1 or more than 512 entries. |
|
|
559
|
-
| `too_many_values` | `pans` or `detunes` is longer than the chord.
|
|
560
|
-
| `attack_greater_or_equal_duration` | An explicit attack leaves no time for the event.
|
|
561
|
-
| `release_exceeds_remaining_duration` | An explicit release does not fit after attack.
|
|
562
|
-
| `decay_exceeds_remaining_duration` | `attack` plus `decay` does not fit in the event.
|
|
563
|
-
| `sustain_without_decay` | `sustain` is below 1 while `decay` is 0.
|
|
564
|
-
| `filter_type_required` | A filter key is set while `filterType` is `none`.
|
|
565
|
-
| `fm_requires_sine` | FM is active on a waveform other than `SINE`.
|
|
566
|
-
| `fm_depth_required` | `fmRatio` is set while FM is off.
|
|
636
|
+
| `too_many_values` | `pans` or `detunes` is longer than the chord. |
|
|
637
|
+
| `attack_greater_or_equal_duration` | An explicit attack leaves no time for the event. |
|
|
638
|
+
| `release_exceeds_remaining_duration` | An explicit release does not fit after attack. |
|
|
639
|
+
| `decay_exceeds_remaining_duration` | `attack` plus `decay` does not fit in the event. |
|
|
640
|
+
| `sustain_without_decay` | `sustain` is below 1 while `decay` is 0. |
|
|
641
|
+
| `filter_type_required` | A filter key is set while `filterType` is `none`. |
|
|
642
|
+
| `fm_requires_sine` | FM is active on a waveform other than `SINE`. |
|
|
643
|
+
| `fm_depth_required` | `fmRatio` is set while FM is off. |
|
|
567
644
|
|
|
568
645
|
Explicit values are not clamped. Read `getDefaults().limits` when accepting user input and decide in the app whether to reject or constrain it.
|
|
569
646
|
|
|
@@ -594,33 +671,33 @@ Use `typeof synth.getStats === 'function'` to check that the expected module is
|
|
|
594
671
|
|
|
595
672
|
Returns a new snapshot without resetting counters. Available before start and after shutdown. Occupancy is the last completed render block; queued commands are read at query time. No audio-thread allocation, locks or waiting are added.
|
|
596
673
|
|
|
597
|
-
| Field | Meaning
|
|
598
|
-
| -------------------------- |
|
|
599
|
-
| `activeVoices` | Occupied primary slots, including binaural FIR draining.
|
|
600
|
-
| `maxVoices` | Configured primary-slot capacity (default 8 before start).
|
|
601
|
-
| `peakActiveVoices` | Highest primary occupancy since reset/start, including peaks between queries.
|
|
602
|
-
| `tailVoices` | External fade tails from replacement or `stopAll`, excluding primary FIR drain.
|
|
603
|
-
| `spatialVoices` | Spatial primary slots, including FIR draining; excludes external tails.
|
|
604
|
-
| `voiceStealCount` | Primary replacements while all slots are occupied.
|
|
605
|
-
| `rejectedRequestCount` | Counted API rejections, including sequence-publication rejection; not a complete rejected-call tally on every native path.
|
|
606
|
-
| `rejectedRequestsByReason` | `{ validation, engineStopped, queueFull }`; sum equals the recorded rejection total.
|
|
607
|
-
| `priorityDropCount`
|
|
608
|
-
| `rejectedPublicationCount` | Rejected sequence publications due to capacity or bank pressure.
|
|
609
|
-
| `pendingCommands` | Published entries awaiting the renderer; chord notes count separately, future scheduler steps are excluded.
|
|
610
|
-
| `sampleRate` | Current native rate, or the last rate after shutdown; 44100 before start.
|
|
611
|
-
| `callbackFrames` | Frames processed in the most recent callback; 0 before start/after shutdown.
|
|
612
|
-
| `renderLoad` | Last callback elapsed seconds / (`callbackFrames / sampleRate`); may exceed 1.
|
|
613
|
-
| `peakRenderLoad` | Maximum callback load since diagnostics were enabled or statistics reset; accumulates across signal windows.
|
|
614
|
-
| `outputPeakDbFS` | `{ left, right }` peaks of final float output in the latest completed approximately 200 ms window.
|
|
615
|
-
| `outputRmsDbFS` | `{ left, right }` RMS of that same window.
|
|
616
|
-
| `preLimiterPeakDb`
|
|
617
|
-
| `maxLimiterReductionDb`
|
|
618
|
-
| `limiterReductionDb` | Maximum limiter attenuation in that window, as a positive dB magnitude.
|
|
619
|
-
| `underrunCount` | Android Oboe accumulated backend xruns since reset/start when supported; otherwise `null`.
|
|
620
|
-
| `bufferFrames` | Android Oboe output buffer size; otherwise `null`. This is distinct from `callbackFrames`.
|
|
621
|
-
| `estimatedOutputLatencyMs` | Android timestamp-based stream-to-DAC estimate, when valid; otherwise `null` (always `null` on this iOS backend).
|
|
622
|
-
|
|
623
|
-
|
|
674
|
+
| Field | Meaning |
|
|
675
|
+
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
676
|
+
| `activeVoices` | Occupied primary slots, including binaural FIR draining. |
|
|
677
|
+
| `maxVoices` | Configured primary-slot capacity (default 8 before start). |
|
|
678
|
+
| `peakActiveVoices` | Highest primary occupancy since reset/start, including peaks between queries. |
|
|
679
|
+
| `tailVoices` | External fade tails from replacement or `stopAll`, excluding primary FIR drain. |
|
|
680
|
+
| `spatialVoices` | Spatial primary slots, including FIR draining; excludes external tails. |
|
|
681
|
+
| `voiceStealCount` | Primary replacements while all slots are occupied. |
|
|
682
|
+
| `rejectedRequestCount` | Counted API rejections, including sequence-publication rejection; not a complete rejected-call tally on every native path. |
|
|
683
|
+
| `rejectedRequestsByReason` | `{ validation, engineStopped, queueFull }`; sum equals the recorded rejection total. |
|
|
684
|
+
| `priorityDropCount` | Events/chords dropped because eligible voices could not accommodate them. |
|
|
685
|
+
| `rejectedPublicationCount` | Rejected sequence publications due to capacity or bank pressure. |
|
|
686
|
+
| `pendingCommands` | Published entries awaiting the renderer; chord notes count separately, future scheduler steps are excluded. |
|
|
687
|
+
| `sampleRate` | Current native rate, or the last rate after shutdown; 44100 before start. |
|
|
688
|
+
| `callbackFrames` | Frames processed in the most recent callback; 0 before start/after shutdown. |
|
|
689
|
+
| `renderLoad` | Last callback elapsed seconds / (`callbackFrames / sampleRate`); may exceed 1. |
|
|
690
|
+
| `peakRenderLoad` | Maximum callback load since diagnostics were enabled or statistics reset; accumulates across signal windows. |
|
|
691
|
+
| `outputPeakDbFS` | `{ left, right }` peaks of final float output in the latest completed approximately 200 ms window. |
|
|
692
|
+
| `outputRmsDbFS` | `{ left, right }` RMS of that same window. |
|
|
693
|
+
| `preLimiterPeakDb` | Maximum native peak before the limiter since reset, in dBFS; diagnostics required. |
|
|
694
|
+
| `maxLimiterReductionDb` | Maximum native limiter attenuation since reset, in dB; diagnostics required. A brief intervention persists across UI polls. |
|
|
695
|
+
| `limiterReductionDb` | Maximum limiter attenuation in that window, as a positive dB magnitude. |
|
|
696
|
+
| `underrunCount` | Android Oboe accumulated backend xruns since reset/start when supported; otherwise `null`. |
|
|
697
|
+
| `bufferFrames` | Android Oboe output buffer size; otherwise `null`. This is distinct from `callbackFrames`. |
|
|
698
|
+
| `estimatedOutputLatencyMs` | Android timestamp-based stream-to-DAC estimate, when valid; otherwise `null` (always `null` on this iOS backend). |
|
|
699
|
+
|
|
700
|
+
In the current 1.0.2/1.1.0 implementations, iOS early rejections in tempo/sequence operations and a
|
|
624
701
|
stopped `setMasterProcessing` call can bypass rejection counters. Incompatible
|
|
625
702
|
held spatial-mode or modulation updates also have uncounted iOS returns.
|
|
626
703
|
Android counts more of these cases, but an unknown/retired `stopSequence` return
|
|
@@ -631,9 +708,13 @@ rejected request. These counters are diagnostics; the API return is authoritativ
|
|
|
631
708
|
|
|
632
709
|
Render load is a fraction: multiply by 100 for a percentage. For example, `0.012` is 1.2% of the block budget, while `1.0` is 100%. An open stream still renders silent blocks, including output/limiter work and enabled signal measurements, so no active voices does not imply zero load. Callback elapsed time varies with scheduling and system activity; displayed decimal places do not establish measurement accuracy. Compare the same configuration on the same device. Percentages from a simulator and a phone do not provide a direct performance comparison.
|
|
633
710
|
|
|
634
|
-
## `
|
|
711
|
+
## `enableStats()` and `disableStats()`
|
|
712
|
+
|
|
713
|
+
Both return Boolean acceptance. `enableStats()` enables optional timing and signal measurements; `disableStats()` disables them. Default `false`. Enabling starts a new diagnostic window, without restarting audio. Calling `enableStats()` again also starts a fresh window. Disabling hides timing and signal fields immediately. Basic counters remain available in either mode. The setting persists across shutdown/start, while a new engine starts with fresh counters.
|
|
714
|
+
|
|
715
|
+
## `setStatsEnabled(enabled)` (deprecated)
|
|
635
716
|
|
|
636
|
-
|
|
717
|
+
Compatibility alias for the same statistics logic. Requires a Boolean and returns Boolean acceptance. Use `enableStats()` or `disableStats()` in new code. It remains available without repeated runtime deprecation warnings or a scheduled removal date.
|
|
637
718
|
|
|
638
719
|
## `resetStats()`
|
|
639
720
|
|
|
@@ -641,11 +722,11 @@ Returns nothing. Resets accumulated counters and maxima without stopping sounds,
|
|
|
641
722
|
|
|
642
723
|
```javascript
|
|
643
724
|
// Optional diagnostics; poll at 5 Hz and stop the timer with the owner.
|
|
644
|
-
if (synth.
|
|
725
|
+
if (synth.enableStats()) {
|
|
645
726
|
var statsTimer = setInterval(function () {
|
|
646
727
|
Ti.API.info(JSON.stringify(synth.getStats()))
|
|
647
728
|
}, 200)
|
|
648
|
-
// Later: clearInterval(statsTimer); synth.
|
|
729
|
+
// Later: clearInterval(statsTimer); synth.disableStats()
|
|
649
730
|
}
|
|
650
731
|
```
|
|
651
732
|
|
|
@@ -653,4 +734,4 @@ if (synth.setStatsEnabled(true)) {
|
|
|
653
734
|
|
|
654
735
|
`playTone`, `playChord`, `noteOn` and sequence voices accept `bus`, `effectSend` and `priority`. Categories are `music`, `effects` (default), `ui` and `ambience`. An omitted send follows `setMasterProcessing({ applyTo })`; an explicit 0-1 send replaces that selection. Priority is integer 0-3, default 0. When the pool fills, the lowest eligible priority is replaced first; a lower-priority event cannot steal a higher-priority voice. Existing release/age tie-breakers remain. Chords are admitted or dropped completely; no voices are reserved. `getStats().priorityDropCount` counts these drops; `rejectedPublicationCount` counts unavailable sequence capacity/banks separately from output diagnostics.
|
|
655
736
|
|
|
656
|
-
`
|
|
737
|
+
`updateNote` also accepts `noiseRate`, `lowPassHz`, `pan`, `spatialX`, `spatialY` and `effectSend`, with 10 ms transitions. Noise rate 0 means white noise; low-pass 0 means bypass. Noise phase, oscillator phase and spatial history survive compatible edits. Pan updates require a stereo voice; coordinates require a voice started with spatial coordinates. An omitted coordinate retains its previous value. The source/filter type still requires a new attack. Updates are generation-scoped so queued old commands cannot change a later attack sharing the public voice ID.
|