Seeeduino Xiao SAMD21 and I2S

Hi everyone,

I recently started a mini-project that could evolve in something like a digital synth in the future. I am using the Xiao SAMD21 and I would like to use a MAX98375A to drive a 8 Ohm 1 W speaker. The Xiao is powered through a USB-C cable to a USB-C port in my computer. The MAX takes its supply from the 5V pin on the Xiao.
I am using Arduino IDE.

The MAX accepts digital data through the I2S protocol. While officially the Xiao SAMD21 does not mention I2S, the chip is equipped with the necessary interface and by changing the variant.h file (as found in a topic in this forum, the I2S interface uses pins 2, 3, 8 respectively for BCLK, LRCLK and DATA) and using the SimpleTone example, I managed to play a simple fixed-frequency square wave.
This example uses Arduino I2S.h library, but then I found a more complete example that plays a little scale and uses Adafruit_ZeroI2S.h, so I went forward with this library. The sample rate is set to 44.1 kHz and the data width is set to 32 bits.
Afraid that the length of the write operation to the I2S interface could be too slow and miss some samples, I followed the example and wrote the entire content into the I2S buffer (which does a non-blocking write) instead of writing one sample at a time (which seem to be blocking).
EDIT: a bit of confusion on my end. In this example data are written one sample per write operation, but there is the possibility to write a buffer of data with the original I2S.h library.

My plan is the have different lookup tables for the different waveforms (square, sawtooth, reverse sawtooth, triangle, sine…) and so far I managed to play the little up and down scale while pressing a button with a few different waveforms BUT… not with all of them.

Each lookup table is an array of 256 signed 32-bit values. I can provide the exact values if they can be of any interest, but I simply generated them with an online calculator and they all have the same number of values and about the same min and max values (you can find some of them in the attached code).

The very mysterious thing is that while the square, triangle and sawtooth waves seem to produce sound, the sine wave is silent or just a very very quiet noise can be perceived. I also tried to generate different waveforms (cosine, gaussian, etc) but with no results.
The craziest thing is that I also generated a sigmoid such that it closely resembles a sawtooth, but the sawtooth correctly plays and the sigmoid doesn’t.

I added my code as a zip file. I don’t have a schematic but I can create one if it can be of any use. There are some unused functions in the code, that were in the original example and I haven’t still deleted.

EDIT2: I tried to add a volume control by simply multiplying each sample by a coefficient, and the sound becomes distorted. I’m starting to think that the write operation takes too many clock cycles and there is not enough time to do anything else even with a low sample rate (8KHz)…

sketch_apr6b.zip (4,9 KB)