I am using the UDA1334 I2S DAC with Metro M4 and the Zero_I2S library. I am able to get the basic Sine/Cosine tone generator example working (tip for others - keep those clock and data lines short!).
I made an array of mono 8kHz 16bit sampled audio and can play it. However, I have to introduce delays to play it at the correct speed. I realise that this is perhaps because I am reading mono data but if I change
Code: Select all
#define I2S_NUM_SLOTS 1
I have played around with the begin() function, adding in different I2SSlotSize, fs_freq and MCLK multipliers to no avail. Could it be something to do with the clock setup registers for low sampling speeds?
I realise that I am stepping through the array of bytes +=2 each time but that is because two bytes have to be combined into a 16bit value to feed to the DAC. I used Audacity to resample at 8kHz 16bit PCM and HxD to remove the .wav header and export as C array.
Please shout if you can suggest where I should investigate next. Here is the bare minimum test (I use a timer to check how long the delayMicroseconds() needs to be to result in a total duration that matches the source audio:
Code: Select all
#include <Arduino.h>
#include <Adafruit_ZeroI2S.h>
#include "lookdave8k.h"
/* max volume for 32 bit data */
#define VOLUME ( (1UL << 31) - 1)
// Use default pins in board variant
Adafruit_ZeroI2S i2s = Adafruit_ZeroI2S();
void setup()
{
while (!Serial) delay(10);
Serial.println("I2S demo");
/* begin I2S on the default pins. 16 bit depth at
8000 samples per second
*/
i2s.begin(I2S_16_BIT, 8000);
i2s.enableTx();
}
void loop()
{
/* write the output buffers
note that i2s.write() will block until both channels are written.
*/
long time = millis();
for (unsigned int i = 0; i < datalen; i += 2) {
int sound = (rawData[i + 1] & 0xFF ) << 8 | ((rawData[i] ) & 0xFF);
i2s.write(sound, sound);
delayMicroseconds(120);
}
Serial.println(millis() - time);
delay(2000);
}