December Adventure (2023)
git clone
Log | Files | Refs | README

commit 511dc4beac72fa89df0f81e6b1b990d72c8b7785
parent 170ee1e7a887017d477409c80bace4ecc2aacef7
Author: Eamon Caddigan <>
Date:   Tue, 19 Dec 2023 22:01:09 -0800

More notes, still confused.

Diffstat: | 37++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/ b/ @@ -43,7 +43,8 @@ Sending a pitch of `0x00` appears to stop playback. The lowest supported note is `0x20`, -The highest bit of the pitch byte (still) controls looping behavior (so the highest pitch supported is `0x7f`, an 8-octave range. +The highest bit of the pitch byte (still) controls looping behavior (so the +highest pitch supported is `0x7f`, an 8-octave range. Notes are converted to frequencies by the `tuning` lookup table. This table is 109 elements long even though there are only 96 possible notes? @@ -55,4 +56,38 @@ the `SAMPLE_FREQUENCY` (44100.0 Hz) defined in I.e., this value gives the (fractional) number of cycles of the waveform per audio sample for a given note. +This "fractional number of cycles" eventually needs to be converted into an +integer number of steps by taking the sample length into account. + +## Playing a note + +The `note_on` function appears to get things ready for a note to play, but +playing itself happens in the `audio_handler`. This function is called with +the "userdata" field, which is a pointer to the current `Uxn` structure +(which contains the stacks, program memory, and devices), a pointer to a +region of memory comprising the "audio data buffer", and an integer +specifying the length thereof. + +SDL is probably responsible for allocating and freeing those buffers, which +means that uxn just needs to fill that thing with audio sample data. How +does it do that? First (and this bit surprises me), uxn is handling the +polyphony. + +`SOUND_TIMER` has a value of (256 / 44100 * 1000) ~5.80, which is the +duration in ms of a 256 sample buffer. Could `duration` be expressed in +ms? I'm still super confused how it's used. I tried writing a callback to +stop playback after the duration is up, but that's not happening. I didn't +have very much time to hack tonight (but I still wrote _some_ code). + +The only thing I've actually figured out: the new S value in the ADSR +envelope is the *volume* of the sustain period. A and D are attack and decay +duration as before. I need to figure out how to stop a note before I can +observe an R. This is all evident in `env_advance` now that I know to look +for it. + +I know that I can use the Screen device as a crude timer, but I'm really +hoping there's a more fine-grained method of setting note duration, which is +why I'm trying to wrap my head on what this `duration` port **actually +does**. + ## To Be Continued