When I put the following code on the simulator I have no problems. However, when I try to do so on my actual Playdate console it creates a harsh buzzing noise whenever both notes are playing. I have to reduce my console's volume to 50% before it stops, and by then the notes are barely audible. I don't think anything is wrong with my console as other games I have played have not given me this issue. Please help!!
local synthA = playdate.sound.synth.new(playdate.sound.kWaveSine)
local synthB = playdate.sound.synth.new(playdate.sound.kWaveSine)
These are some great diagnostic steps. I've tried each one and here are the results:
Multiplying the frequencies has no change to the result.
If I change one (or both) frequencies the noise DOES change in timbre. It does still sound horrible as though the result shouldn't be the product of these two frequencies.
I've tried different combinations and it looks like different waves lead to different levels of buzzing. Two square waves have the least amount of clipping but I think that's because they are already pretty buzzy sounding.
I do think it has something to do with clipping, but that's part of my confusion - both synths' volumes have been lowered individually.
Lowering the global volume DOES remove the clipping on my device. However, what confuses me is that other games often run with multiple sounds overlapping at a much higher volume and I've never experienced this issue with them.
Thanks again for the great troubleshooting advice, I'm curious to hear what your thoughts are.
As for games never having to lower their volume... My game Gravity Express distorts with system volume above 50%, as does the demo app linked in that post. To this day I don't know what is happening there
I wonder whether sound samples should maybe be mixed differently. Currently, when two samples at volume 0.7 are mixed together they seem to be added, resulting in clipping at a volume of 1.4.
The problem would be avoided if the samples are only added when they have different sign (- 0.3 and +0.3).
When the sign is the same, the maximum value should be taken.
I do realize this might be computationally too expensive.
I would prefer a compression or limiter as an option I think. Not sure how easy it would be to implement. I'd be willing to do it myself using a similar method as Dave's FM synth. Seems above my level a bit but I'm willing to explore it if it's even possible.
Again, I have no experience doing this with the Playdate. But where I'd start is implementing the Playdate's SoundEffect interface. MusicDSP.org is where I go for all my effect examples, but it looks like their Compressor code is C++ and uses floating point samples. Playdate uses C and uses 8.24 bit fixed point samples. Overall, this looks like 4 learning experiences at the same time: C++ to C, fixed point math, filters, and effects. So, depending on your tolerance for learning, this project is may not be the best place to start with the topic. But it is a really fun field to get into.
derp. I should have actually looked at your code before replying it, maybe even run it. It sounds like we're clipping there well before the point we should be. Thanks for pointing this out. I'll take a look!