utz wrote:I don't think there is any code for the method Shiru describes, because nobody has implemented it. The idea for continuous sound would be not to call the sound generator through an ISR (because 50 Hz is too slow to make anything but the lowest audible tones), but to interleave it with the multicolour code at regular intervals. The usual restrictions with contention apply there, so it would still be quite tricky.
Actually, I have implemented exactly this idea in my 1K intro "Splash" (2014). The beeper engine there is very simplistic, single voice, but this is purely due to the size limitations I was dealing with.
In fact, I think that it won't be a large overstatement to say that most of my beeper experiments were about trying to push the envelope of how beeper sound can be combined with other things.
Shiru's methods 1 and 2 can be found in quite a few old games with beeper music. I never liked the resulting sound, so I did not do much research on it. Hence, I am not sure if e.g. Manic Miner uses method 1 or method 2 (method 1 seems more likely, given the lack of vsync in the game). My beeper scroller in "Dat Fuzz" (2014) is using, I guess, a variation of the method 2, with one modification: the visuals occupy small fixed time remaining after playing something like 2.5 frames of sound. So, improving the quality of sound is easy - just ensure that the sound does not get interrupted much.
Like I said, method 3 in Shiru's list can be found in "Splash" (2014). At the same time, outside of beeper, I am pretty sure that at least some demos with digital sound use a similar approach (e.g. "Scroller" (2010) or "Atarin" (2018)). In fact, I'd say that the devil is in the implementation detail: visuals usually require v-sync, while beeper (or digi) need +- constant rate of updating, which does not fit well with updating visuals synchronized to vsync or, more generally, doing any non-trivial logic. Specific solutions of this clash of needs can be different and varied; what I did in Splash does not make me happy and I am currently experimenting with another approaches.
A good way to think about all these methods is to think about code responsible for visuals as something that "distorts" sound. Then your strategy to improve the sound quality would always be about something that reduces the distortion. The larger proportion of time you can spend on making the sound, the better sound quality you'd get. This applies to all three of Shiru's methods.
However, there are other methods for reducing the distortion. Instead of trying to reduce the "amplitude" of the distortion ("amplitude" in the PWM sense would be the duration of anything that is not generating sounds), you can change the dominant frequency with which distortion occurs. E.g. the scroller in "Dat Fuzz" operates on the basis of one scroll every 3 frames only partly because this was the only way to significantly change the proportion of time between the work of the beeper engine and the work of the visual code. It is also important that the base frequency of the resulting distortion becomes 18.5Hz (which cannot be heard) instead of the pretty obvious 50Hz produced by engines operating on the basis of single frames logic. If taken to the extreme, some games do all drawing between the rows in the beeper engine, which tends to mask quite well even pretty significant interruptions in sound. Of course, from the point of view of visuals extremely slow updates do not work very well.
My demo "Rain" (2016) was an attempt to see what happens at the other end of the spectrum. What would happen with the sound if the distortion was to operate at very high frequency? In "Rain", the visual code occupies every 4th iteration of the sound loop running at something like 12kHz. It does distort the sound, but the nature of the distortion is such as to create "spacey" sound, which seems a lot more acceptable that what methods 1 or 2 can provide you with. Of course, the type of code you need to write for this mindset is not very vsync-friendly and, in fact, is not very visual-effects friendly. However, you do get surprising amount of time for doing useful work beyond making the sound, so definitely consider this approach too.