Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add I2S examples and documentation #9030

Merged
merged 3 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
561 changes: 276 additions & 285 deletions docs/en/api/i2s.rst

Large diffs are not rendered by default.

918 changes: 918 additions & 0 deletions libraries/ESP_I2S/examples/ES8388_loopback/ES8388.cpp

Large diffs are not rendered by default.

1,093 changes: 1,093 additions & 0 deletions libraries/ESP_I2S/examples/ES8388_loopback/ES8388.h

Large diffs are not rendered by default.

86 changes: 86 additions & 0 deletions libraries/ESP_I2S/examples/ES8388_loopback/ES8388_loopback.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
ESP32-LyraT I2S ES8388 loopback example
This simple example demonstrates using the I2S library in combination
with the ES8388 codec on the ESP32-LyraT board to record and play back
audio data.

Don't forget to enable the PSRAM in the Tools menu!

Created for arduino-esp32 on 20 Dec, 2023
by Lucas Saavedra Vaz (lucasssvaz)
*/

#include "ESP_I2S.h"
#include "Wire.h"

#include "ES8388.h"

/* Pin definitions */

/* I2C */
const uint8_t I2C_SCL = 23;
const uint8_t I2C_SDA = 18;
const uint32_t I2C_FREQ = 400000;

/* I2S */
const uint8_t I2S_MCLK = 0; /* Master clock */
const uint8_t I2S_SCK = 5; /* Audio data bit clock */
const uint8_t I2S_WS = 25; /* Audio data left and right clock */
const uint8_t I2S_SDOUT = 26; /* ESP32 audio data output (to speakers) */
const uint8_t I2S_SDIN = 35; /* ESP32 audio data input (from microphone) */

/* PA */
const uint8_t PA_ENABLE = 21; /* Power amplifier enable */

void setup() {
I2SClass i2s;
ES8388 codec;
uint8_t *wav_buffer;
size_t wav_size;

// Initialize the serial port
Serial.begin(115200);
while (!Serial) { delay(10); }

pinMode(PA_ENABLE, OUTPUT);
digitalWrite(PA_ENABLE, HIGH);

Serial.println("Initializing I2C bus...");

// Initialize the I2C bus
Wire.begin(I2C_SDA, I2C_SCL, I2C_FREQ);

Serial.println("Initializing I2S bus...");

// Set up the pins used for audio input
i2s.setPins(I2S_SCK, I2S_WS, I2S_SDOUT, I2S_SDIN, I2S_MCLK);

// Initialize the I2S bus in standard mode
if (!i2s.begin(I2S_MODE_STD, 44100, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO, I2S_STD_SLOT_BOTH)) {
Serial.println("Failed to initialize I2S bus!");
return;
}

Serial.println("Initializing ES8388...");

if (!codec.begin(i2s)) {
Serial.println("Failed to initialize ES8388!");
return;
}

Serial.println("Recording 10 seconds of audio data...");

// Record 10 seconds of audio data
wav_buffer = codec.recordWAV(10, &wav_size);

Serial.println("Recording complete. Playing audio data in 3 seconds.");
delay(3000);

// Play the audio data
Serial.println("Playing audio data...");
codec.playWAV(wav_buffer, wav_size);

Serial.println("Application complete.");
}

void loop() {}
Empty file.
Empty file.
Empty file.
Empty file.
90 changes: 90 additions & 0 deletions libraries/ESP_I2S/examples/Record_to_WAV/Record_to_WAV.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
ESP32-S2-EYE I2S record to WAV example
This simple example demonstrates using the I2S library to record
5 seconds of audio data and write it to a WAV file on the SD card.

Don't forget to select the OPI PSRAM, 8MB flash size and Enable USB CDC
on boot in the Tools menu!

Created for arduino-esp32 on 18 Dec, 2023
by Lucas Saavedra Vaz (lucasssvaz)
*/

#include "ESP_I2S.h"
#include "FS.h"
#include "SD_MMC.h"

const uint8_t I2S_SCK = 41;
const uint8_t I2S_WS = 42;
const uint8_t I2S_DIN = 2;

const uint8_t SD_CMD = 38;
const uint8_t SD_CLK = 39;
const uint8_t SD_DATA0 = 40;

void setup() {
// Create an instance of the I2SClass
I2SClass i2s;

// Create variables to store the audio data
uint8_t *wav_buffer;
size_t wav_size;

// Initialize the serial port
Serial.begin(115200);
while (!Serial) { delay(10); }

Serial.println("Initializing I2S bus...");

// Set up the pins used for audio input
i2s.setPins(I2S_SCK, I2S_WS, -1, I2S_DIN);

// Initialize the I2S bus in standard mode
if (!i2s.begin(I2S_MODE_STD, 16000, I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO, I2S_STD_SLOT_LEFT)) {
Serial.println("Failed to initialize I2S bus!");
return;
}

Serial.println("I2S bus initialized.");
Serial.println("Initializing SD card...");

// Set up the pins used for SD card access
if (!SD_MMC.setPins(SD_CLK, SD_CMD, SD_DATA0)) {
Serial.println("Failed to set SD pins!");
return;
}

// Mount the SD card
if(!SD_MMC.begin("/sdcard", true)){
Serial.println("Failed to initialize SD card!");
return;
}

Serial.println("SD card initialized.");
Serial.println("Recording 5 seconds of audio data...");

// Record 5 seconds of audio data
wav_buffer = i2s.recordWAV(5, &wav_size);

// Create a file on the SD card
File file = SD_MMC.open("/test.wav", FILE_WRITE);
if (!file) {
Serial.println("Failed to open file for writing!");
return;
}

Serial.println("Writing audio data to file...");

// Write the audio data to the file
if (file.write(wav_buffer, wav_size) != wav_size) {
Serial.println("Failed to write audio data to file!");
return;
}

// Close the file
file.close();

Serial.println("Application complete.");
}

void loop() {}
68 changes: 68 additions & 0 deletions libraries/ESP_I2S/examples/Simple_tone/Simple_tone.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
This example generates a square wave based tone at a specified frequency
and sample rate. Then outputs the data using the I2S interface to a
MAX08357 I2S Amp Breakout board.
I2S Circuit:
* Arduino/Genuino Zero, MKR family and Nano 33 IoT
* MAX08357:
* GND connected GND
* VIN connected 5V
* LRC connected to pin 0 (Zero) or 3 (MKR), A2 (Nano) or 25 (ESP32)
* BCLK connected to pin 1 (Zero) or 2 (MKR), A3 (Nano) or 5 (ESP32)
* DIN connected to pin 9 (Zero) or A6 (MKR), 4 (Nano) or 26 (ESP32)
DAC Circuit:
* ESP32 or ESP32-S2
* Audio amplifier
- Note:
- ESP32 has DAC on GPIO pins 25 and 26.
- ESP32-S2 has DAC on GPIO pins 17 and 18.
- Connect speaker(s) or headphones.
created 17 November 2016
by Sandeep Mistry
For ESP extended
Tomas Pilny
2nd September 2021
Lucas Saavedra Vaz (lucasssvaz)
22nd December 2023
*/

#include <ESP_I2S.h>

const int frequency = 440; // frequency of square wave in Hz
const int amplitude = 500; // amplitude of square wave
const int sampleRate = 8000; // sample rate in Hz

i2s_data_bit_width_t bps = I2S_DATA_BIT_WIDTH_16BIT;
i2s_mode_t mode = I2S_MODE_STD;
i2s_slot_mode_t slot = I2S_SLOT_MODE_STEREO;

const int halfWavelength = (sampleRate / frequency); // half wavelength of square wave

int32_t sample = amplitude; // current sample value
int count = 0;

I2SClass i2s;

void setup() {
Serial.begin(115200);
Serial.println("I2S simple tone");

// start I2S at the sample rate with 16-bits per sample
if (!i2s.begin(mode, sampleRate, bps, slot)) {
Serial.println("Failed to initialize I2S!");
while (1); // do nothing
}
}

void loop() {
if (count % halfWavelength == 0 ) {
// invert the sample every half wavelength count multiple to generate square wave
sample = -1 * sample;
}

i2s.write(sample); // Right channel
i2s.write(sample); // Left channel

// increment the counter for the next sample
count++;
}
Loading