The next thing I found was this learn guide for AudioOut. This is also playing tones, but it's a bit of a different approach. Instead wobbling the pin directly to make auditory pixies, it looks like this is creating a RawSample object ahead of time and then playing it back later using the AudioOut objects play function. This one also is creating sine waves instead of square waves like before. We'll file that away for later when we try to figure out how to make other patters like triangle and sawtooth. Another neat thing going on with this example is that it is controlling the volume, there is a variable tone_volume that we can change to make the beeps and boops louder and softer. I don't quite grok how it works, but it seems this variable is being used when it generates the raw wave data that is getting turned into a RawSample for us to play back later.
At this point I re-worked my previous super basic synth program to use AudioOut. I created a list to store my RawSample objects and created enough of them to play one full octave. Once the modifications were everything from the users perspective worked pretty much the same as before, but now at a volume comfortable enough to play with the earbuds in.
The next thing I tried to tackle was stereo playback. So far we're only playing audio out of one channel of the available two in the neotrellis' 3.5mm jack backed by dual DAC's in the SAMD51. Poking around a bit online I found myself at the docs page for AudioOut. I probably should have started looking there sooner, because it has the exact thing we need to enable stereo! In the constructor we can pass left_channel and right_channel pins. A quick tweak to the code and sure enough now we've got sound in both ears