@maccesar/titools 5.2.4 → 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -32
- package/agents/ti-pro.md +1 -1
- package/commands/ti-audit.md +1 -1
- package/docs/examples.md +15 -8
- package/package.json +1 -1
- package/skills/ti-synthengine/SKILL.md +62 -92
- package/skills/ti-synthengine/assets/example/README.md +51 -54
- package/skills/ti-synthengine/assets/example/app.js +96 -57
- package/skills/ti-synthengine/assets/example/lib/sequenceOwner.js +39 -40
- package/skills/ti-synthengine/assets/example/lib/soundPreset.js +34 -0
- package/skills/ti-synthengine/assets/index.d.ts +226 -0
- package/skills/ti-synthengine/references/advanced-examples.md +12 -12
- package/skills/ti-synthengine/references/api.md +125 -33
- package/skills/ti-synthengine/references/audio-engine.md +24 -59
- package/skills/ti-synthengine/references/examples.md +64 -7
- package/skills/ti-synthengine/references/guide.md +69 -63
- package/skills/ti-synthengine/references/instruments-and-effects.md +34 -27
- package/skills/ti-synthengine/references/native-variation.md +92 -51
- package/skills/ti-synthengine/references/recipes-interaction.md +26 -19
- package/skills/ti-synthengine/references/recipes.md +19 -15
- package/skills/ti-synthengine/references/recommendations.md +14 -14
- package/skills/ti-synthengine/references/sound-api.md +197 -0
- package/skills/ti-synthengine/references/sound-design.md +11 -11
- package/skills/ti-synthengine/references/source-notes.md +62 -147
- package/skills/ti-synthengine/references/troubleshooting.md +22 -24
- package/skills/ti-synthengine/references/upgrade-2.0.0.md +40 -0
- package/skills/ti-synthengine/references/android-sim80-correction-evidence.zip +0 -0
- package/skills/ti-synthengine/references/android-sim80-correction.json +0 -162
- package/skills/ti-synthengine/references/audio-pipeline-validation.md +0 -19
- package/skills/ti-synthengine/references/bypass-physical-recheck-evidence.zip +0 -0
- package/skills/ti-synthengine/references/frontier-android-evidence.zip +0 -0
- package/skills/ti-synthengine/references/frontier-ipad-evidence.zip +0 -0
- package/skills/ti-synthengine/references/frontier-physical-validation.json +0 -1918
- package/skills/ti-synthengine/references/native-variation-proposal.md +0 -182
- package/skills/ti-synthengine/references/native-variation-validation.md +0 -63
- package/skills/ti-synthengine/references/performance-review-evidence.zip +0 -0
- package/skills/ti-synthengine/references/performance-review.json +0 -1146
- package/skills/ti-synthengine/references/physical-validation.json +0 -1457
- package/skills/ti-synthengine/references/source-snapshot.json +0 -463
- package/skills/ti-synthengine/references/stats-performance.json +0 -2992
- package/skills/ti-synthengine/references/stats-performance.md +0 -82
- package/skills/ti-synthengine/references/studio-validation.json +0 -6202
- package/skills/ti-synthengine/references/unified-bypass-performance.json +0 -22425
- package/skills/ti-synthengine/references/unified-validation.json +0 -314
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
> Source snapshot: official TiSynthEngine documentation at commit `
|
|
1
|
+
> Source snapshot: official TiSynthEngine documentation at commit `9d74aa45f84d3f2822d4aab76874efe37d81257f` (2026-11-03). Published module 2.0.0. Upstream `documentation/troubleshooting.md` SHA-256: `edf85de5fa08ead37820264f8381e1ef6e72d67c274fac0650dda723446dedbc`.
|
|
2
2
|
|
|
3
3
|
# Troubleshooting
|
|
4
4
|
|
|
5
|
-
Start with the method's documented return value and the native log. Most
|
|
5
|
+
Start with the method's documented return value and the native log. Most requests that produce no sound are contract rejections or involve a stale binary or an engine that never started.
|
|
6
6
|
|
|
7
7
|
## A call returns `false`
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ For methods that emit structured validation warnings, inspect logcat or the Xcod
|
|
|
12
12
|
event=validation_warning method=playTone key=duraton reason=unsupported_option action=rejected value=200
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
Always check the return value: `playSequence` rejects with 0, while Boolean methods reject with `false`. Some sequence/control rejection paths do not emit a structured warning
|
|
15
|
+
Always check the return value: `playSequence` rejects with 0, while Boolean methods reject with `false`. Some sequence/control rejection paths do not emit a structured warning. The absence of a new log entry does not establish acceptance.
|
|
16
16
|
|
|
17
17
|
Common fixes:
|
|
18
18
|
|
|
@@ -43,31 +43,29 @@ An `overflow` warning means the command queue was full. Reduce the command burst
|
|
|
43
43
|
|
|
44
44
|
The envelope and filter rules apply to the final values of each sounding event. In a native sequence, each step's `overrides` merges over root `voice`: root `voice.sustain` is valid when every sounding step supplies compatible decay, and `voice.filterHz` needs a non-none filter type after merging. Timed tones/chords enforce their total-duration envelope budget; held and sequence ADSR has no sequence-interval budget. A `detune` that pushes the pitch, or `frequencyEnd`, outside the frequency range is rejected with `out_of_range`.
|
|
45
45
|
|
|
46
|
-
`fmDepthEnd: 0` is valid. It sweeps the index down to nothing. Omit the key
|
|
46
|
+
`fmDepthEnd: 0` is valid. It sweeps the index down to nothing. Omit the key when the index should not move; passing 0 sets a sweep target.
|
|
47
47
|
|
|
48
48
|
For the shaping controls, check the discontinuous disabled values as well as the numeric range: `bitDepth` accepts 0 or 2 through 16, and `pulseWidthEnd` accepts 0 or 0.05 through 0.95. A `waveTable` must contain only finite values from -1 to 1.
|
|
49
49
|
|
|
50
|
-
## The installed
|
|
50
|
+
## The installed module version is wrong
|
|
51
51
|
|
|
52
52
|
Check the native binary at startup:
|
|
53
53
|
|
|
54
54
|
```javascript
|
|
55
|
-
var actual = synth.getDefaults().
|
|
56
|
-
if (actual !== '
|
|
57
|
-
throw new Error('Expected TiSynthEngine
|
|
55
|
+
var actual = synth.getDefaults().version
|
|
56
|
+
if (actual !== '2.0.0') {
|
|
57
|
+
throw new Error('Expected TiSynthEngine 2.0.0, found ' + actual)
|
|
58
58
|
}
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
`
|
|
61
|
+
`version` is the installed module version in both `getDefaults()` and `getContract()`. TiSynth has no independent API version. Pin both entries in `tiapp.xml` to the intended module version and rebuild the app so Titanium includes the new archive. For 2.0.0, the directories are:
|
|
62
62
|
|
|
63
63
|
```text
|
|
64
|
-
modules/android/ti.synthengine/
|
|
65
|
-
modules/iphone/ti.synthengine/
|
|
64
|
+
modules/android/ti.synthengine/2.0.0/
|
|
65
|
+
modules/iphone/ti.synthengine/2.0.0/
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
For binaural, also inspect `getDefaults().limits.spatialX` and `.spatialY`. Use the official packages to avoid stale development binaries. Copying the package does not update an already installed app: rebuild and reinstall it.
|
|
68
|
+
Check the required methods and capability/schema pair before using variation. For binaural, inspect `getDefaults().limits.spatialX` and `.spatialY`. Copying a package does not update an installed app: rebuild and reinstall it.
|
|
71
69
|
|
|
72
70
|
## Binaural does not change the position
|
|
73
71
|
|
|
@@ -79,15 +77,15 @@ Inspect the options sent to the native method as well as the settings screen:
|
|
|
79
77
|
- No stereo placement fields remain, even with value 0 or through pattern inheritance. Handle the Boolean return value.
|
|
80
78
|
- The installed contract reports both spatial limits and the device has the rebuilt app.
|
|
81
79
|
- Use headphones and one broadband event at a time; with binaural off, points with the same X use the same horizontal placement regardless of Y.
|
|
82
|
-
- Timed tones/chords and each sequence attack keep their specified position. A spatial held voice can move through `
|
|
80
|
+
- Timed tones/chords and each sequence attack keep their specified position. A spatial held voice can move through `updateNote({ voiceId, spatialX, spatialY })`; omitted coordinates retain their previous value, and the FIR ramps over 10 ms without clearing history. A stereo voice cannot be converted to spatial by an update.
|
|
83
81
|
|
|
84
82
|
The [integration guide](guide.md#integrate-binaural-in-a-2d-app) contains the JavaScript conversion and explains switch/slider behavior.
|
|
85
83
|
|
|
86
84
|
## Statistics are missing or show `null`
|
|
87
85
|
|
|
88
|
-
|
|
86
|
+
The 2.0.0 module includes statistics methods. Check `typeof synth.getStats`, `typeof synth.enableStats`, `typeof synth.disableStats` and `typeof synth.resetStats`; install the current packages, rebuild and reinstall the app if needed.
|
|
89
87
|
|
|
90
|
-
Basic voice/queue/rejection counters do not require diagnostics. Timing, output peak/RMS and limiter reduction require `
|
|
88
|
+
Basic voice/queue/rejection counters do not require diagnostics. Timing, output peak/RMS and limiter reduction require `enableStats()` and a measured callback/window. `null` means unmeasured or unavailable; keep it distinct from zero. The current iOS backend always reports `null` for underruns, output buffer size and estimated hardware latency. Android backend metrics are best-effort and independent of the diagnostic switch.
|
|
91
89
|
|
|
92
90
|
Read at a modest rate, such as 5 Hz, and stop polling and optional measurements when the diagnostic owner hides or closes. `getStats()` never resets counters; call `resetStats()` deliberately. See the [integration recipe](guide.md#read-engine-statistics).
|
|
93
91
|
|
|
@@ -151,7 +149,7 @@ Compare several devices before changing the synthesis globally. A resonance on o
|
|
|
151
149
|
|
|
152
150
|
## Audio changes after connecting headphones
|
|
153
151
|
|
|
154
|
-
|
|
152
|
+
The engine recovers routes automatically, but the sound crossing the hardware transition may end early. The operating system can also mute or fade the new route for a brief device-dependent interval. Wait for the route to settle and play a new sound; do not restart the app.
|
|
155
153
|
|
|
156
154
|
If later sounds remain silent, capture the Android or Xcode log around the route change. Confirm that no screen lifecycle handler called `shutdown()` at the same time.
|
|
157
155
|
|
|
@@ -168,7 +166,7 @@ If later sounds remain silent, capture the Android or Xcode log around the route
|
|
|
168
166
|
- Confirm the deployment target is iOS 15 or newer.
|
|
169
167
|
- Check whether another module changes `AVAudioSession` after startup.
|
|
170
168
|
- Test interruptions, phone calls, Bluetooth and route changes on hardware.
|
|
171
|
-
- Use the matching device or simulator slice from the
|
|
169
|
+
- Use the matching device or simulator slice from the 2.0.0 archive.
|
|
172
170
|
|
|
173
171
|
## What to include in a bug report
|
|
174
172
|
|
|
@@ -176,11 +174,11 @@ Include the platform, OS version, device model, Titanium SDK version, module ver
|
|
|
176
174
|
|
|
177
175
|
## Held notes, sequences or effects methods are missing
|
|
178
176
|
|
|
179
|
-
|
|
177
|
+
Use `createSound()` and its returned playback controls for held notes, repetitions and patterns. Detect `noteOn`/`noteOff`/`updateNote`, all four sequence methods and `setMasterProcessing` according to the feature needed. Install matching current Android/iOS packages, rebuild and reinstall the consumer app. A stale development binary may report the same version without the complete release API. See [capability detection](guide.md#detect-required-capabilities).
|
|
180
178
|
|
|
181
179
|
## A held voice does not release or update
|
|
182
180
|
|
|
183
|
-
Use the original positive `voiceId`, not the pitch or an ID that has already been reused. `noteOn` does not accept `duration` or temporal `*End` fields. `
|
|
181
|
+
Use the original positive `voiceId`, not the pitch or an ID that has already been reused. `noteOn` does not accept `duration` or temporal `*End` fields. `updateNote` cannot change source, filter type, table, quantization, ADSR or stereo-versus-spatial mode; restart with a new ID when those attack-time settings must change. Noise clock, one-pole cutoff, effect send and compatible stereo/spatial position support live edits. Changed continuous parameters ramp for 10 ms.
|
|
184
182
|
|
|
185
183
|
Check Boolean returns. A full public queue can reject `noteOff`; retry twice at 16 ms outside render, then shut down/report if still rejected. Cancel those retries on owner teardown. The [held motor example](advanced-examples.md#sustained-game-motor) implements this policy. Touch cancellation, pause and close need cleanup as well as normal key up.
|
|
186
184
|
|
|
@@ -198,7 +196,7 @@ Disabling effects closes input smoothly and lets bounded tails finish, then bypa
|
|
|
198
196
|
|
|
199
197
|
## A brief level dip is gone before the meter refreshes
|
|
200
198
|
|
|
201
|
-
Enable diagnostics, reset deliberately, then inspect `preLimiterPeakDb` and `maxLimiterReductionDb`. They retain the native pre-limiter peak and greatest attenuation since reset, including brief interventions between UI polls. `limiterReductionDb` is a window measurement and can return to zero sooner.
|
|
199
|
+
Enable diagnostics, reset deliberately, then inspect `preLimiterPeakDb` and `maxLimiterReductionDb`. They retain the native pre-limiter peak and greatest attenuation since reset, including brief interventions between UI polls. `limiterReductionDb` is a window measurement and can return to zero sooner. Disabled or unmeasured diagnostics return `null`. See [measurement example](advanced-examples.md#measure-peaks-and-limiter-reduction).
|
|
202
200
|
|
|
203
201
|
If accumulated attenuation remains near zero, investigate phase cancellation between repeated same-pitch oscillators, changing filters or the device speaker/protection path. Compatible released public held-note repetitions preserve predecessor phase; simultaneous unisons, timed calls and transport notes retain their existing phase behavior. Extra effects and resonance can consume headroom even when source gain is fixed. Compare matched levels through headphones and the physical speaker before changing the mix globally.
|
|
204
202
|
|
|
@@ -210,6 +208,6 @@ Compare one note with `SINE`, at a comfortable matched level, to distinguish the
|
|
|
210
208
|
|
|
211
209
|
## A variation dictionary is rejected or repeats the same sound
|
|
212
210
|
|
|
213
|
-
Check both `capabilities.variation === true` and `variationSchemaVersion === 1` before sending the property.
|
|
211
|
+
Check both `capabilities.variation === true` and `variationSchemaVersion === 1` before sending the property. Source restrictions and range ordering still apply at amount zero; near the frequency ceiling, validate tuning, detune, every chord pitch and active pitch endpoints together.
|
|
214
212
|
|
|
215
|
-
Repeated standalone calls with one explicit seed reproduce the selected parameters. Omit it for independent selections, or use a native sequence to retain an advancing stream across loops. A held voice samples only at attack, and `
|
|
213
|
+
Repeated standalone calls with one explicit seed reproduce the selected parameters. Omit it for independent selections, or use a native sequence to retain an advancing stream across loops. A held voice samples only at attack, and `updateNote` rejects `variation`. For a running sequence, clear an inherited root dictionary with a valid amount-zero replacement; omitting it from a revision retains the merged value. See the [complete examples and rules](native-variation.md).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
> Source snapshot: official TiSynthEngine documentation at commit `9d74aa45f84d3f2822d4aab76874efe37d81257f` (2026-11-03). Published module 2.0.0. Upstream `documentation/upgrade-2.0.0.md` SHA-256: `d25459ad28ec6fea2e40796d09aa0d6348b0f2a177cd79e3ef223fbe3ae23172`.
|
|
2
|
+
|
|
3
|
+
# Upgrade to TiSynth 2.0.0
|
|
4
|
+
|
|
5
|
+
TiSynth 2.0.0 separates reusable sound definitions from playback. Existing direct methods remain supported with their signatures, return values, identifiers, events and behavior. Use Sound objects for new code.
|
|
6
|
+
|
|
7
|
+
| Direct call | Sound interface |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| `playTone(options)` | A tone definition followed by `sound.play()` |
|
|
10
|
+
| `playChord(options)` | A chord definition followed by `sound.play()` |
|
|
11
|
+
| `noteOn({ voiceId, ... })` | `sound.noteOn()` or a held definition's `play()` |
|
|
12
|
+
| `updateNote({ voiceId, ... })`, `noteOff({ voiceId })` | Returned note control's `update()` and `noteOff()` |
|
|
13
|
+
| `repeatTone`, `updateTone`, `stopTone` | A repeat definition's `play()`, then the control's `update()` and `stop()` |
|
|
14
|
+
| `playSequence`, `updateSequence`, `stopSequence`, `getSequenceState` | A pattern definition's `play()`, then the control's `update()`, `stop()` and `getState()` |
|
|
15
|
+
| Global `sequenceend` with a `sequenceId` | The pattern control's `end` event with `{ reason }` |
|
|
16
|
+
| `setMasterProcessing(options)` | `setProcessing(options)` with the units below |
|
|
17
|
+
| `setVolume({ volume })`, `setTempo({ bpm })` | `setVolume(number)`, `setTempo(number)` |
|
|
18
|
+
|
|
19
|
+
Put synthesis fields in `sound` and pitch arrays, type and timing in `playback`. Direct `note` and `frequency` become one-element `notes` and `frequencies` arrays. Use flat execution overrides and nested `{ sound, playback }` dictionaries for stored revisions.
|
|
20
|
+
|
|
21
|
+
## Names and units
|
|
22
|
+
|
|
23
|
+
- Repetition `intervalMs` becomes `playback.interval`, still integer milliseconds.
|
|
24
|
+
- Pattern `stepDuration` becomes root `playback.interval`. Step `duration` becomes step `interval`; both keep the declared `timeUnit`, which defaults to beats. Step `length` keeps its sounding-length meaning.
|
|
25
|
+
- Pattern `voice` becomes root `sound`; step `overrides` becomes step `sound`. Root sequence detune belongs in root `sound.detune`.
|
|
26
|
+
- Processing delay `timeMs` becomes `time`, still milliseconds. Reverb `decay` changes from seconds in `setMasterProcessing()` to milliseconds in `setProcessing()`; multiply the value by 1000.
|
|
27
|
+
- Finite `duration` still includes release. ADSR remains milliseconds. Converting a finite event into a pattern requires a deliberate length/gate conversion and can change sweeps or chord gain.
|
|
28
|
+
- Replace runtime metadata `apiVersion` reads with `version`. There is one installed module version.
|
|
29
|
+
|
|
30
|
+
`setProcessing()` accepts `timeMs` as an input alias for delay, but it cannot coexist with `time`. Reverb decay remains milliseconds in this method. The direct processing method retains its own units.
|
|
31
|
+
|
|
32
|
+
## Ownership and errors
|
|
33
|
+
|
|
34
|
+
Keep each Sound control with the interaction that owns it. Controls hide native playback identifiers and become invalid on shutdown; reusable definitions survive. Finite tones and chords return acceptance without a stop control.
|
|
35
|
+
|
|
36
|
+
Sound validation throws descriptive errors. Operational playback rejection returns `false`. Direct methods keep their existing return contracts. `Sound.set()` validates an atomic revision for future executions and leaves active executions unchanged.
|
|
37
|
+
|
|
38
|
+
The direct aliases `updateVoice` and `setStatsEnabled` remain supported. New code uses note controls and `enableStats()` / `disableStats()`.
|
|
39
|
+
|
|
40
|
+
The [Sound reference](sound-api.md) documents current use. The [validation report](https://github.com/macCesar/TiSynthEngine/blob/9d74aa45f84d3f2822d4aab76874efe37d81257f/documentation/sound-api-validation.md) records the comparison against the source baseline.
|
|
Binary file
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schemaVersion": 1,
|
|
3
|
-
"date": "2026-10-23",
|
|
4
|
-
"moduleVersion": "1.0.0 beta",
|
|
5
|
-
"status": "corrected-for-tested-Sim80-headphone-case",
|
|
6
|
-
"acceptanceComplete": false,
|
|
7
|
-
"listening": {
|
|
8
|
-
"accepted": true,
|
|
9
|
-
"reviewer": "Cesar",
|
|
10
|
-
"replyTranslation": "Clean, no perceptible distortion.",
|
|
11
|
-
"scenario": "Real Sim80, live synthesis, headphones, eight-output candidate",
|
|
12
|
-
"scope": "Subjective acceptance of this short scene, not every voice/effect or a ten-minute maximum-load pass."
|
|
13
|
-
},
|
|
14
|
-
"implementation": {
|
|
15
|
-
"platform": "Android ARM64",
|
|
16
|
-
"change": "Reuse FIR coefficients across eight consecutive samples per voice while preserving each sample partial-sum and reduction order. Bound tiles at sequence attacks. Keep the previous stereo and other-ABI paths.",
|
|
17
|
-
"gainQualityOrVoiceLimitsChanged": false,
|
|
18
|
-
"outputBufferChanged": false,
|
|
19
|
-
"publicApiChanged": false,
|
|
20
|
-
"diagnosticInterfacesInProduction": false
|
|
21
|
-
},
|
|
22
|
-
"comparisonWithIOS": {
|
|
23
|
-
"sharedBinauralAlgorithm": true,
|
|
24
|
-
"ipadMeasuredRate": 44100,
|
|
25
|
-
"ipadMeasuredBlockFrames": 1024,
|
|
26
|
-
"androidMeasuredRate": 48000,
|
|
27
|
-
"androidMeasuredBlockFrames": 256,
|
|
28
|
-
"ipadTaps": 128,
|
|
29
|
-
"androidTaps": 140,
|
|
30
|
-
"limits": "Different measured hardware/output configurations; larger blocks alone do not cure sustained CPU overload."
|
|
31
|
-
},
|
|
32
|
-
"profilingBeforeCorrection": {
|
|
33
|
-
"route": "speaker",
|
|
34
|
-
"volumeIndex": 80,
|
|
35
|
-
"callbacks": 1801,
|
|
36
|
-
"xruns": 73,
|
|
37
|
-
"cpuBlocksAboveDeadline": 455,
|
|
38
|
-
"withoutOnsetCpuBlocksAboveDeadline": 357,
|
|
39
|
-
"onsetCpuShare": 0.004458489684975288,
|
|
40
|
-
"spatialFirSamples": 1017,
|
|
41
|
-
"audioThreadSamples": 1566,
|
|
42
|
-
"scope": "Actual Sim80, flat250HzCPU sampling with inline symbol attribution, not DSP-only isolation."
|
|
43
|
-
},
|
|
44
|
-
"fourOutputCandidate": {
|
|
45
|
-
"speakerXruns": 1,
|
|
46
|
-
"speakerCpuP95LoadInterval": [
|
|
47
|
-
1.205,
|
|
48
|
-
1.21
|
|
49
|
-
],
|
|
50
|
-
"manualHeadphoneXruns": 37,
|
|
51
|
-
"manualHeadphoneVolumeIndex": 120,
|
|
52
|
-
"manualHeadphoneCpuP95LoadInterval": [
|
|
53
|
-
1.62,
|
|
54
|
-
1.625
|
|
55
|
-
],
|
|
56
|
-
"listening": "Improved but still a couple of perceived distorted moments.",
|
|
57
|
-
"limits": "Speaker profiling and manual headphone capture are distinct runs/routes, not a controlled route comparison."
|
|
58
|
-
},
|
|
59
|
-
"eightOutputCapture": {
|
|
60
|
-
"device": "Android CPH2639",
|
|
61
|
-
"route": "wired headphones",
|
|
62
|
-
"volumeIndex": 120,
|
|
63
|
-
"volumeMax": 160,
|
|
64
|
-
"sampleRate": 48000,
|
|
65
|
-
"callbackFrames": 256,
|
|
66
|
-
"burstFrames": 256,
|
|
67
|
-
"bufferFrames": 512,
|
|
68
|
-
"frames": 480000,
|
|
69
|
-
"capturedSeconds": 10,
|
|
70
|
-
"xruns": 0,
|
|
71
|
-
"routeStayedValid": true,
|
|
72
|
-
"callbacks": 1875,
|
|
73
|
-
"maxVoices": 32,
|
|
74
|
-
"maxTails": 25,
|
|
75
|
-
"wallP95LoadInterval": [
|
|
76
|
-
1.02,
|
|
77
|
-
1.025
|
|
78
|
-
],
|
|
79
|
-
"cpuP95LoadInterval": [
|
|
80
|
-
0.965,
|
|
81
|
-
0.97
|
|
82
|
-
],
|
|
83
|
-
"wallMaxNs": 9150154,
|
|
84
|
-
"cpuMaxNs": 8857462,
|
|
85
|
-
"wallBlocksAboveDeadline": 104,
|
|
86
|
-
"cpuBlocksAboveDeadline": 80,
|
|
87
|
-
"clockErrors": 0,
|
|
88
|
-
"pcmHash": "7f89b839f15ce44d",
|
|
89
|
-
"nonFiniteFrames": 0,
|
|
90
|
-
"peakLeft": 0.8500000238418579,
|
|
91
|
-
"peakRight": 0.8500000238418579,
|
|
92
|
-
"scope": "Private instrumented module with PCM capture/clocks and250Hzsampling. Observed output delivery passed this ten-second scene; callback overruns still prevent a strict render-deadline pass."
|
|
93
|
-
},
|
|
94
|
-
"verification": {
|
|
95
|
-
"streamingVsBlocked": "120000 standalone frames/sixrates8\u2013192k, ramps, wrap and complete state bit-identical on Android; varied short blocks also pass C and forcedAndroidNEON on ARM host.",
|
|
96
|
-
"renderer": "135onset/fullstate,20fractionaltransport/fullstate,9legacy renders, spatial regression and fullheld regression match or pass on ARM host.",
|
|
97
|
-
"review": "Independent source review found no critical/important issue in four/eight windows, clocks, tails, sends, stereo guard or bounded stack.",
|
|
98
|
-
"physicalAcceptance": false,
|
|
99
|
-
"stereoBypassChange": {
|
|
100
|
-
"scope": "One stereo voice, new fix versus immediately preceding205a renderer, same warmed process, both4slots; previous937screen separate",
|
|
101
|
-
"pairs": 10,
|
|
102
|
-
"medianRenderRatio": 1.0113211982131405,
|
|
103
|
-
"medianP95Ratio": 1.0053333333333334,
|
|
104
|
-
"ratios": [
|
|
105
|
-
1.0005653275429052,
|
|
106
|
-
1.0126349702109787,
|
|
107
|
-
1.0196281518419976,
|
|
108
|
-
1.0126315815643214,
|
|
109
|
-
1.0206466219701242,
|
|
110
|
-
1.0100108148619595,
|
|
111
|
-
0.996436735715484,
|
|
112
|
-
1.016768104985823,
|
|
113
|
-
1.0091023055656232,
|
|
114
|
-
0.9846528665539155
|
|
115
|
-
],
|
|
116
|
-
"bitExact": true
|
|
117
|
-
},
|
|
118
|
-
"finalProductionClockHeldLegacy": "Byte-identical to the pre-correction renderer after restoring lazy scalar clock reads and forced inlining."
|
|
119
|
-
},
|
|
120
|
-
"productionSourceSha256": {
|
|
121
|
-
"android/jni/SynthOboeEngine.cpp": "cc7f050084871a79cb028b48081a8e51158a3a69f876c59e0f9de1a6ea7ecac6",
|
|
122
|
-
"shared/synth_spatial.h": "d628ef9c60776be463c5dc45a972c9f9bbb0d183656f0dc177211038ba39d75a",
|
|
123
|
-
"tests/spatial_regression.c": "2cf768e4dc18035010819b74837921c8b27ae391670acde0bf56197793c655c0"
|
|
124
|
-
},
|
|
125
|
-
"measuredPrivateArtifact": {
|
|
126
|
-
"apkSha256": "324dc75a4b6caddbf6205915287ad90f68f0c735ac9d395ffb6bfb4821cbd934",
|
|
127
|
-
"aarSha256": "156156df699eabc8647598b5da7fa4f0d20014c3a765b04120a43a0800e40d47",
|
|
128
|
-
"sourceSha256": {
|
|
129
|
-
"android/jni/SynthOboeEngine.cpp": "8b0fc7eb99bc1f0b1d76643776fcb7e8eb540f4ba5cd9379313e7f615670e1b0",
|
|
130
|
-
"shared/synth_spatial.h": "9184a9d81de04c5216c52b96a8860c33bfd3492081089b34df35743d51e90bbb"
|
|
131
|
-
},
|
|
132
|
-
"nativeHashes": {
|
|
133
|
-
"lib/arm64-v8a/liboboe.so": "2696179a9e302f4047ce04146de39f64930bdfaa75d51da63bc7af1a228b8d73",
|
|
134
|
-
"lib/arm64-v8a/libti.synthengine.so": "3c04735e3f4a60b4d5218fadb192121978c30e105f02115383ba68120635c272",
|
|
135
|
-
"lib/armeabi-v7a/liboboe.so": "6eebcff8923f11f79d10bd3404afccab9c8d9ba629709334fc76663894b0e914",
|
|
136
|
-
"lib/armeabi-v7a/libti.synthengine.so": "b07a4b3d2e1d32b71a5267cd47d52024f9f8414d2531867ebcb0281548402919",
|
|
137
|
-
"lib/x86/liboboe.so": "8846bdc73a1ad884e017c7f3082042184bb8c9876651f48e77faef24f7c7eec4",
|
|
138
|
-
"lib/x86/libti.synthengine.so": "b13a3adcc8681090d6c305ca7436d60e367ffbcabce0fec0c64861925fcb28cc",
|
|
139
|
-
"lib/x86_64/liboboe.so": "f1168819d87b8571bb7c8147176854a2e5783bae6e35d2a420d99dc19692db94",
|
|
140
|
-
"lib/x86_64/libti.synthengine.so": "c008b2eb71b38e271a39fc3c5a1d70698e60bd06da578c723637890291970e98"
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
"rawEvidenceArchive": "android-sim80-correction-evidence.zip",
|
|
144
|
-
"remaining": [
|
|
145
|
-
"Android ten-minute maximum-load criterion is still open; do not reinterpret this short Sim80 result as that acceptance.",
|
|
146
|
-
"The measured candidate still has80CPU/104wall callbacks above one deadline.",
|
|
147
|
-
"Whole-process192k memory, prior one-voice bypass screen, Android Sim20 renderer elapsed work and strict Sim80 presentation matching retain their prior limits."
|
|
148
|
-
],
|
|
149
|
-
"publication": "Beta1.0.0, no release or push.",
|
|
150
|
-
"rawEvidenceArchiveSha256": "faff448de458ef0cb5299e234177f17a914f7801c27581ab969a9010a68c3c5f",
|
|
151
|
-
"productionAndroidBuild": {
|
|
152
|
-
"aarSha256": "7e98bf4fbc6fbe4d1f4a5d9f5a561137522e831fb54480ae0310dd22b60a0c2c",
|
|
153
|
-
"nativeSoSha256": {
|
|
154
|
-
"arm64-v8a": "631aaca4f4dabcedc33cf3bf1b23601de3da6291448a299e195cbf5b07f526e3",
|
|
155
|
-
"armeabi-v7a": "1a4100a25f920784dfc5bda91f30fa6f405e2b85deee51a8b14ce5502a2cf47c",
|
|
156
|
-
"x86": "8f4545e24cb7f35220445b6e8c04f561bbf5a6cbf55b755c8e8aeffe923e748d",
|
|
157
|
-
"x86_64": "96a8c5224129de2cd215c9d3b6a2cc50c08865f2de35bf95274026ea452a4a57"
|
|
158
|
-
},
|
|
159
|
-
"realFourAbiBuild": true,
|
|
160
|
-
"diagnosticCodeAbsent": true
|
|
161
|
-
}
|
|
162
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
> Source snapshot: official TiSynthEngine documentation at commit `b07c97c762be5905f132cecf33e9d60ea0c21316` (2026-11-02). Published 1.0.2; local 1.1.0 candidates; public API 1.0.0. Upstream `documentation/audio-pipeline-validation.md` SHA-256: `7359d85de63e9fe94f85477e03a22fc1531c8acaabe30333e7ff2515cc5ec3e9`.
|
|
2
|
-
|
|
3
|
-
# Audio pipeline correction
|
|
4
|
-
|
|
5
|
-
Version 1.0.2 removes final-output retention on Android and iOS while retaining one stereo output per platform, fixed event gains, waveform profiles and chord compensation. It adds no public options. Existing envelopes, release tails and parameter transitions keep their roles.
|
|
6
|
-
|
|
7
|
-
The final protector responds immediately to each stereo sample peak. This removes the old mandatory 10 ms delay, at the cost of a different overload response. Heavy mixes can audibly change waveform shape. Protection recovers with a 100 ms exponential time constant. The 0.85/0.70 ceilings describe sample values, not inter-sample peaks or speaker behavior. The master now follows the same linear 10 ms ramp on both platforms. iOS consumers requesting `raw` now receive its documented gain instead of the conservative gain; review those mixes.
|
|
8
|
-
|
|
9
|
-
`tests/output_core_regression.c` checks linked impulses, silence/reset, bounded recovery and exact/retargeted master ramps at 16, 44.1, 48, 96 and 192 kHz (absolute double tolerance 1e-12). Android host checks compile the real C++ callback. Apple checks extract the actual callback, helpers and start validation/profile selection, replacing device/Titanium plumbing. The historical Java DSP model is not an oracle for native sound. CI runs production output checks alongside transport, effects, spatial and statistics regressions.
|
|
10
|
-
|
|
11
|
-
`tools/calibrate_studio.py` (Android by default, `--platform ios` for Apple) reports all 37 Studio presets individually across independent low/mid/high notes, grouped chords, unisons and overlapping releases at 1, 2, 4, 8, 16 and 32 voices. Its recommendation uses the maximum measured pre-protection peak for the declared usual configuration (1-8 voices) to target −6 dBFS, with 0.01 dB measurement margin and the public volume limit. It reports 16/32-voice stress separately. The recommendations apply to the measured configuration. Event gains remain fixed, and other workloads can exceed the target. Effects and new LFOs are disabled in preset calibration. It never edits Studio.
|
|
12
|
-
|
|
13
|
-
The before/after host comparison covered 80 PCM pairs across both renderers at five sample rates. After aligning the former output delay, all 40 cases without overload preserved the waveform within an absolute float tolerance of 1e-7. Overload cases remained finite and within the sample ceiling; their waveform differences were measured. Matched host benchmarks found no median callback-time increase. These measurements do not establish whole-app CPU use or physical output latency.
|
|
14
|
-
|
|
15
|
-
Physical comparisons used Studio and Frontier on an OPPO CPH2639 running Android 16 and an iPad. Studio checks covered its 37 presets, short notes, Hold, chords, repetitions, sequences, effects and spatial controls. Frontier checks covered gameplay with simultaneous sounds. The same native candidate binaries were then integrated into the real Studio and Frontier apps, which built and launched on both devices. Their presets and gains were preserved. Route-wide latency, Bluetooth behavior and extended maximum-load acceptance remain outside these results.
|
|
16
|
-
|
|
17
|
-
Android can report an underrun during stream startup. An initial matched repeat recorded it in four of six starts for both the original and candidate, with no additional underruns during the subsequent note/chord checks. Further silent tests reproduced the symptom with an independent Oboe 1.11.0 callback that only writes zeros. The startup condition remains unresolved; the counter is retained. Silent tests do not establish whether it causes an audible defect. Oboe's open [LatencyTuner proposal](https://github.com/google/oboe/pull/2432) discusses how startup XRuns affect buffer tuning, but does not eliminate their cause. TiSynthEngine does not use that tuner.
|
|
18
|
-
|
|
19
|
-
PCM, original and candidate packages, commands, hashes and device traces are retained outside the app repositories. The physical results apply to the tested devices and scenarios.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|