I2S from mkrzero into MAX98357 - corrupted sound

Hi all. I am connecting my mkrzero derived custom board to a MAX98357 over I2S and trying to output a sine wave to test initially. The interface and power isolation I think is good as no pop/click "noise" and volume is fine, but the sine wave sounds more like an old-school modem! So I am thinking about signed/unsigned data, L/R/mono issues maybe, but I have got nowhere investigating these.

If I print the sine values they look fine ( eg. -23169, -12539, 0, 12539, 23169, 30272, 32767, 30272, 23169, 12539, 0, -12539, -23169, -30272, -32767, -30272, -23169, -12539..).

I have tried a few sample rates. I am using the I2S.h library and simply doing I2S.begin(I2S_PHILIPS_MODE, sampleRate, 16) and then a bunch of I2S.write(x). Maybe I am missing some more config stuff? I am driving SDMODE high for mono data.

Thanks

One clue is that my 1 sec test sine wave lasts for more like 4 secs, so maybe my loop is not writing values to the MAX fast enough ...

for (int i = 0; i < sampleRate; i++) { // sampleRate ==16000
    float sample = 32767 * sin((2 * PI * i) / 16);
    int16_t sampleValue = (int16_t) sample;
    I2S.write(sampleValue); // L
  }

I fixed it myself! :rofl:

The trig and float math was not able to run fast enough. Switching to a simple square wave works clean as a whistle :

  for (int i = 0; i < sampleRate; i++) { //16000
    //float sample = 32767 * sin((2 * PI * i) / 16);
   // int16_t sampleValue = (int16_t) sample;
    if (i%8==0) { 
      if (sampleValue == 32767) {
        sampleValue = -32767;
        } else {
        sampleValue = 32767;
      };
    };
    I2S.write(sampleValue); // L
  }

In which case you need to pre calculate the samples of the sin wave and put them in a buffer in the setup function.

Then to generate the signals you just output successive samples in the buffer. If you use a floating point buffer pointer, with an increment less than 1, then you can control the speed of the output with the increment size.

Of course you only use the integer part of the buffer pointer when fetching samples from the buffer.

nice tip thanks! I have hooked it up to my adpcm decoder now and strangely the volume there is much lower, it's not quite full-scale but I get peaks at +/- 20,000, so about 2/3rds full-scale of 32768. Maybe it's a log thing...

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.