BASIC's SOUND ramps a tone's pitch toward a limit, and nothing here could do it. Faking it from the caller means re-issuing tones from its own step loop, which ties audible pitch to how often that loop runs -- a siren that changes shape with the frame rate. The step has to be taken on the mixer's frame counter, which only this library can see. akgl_audio_sweep(voice, from_hz, to_hz, step_hz, ms) steps once every 1/60 second, the rate the machine this vocabulary comes from used, which divides 44100 exactly so a step always lands on a whole frame. Direction comes from the two frequencies rather than the sign of the step, the last step clamps to the target, and equal frequencies are a held tone rather than an error. akgl_audio_tone() is the same start path with a step of 0, so a voice reused for a plain tone stops sweeping. A swept voice accumulates its phase instead of deriving it from the frame counter: deriving assumes a constant frequency and would jump the waveform at every step. tests/audio.c drives the mixer by hand and asserts the exact frame the pitch moves on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
16 KiB
16 KiB