Skip to content

Add TAYM export with timer effects and sample playback - #47

Closed
ruguevara wants to merge 5 commits into
paator:mainfrom
ruguevara:taym-samples
Closed

Add TAYM export with timer effects and sample playback#47
ruguevara wants to merge 5 commits into
paator:mainfrom
ruguevara:taym-samples

Conversation

@ruguevara

Copy link
Copy Markdown
Contributor

Summary

  • Add TAYM export to the tracker UI, including direct .taym downloads and .taym files inside ZIP exports.
  • Add command-line exporters for BTP projects to TAYM, TMR, and PSG.
  • Encode AY foreground register frames together with timer-driven SID, sync-buzzer, FM, and envelope-FM effects on a shared capture timeline.
  • Export playing samples as TAYM amplitude lanes, using the 0x80 virtual target and AY/YM-aware DAC volume mapping.
  • Keep each playing-sample instance on one stable amplitude lane and encode sample pitch as precise absolute rates by default.
  • Correct SID PWM duty alternation in both TAYM and TMR output and share the AY timer-effect encoding logic.

Fresh-main integration

  • Rebased the five export commits onto current origin/main.
  • Keep main's new TAYM importer timer resolver at taym-timers.ts; the export-side timer-table builder now has the distinct taym-export-timers.ts boundary.
  • Update CLI module loading to the current public/ay and public/tracker paths and use Node-safe export modules.
  • Capture multi-AY TMR projects on one shared timeline, matching playback/VGM synchronization and compatibility checks.
  • Add a regression assertion that export bytes are accepted by main's strict TAYM reader.

Validation

  • pnpm check — 0 errors, 0 warnings.
  • Focused TAYM/TMR/VGM/PSG import/export suite — 118 tests passed.
  • pnpm btp-to-taym src/demo/man.btp /private/tmp/bitphase-pr-smoke.taym — completed successfully.
  • Loaded the CLI-produced TAYM through main's importTaymBuffer — 1 song, 0 warnings.
  • Reproduced samples-1ch.btp through the UI-default capture/build path — one 9,800-byte sample lane instead of per-frame rotated duplicates.
  • Converted the result with AYMax taym2aymax.py — its 126-entry event stream is byte-identical to the known-good absolute-rate export.

The complete test run reached 999 passing tests; six unrelated keyboard-shortcut tests fail in Node because localStorage is unavailable.

Implement TAYM container codec, model, spec, validation, and timer-table
builder; refactor the TMR encoder onto shared ay-timer-effects helpers.
Wire taym/psg export into the menu, progress modal, and export formats,
with CLI entry points and test coverage.
SID PWM is emitted by the driver as TIMER_PWM_MODE_BY_DUTY_INDEX, where the
period alternates by step-index parity (matching the C engine), with the
waveform holding volume levels. The export path treated SID as BY_STEP_VALUE,
so it captured pwm=false and selected the period from the waveform value.
Since SID PWM waveform values are nonzero, only highPeriod was ever used and
the duty sweep was lost, producing a fixed high-frequency 50% pulse instead
of the swept low-pitched tone.

Detect SID PWM via BY_DUTY_INDEX, switch sidStepPeriod to index-parity
selection, and drop the pwm=true workaround in both export paths.
Export PCM samples as a per-channel timer driving the 0x80 sample-amplitude
target paired with the channel volume register; shared unquantized lane,
per-frame volume via inline action, exact rate via abs-rate-hz mode.

Add physically-linear SID-volume combine (DAC-domain) in ayumi via a
precomputed sid_volume_code table; bump AYUMI_STRUCT_SIZE accordingly.
@ruguevara ruguevara closed this Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant