DMA Test
The basic test above created the output directly by using the i2s.write() function in a loop. Another approach is to use
DMA to generate the output. With this approach, you do some initial setup to configure the DMA engine for playback.
It can then take care of generating the output in the background allowing you to do other things in your code.
To take this approach, you will need to install the Zero DMA library (https://adafru.it/lnb). You can do that through the
Library Manager:
// Initialize the I2S transmitter.
if (!i2s.begin(I2S_32_BIT, SAMPLERATE_HZ)) {
Serial.println("Failed to initialize I2S transmitter!");
while (1);
}
i2s.enableTx();
// Generate waveforms.
generateSine(AMPLITUDE, sine, WAV_SIZE);
generateSawtooth(AMPLITUDE, sawtooth, WAV_SIZE);
generateTriangle(AMPLITUDE, triangle, WAV_SIZE);
generateSquare(AMPLITUDE, square, WAV_SIZE);
}
void loop() {
Serial.println("Sine wave");
for (int i=0; i<sizeof(scale)/sizeof(float); ++i) {
// Play the note for a quarter of a second.
playWave(sine, WAV_SIZE, scale[i], 0.25);
// Pause for a tenth of a second between notes.
delay(100);
}
Serial.println("Sawtooth wave");
for (int i=0; i<sizeof(scale)/sizeof(float); ++i) {
// Play the note for a quarter of a second.
playWave(sawtooth, WAV_SIZE, scale[i], 0.25);
// Pause for a tenth of a second between notes.
delay(100);
}
Serial.println("Triangle wave");
for (int i=0; i<sizeof(scale)/sizeof(float); ++i) {
// Play the note for a quarter of a second.
playWave(triangle, WAV_SIZE, scale[i], 0.25);
// Pause for a tenth of a second between notes.
delay(100);
}
Serial.println("Square wave");
for (int i=0; i<sizeof(scale)/sizeof(float); ++i) {
// Play the note for a quarter of a second.
playWave(square, WAV_SIZE, scale[i], 0.25);
// Pause for a tenth of a second between notes.
delay(100);
}
}