From 86fa66634326498d5629bf431dcc70b896178a53 Mon Sep 17 00:00:00 2001 From: "pedro.minatel" Date: Mon, 22 Mar 2021 18:08:57 +0000 Subject: [PATCH] Added I2S example for microphone recording to WAV file and I2S examples folder moved Added import module check on generate_audio_file.py and removed from mypy ignore list Added sugestions and minor changes on the README --- .../{ => i2s}/i2s_adc_dac/CMakeLists.txt | 0 .../{ => i2s}/i2s_adc_dac/Makefile | 0 .../{ => i2s}/i2s_adc_dac/README.md | 0 .../{ => i2s}/i2s_adc_dac/main/CMakeLists.txt | 0 .../{ => i2s}/i2s_adc_dac/main/app_main.c | 0 .../i2s_adc_dac/main/audio_example_file.h | 0 .../{ => i2s}/i2s_adc_dac/main/component.mk | 0 .../partitions_adc_dac_example.csv | 0 .../i2s_adc_dac/tools/generate_audio_file.py | 15 +- .../{ => i2s}/i2s_adc_dac/tools/sample_00.wav | Bin .../{ => i2s}/i2s_adc_dac/tools/sample_01.wav | Bin .../{ => i2s}/i2s_adc_dac/tools/sample_02.wav | Bin .../CMakeLists.txt | 0 .../i2s/i2s_audio_recorder_sdcard/Makefile | 7 + .../i2s/i2s_audio_recorder_sdcard/README.md | 102 +++++++++ .../main/CMakeLists.txt | 2 + .../main/Kconfig.projbuild | 71 ++++++ .../main/component.mk | 0 .../main/i2s_recorder_main.c | 209 ++++++++++++++++++ .../peripherals/i2s/i2s_basic/CMakeLists.txt | 6 + .../peripherals/i2s/{ => i2s_basic}/Makefile | 0 .../peripherals/i2s/{ => i2s_basic}/README.md | 0 .../i2s/{ => i2s_basic}/main/CMakeLists.txt | 0 .../i2s/i2s_basic/main/component.mk | 6 + .../{ => i2s_basic}/main/i2s_example_main.c | 0 tools/ci/mypy_ignore_list.txt | 1 - 26 files changed, 413 insertions(+), 6 deletions(-) rename examples/peripherals/{ => i2s}/i2s_adc_dac/CMakeLists.txt (100%) rename examples/peripherals/{ => i2s}/i2s_adc_dac/Makefile (100%) rename examples/peripherals/{ => i2s}/i2s_adc_dac/README.md (100%) rename examples/peripherals/{ => i2s}/i2s_adc_dac/main/CMakeLists.txt (100%) rename examples/peripherals/{ => i2s}/i2s_adc_dac/main/app_main.c (100%) rename examples/peripherals/{ => i2s}/i2s_adc_dac/main/audio_example_file.h (100%) rename examples/peripherals/{ => i2s}/i2s_adc_dac/main/component.mk (100%) rename examples/peripherals/{ => i2s}/i2s_adc_dac/partitions_adc_dac_example.csv (100%) rename examples/peripherals/{ => i2s}/i2s_adc_dac/tools/generate_audio_file.py (82%) rename examples/peripherals/{ => i2s}/i2s_adc_dac/tools/sample_00.wav (100%) rename examples/peripherals/{ => i2s}/i2s_adc_dac/tools/sample_01.wav (100%) rename examples/peripherals/{ => i2s}/i2s_adc_dac/tools/sample_02.wav (100%) rename examples/peripherals/i2s/{ => i2s_audio_recorder_sdcard}/CMakeLists.txt (100%) create mode 100644 examples/peripherals/i2s/i2s_audio_recorder_sdcard/Makefile create mode 100644 examples/peripherals/i2s/i2s_audio_recorder_sdcard/README.md create mode 100644 examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/CMakeLists.txt create mode 100644 examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/Kconfig.projbuild rename examples/peripherals/i2s/{ => i2s_audio_recorder_sdcard}/main/component.mk (100%) create mode 100644 examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c create mode 100644 examples/peripherals/i2s/i2s_basic/CMakeLists.txt rename examples/peripherals/i2s/{ => i2s_basic}/Makefile (100%) rename examples/peripherals/i2s/{ => i2s_basic}/README.md (100%) rename examples/peripherals/i2s/{ => i2s_basic}/main/CMakeLists.txt (100%) create mode 100644 examples/peripherals/i2s/i2s_basic/main/component.mk rename examples/peripherals/i2s/{ => i2s_basic}/main/i2s_example_main.c (100%) diff --git a/examples/peripherals/i2s_adc_dac/CMakeLists.txt b/examples/peripherals/i2s/i2s_adc_dac/CMakeLists.txt similarity index 100% rename from examples/peripherals/i2s_adc_dac/CMakeLists.txt rename to examples/peripherals/i2s/i2s_adc_dac/CMakeLists.txt diff --git a/examples/peripherals/i2s_adc_dac/Makefile b/examples/peripherals/i2s/i2s_adc_dac/Makefile similarity index 100% rename from examples/peripherals/i2s_adc_dac/Makefile rename to examples/peripherals/i2s/i2s_adc_dac/Makefile diff --git a/examples/peripherals/i2s_adc_dac/README.md b/examples/peripherals/i2s/i2s_adc_dac/README.md similarity index 100% rename from examples/peripherals/i2s_adc_dac/README.md rename to examples/peripherals/i2s/i2s_adc_dac/README.md diff --git a/examples/peripherals/i2s_adc_dac/main/CMakeLists.txt b/examples/peripherals/i2s/i2s_adc_dac/main/CMakeLists.txt similarity index 100% rename from examples/peripherals/i2s_adc_dac/main/CMakeLists.txt rename to examples/peripherals/i2s/i2s_adc_dac/main/CMakeLists.txt diff --git a/examples/peripherals/i2s_adc_dac/main/app_main.c b/examples/peripherals/i2s/i2s_adc_dac/main/app_main.c similarity index 100% rename from examples/peripherals/i2s_adc_dac/main/app_main.c rename to examples/peripherals/i2s/i2s_adc_dac/main/app_main.c diff --git a/examples/peripherals/i2s_adc_dac/main/audio_example_file.h b/examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h similarity index 100% rename from examples/peripherals/i2s_adc_dac/main/audio_example_file.h rename to examples/peripherals/i2s/i2s_adc_dac/main/audio_example_file.h diff --git a/examples/peripherals/i2s_adc_dac/main/component.mk b/examples/peripherals/i2s/i2s_adc_dac/main/component.mk similarity index 100% rename from examples/peripherals/i2s_adc_dac/main/component.mk rename to examples/peripherals/i2s/i2s_adc_dac/main/component.mk diff --git a/examples/peripherals/i2s_adc_dac/partitions_adc_dac_example.csv b/examples/peripherals/i2s/i2s_adc_dac/partitions_adc_dac_example.csv similarity index 100% rename from examples/peripherals/i2s_adc_dac/partitions_adc_dac_example.csv rename to examples/peripherals/i2s/i2s_adc_dac/partitions_adc_dac_example.csv diff --git a/examples/peripherals/i2s_adc_dac/tools/generate_audio_file.py b/examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py similarity index 82% rename from examples/peripherals/i2s_adc_dac/tools/generate_audio_file.py rename to examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py index 4b4b9ed1c9..faa8d6bf2c 100644 --- a/examples/peripherals/i2s_adc_dac/tools/generate_audio_file.py +++ b/examples/peripherals/i2s/i2s_adc_dac/tools/generate_audio_file.py @@ -5,8 +5,13 @@ import struct import wave from builtins import range +try: + from typing import List +except ImportError: + pass -def get_wave_array_str(filename, target_bits): + +def get_wave_array_str(filename, target_bits): # type: (str, int) -> str wave_read = wave.open(filename, 'r') array_str = '' nchannels, sampwidth, framerate, nframes, comptype, compname = wave_read.getparams() @@ -24,7 +29,7 @@ def get_wave_array_str(filename, target_bits): return array_str -def gen_wave_table(wav_file_list, target_file_name, scale_bits=8): +def gen_wave_table(wav_file_list, target_file_name, scale_bits=8): # type: (List[str], str, int) -> None with open(target_file_name, 'w') as audio_table: print('#include ', file=audio_table) print('const unsigned char audio_table[] = {', file=audio_table) @@ -38,7 +43,7 @@ def gen_wave_table(wav_file_list, target_file_name, scale_bits=8): if __name__ == '__main__': print('Generating audio array...') wav_list = [] - for filename in os.listdir('./'): - if filename.endswith('.wav'): - wav_list.append(filename) + for wavefile in os.listdir('./'): + if wavefile.endswith('.wav'): + wav_list.append(wavefile) gen_wave_table(wav_file_list=wav_list, target_file_name='audio_example_file.h') diff --git a/examples/peripherals/i2s_adc_dac/tools/sample_00.wav b/examples/peripherals/i2s/i2s_adc_dac/tools/sample_00.wav similarity index 100% rename from examples/peripherals/i2s_adc_dac/tools/sample_00.wav rename to examples/peripherals/i2s/i2s_adc_dac/tools/sample_00.wav diff --git a/examples/peripherals/i2s_adc_dac/tools/sample_01.wav b/examples/peripherals/i2s/i2s_adc_dac/tools/sample_01.wav similarity index 100% rename from examples/peripherals/i2s_adc_dac/tools/sample_01.wav rename to examples/peripherals/i2s/i2s_adc_dac/tools/sample_01.wav diff --git a/examples/peripherals/i2s_adc_dac/tools/sample_02.wav b/examples/peripherals/i2s/i2s_adc_dac/tools/sample_02.wav similarity index 100% rename from examples/peripherals/i2s_adc_dac/tools/sample_02.wav rename to examples/peripherals/i2s/i2s_adc_dac/tools/sample_02.wav diff --git a/examples/peripherals/i2s/CMakeLists.txt b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/CMakeLists.txt similarity index 100% rename from examples/peripherals/i2s/CMakeLists.txt rename to examples/peripherals/i2s/i2s_audio_recorder_sdcard/CMakeLists.txt diff --git a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/Makefile b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/Makefile new file mode 100644 index 0000000000..6e25cd97dd --- /dev/null +++ b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/Makefile @@ -0,0 +1,7 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# +VERBOSE = 1 +PROJECT_NAME := esp32-i2s-recorder-example +include $(IDF_PATH)/make/project.mk diff --git a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/README.md b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/README.md new file mode 100644 index 0000000000..85b254b2df --- /dev/null +++ b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/README.md @@ -0,0 +1,102 @@ +| Supported Targets | ESP32 | +| ----------------- | ----- | + +# I2S Digital Microphone Recording Example + +(See the README.md file in the upper level 'examples' directory for more information about examples.) + +In this example, we record a sample audio file captured from the digital MEMS microphone on the I2S peripheral using PDM data format. + +The audio is recorded into the SDCard using WAVE file format. + +| Audio Setting | Value | +|:---:|:---:| +| Sample Rate |44100 Hz| +| Bits per Sample |16 bits| + +## How to Use Example + +### Hardware Required + +* A development board with ESP32 SoC (e.g., ESP32-DevKitC, ESP-WROVER-KIT, etc.) +* A USB cable for power supply and programming +* A digital microphone (SPK0838HT4H PDM output was used in this example) + +The digital PDM microphone is connected on the I2S interface `I2S_NUM_0`. + +The default GPIO configuration is the following: + +|Mic | GPIO | +|:---------:|:------:| +| PDM Clock | GPIO22 | +| PDM Data | GPIO23 | + +The SDCard is connected using SPI peripheral. + +| SPI | SDCard | GPIO | +|:----:|:------:|:------:| +| MISO | DAT0 | GPIO2 | +| MOSI | CMD | GPIO15 | +| SCLK | CLK | GPIO14 | +| CS | CD | GPIO13 | + +To change the GPIO configuration, see the `Example Configuration` from the menuconfig. + +### Configure the Project + +``` +idf.py menuconfig +``` + +In the `Example Configuration` menu: + +* Use `SDCard Configuration` to assign the SPI peripheral GPIOs. +* Use `I2S MEMS MIC Configuration` to assign the I2S peripheral GPIOs and audio settings. + +Optional: If you need, change the other options according to your requirements. + +### Build and Flash + +Build the project and flash it to the board, then run monitor tool to view serial output: + +``` +idf.py -p PORT flash monitor +``` + +(To exit the serial monitor, type ``Ctrl-]``.) + +See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. + +* [ESP-IDF Getting Started Guide on ESP32](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html) + +## Example Output + +Running this example, you will see the Bits per Sample changes every 5 seconds after you have run this example. You can use `i2s_set_clk` to change the Bits per Sample and the Sample Rate. The output log can be seen below: + +``` +I (361) pdm_rec_example: PDM microphone recording Example start +I (371) I2S: DMA Malloc info, datalen=blocksize=2048, dma_buf_count=64 +I (401) I2S: APLL: Req RATE: 44100, real rate: 88199.977, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 22579194.000, SCLK: 2822399.250000, diva: 1, divb: 0 +I (431) I2S: APLL: Req RATE: 44100, real rate: 88199.977, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 22579194.000, SCLK: 2822399.250000, diva: 1, divb: 0 +I (431) pdm_rec_example: Initializing SD card +I (431) pdm_rec_example: Using SDMMC peripheral +I (441) gpio: GPIO[13]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +Name: USD +Type: SDHC/SDXC +Speed: 20 MHz +Size: 3813MB +I (481) pdm_rec_example: Starting recording for 60 seconds! +I (481) pdm_rec_example: Opening file +I (60451) pdm_rec_example: Recording done! +I (60471) pdm_rec_example: File written on SDCard +I (60471) pdm_rec_example: Card unmounted +``` + +## Troubleshooting + +* Program upload failure + + * Hardware connection is not correct: run `idf.py -p PORT monitor`, and reboot your board to see if there are any output logs. + * The baud rate for downloading is too high: lower your baud rate in the `menuconfig` menu, and try again. + +For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. diff --git a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/CMakeLists.txt b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/CMakeLists.txt new file mode 100644 index 0000000000..5ffc0c8df5 --- /dev/null +++ b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRCS "i2s_recorder_main.c" + INCLUDE_DIRS ".") diff --git a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/Kconfig.projbuild b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/Kconfig.projbuild new file mode 100644 index 0000000000..a23430d67e --- /dev/null +++ b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/Kconfig.projbuild @@ -0,0 +1,71 @@ +menu "Example Configuration" + + menu "SDCard Configuration" + + config EXAMPLE_SPI_MISO_GPIO + int "SPI MISO GPIO" + default 2 + help + Set the GPIO number used for MISO from SPI. + + config EXAMPLE_SPI_MOSI_GPIO + int "SPI MOSI GPIO" + default 15 + help + Set the GPIO number used for MOSI from SPI. + + config EXAMPLE_SPI_SCLK_GPIO + int "SPI SCLK GPIO" + default 14 + help + Set the GPIO number used for SCLK from SPI. + + config EXAMPLE_SPI_CS_GPIO + int "SPI CS GPIO" + default 13 + help + Set the GPIO number used for CS from SPI. + + endmenu + + menu "I2S MEMS MIC Configuration" + + config EXAMPLE_I2S_CH + int "I2S Channel Number" + default 0 + help + Set the I2S channel number. + + config EXAMPLE_AUDIO_SAMPLE_RATE + int "Audio Sample Rate" + default 44100 + help + Set the audio sample rate frequency. Usually 16000 or 44100 Hz. + + config EXAMPLE_AUDIO_BIT_SAMPLE + int "Audio Bit Sample" + default 16 + help + Define the number of bits for each sample. Default 16 bits per sample. + + config EXAMPLE_I2S_DATA_GPIO + int "I2S Data GPIO" + default 23 + help + Set the GPIO number used for transmitting/receiving data from I2S. + + config EXAMPLE_I2S_CLK_GPIO + int "I2S Clock GPIO" + default 22 + help + Set the GPIO number used for the clock line from I2S. + + endmenu + + config EXAMPLE_REC_TIME + int "Example Recording Time in Seconds" + default 15 + help + Set the time for recording audio in seconds. + +endmenu diff --git a/examples/peripherals/i2s/main/component.mk b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/component.mk similarity index 100% rename from examples/peripherals/i2s/main/component.mk rename to examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/component.mk diff --git a/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c new file mode 100644 index 0000000000..afc9272e59 --- /dev/null +++ b/examples/peripherals/i2s/i2s_audio_recorder_sdcard/main/i2s_recorder_main.c @@ -0,0 +1,209 @@ +/* I2S Digital Microphone Recording Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "driver/i2s.h" +#include "driver/gpio.h" +#include "esp_system.h" +#include +#include "esp_log.h" +#include +#include +#include "esp_err.h" +#include "esp_vfs_fat.h" +#include "driver/sdspi_host.h" +#include "driver/spi_common.h" +#include "sdmmc_cmd.h" +#include "sdkconfig.h" + +static const char* TAG = "pdm_rec_example"; + +#define AUDIO_SAMPLE_SIZE (CONFIG_EXAMPLE_AUDIO_BIT_SAMPLE * 1024) +#define SAMPLES_NUM ((CONFIG_EXAMPLE_AUDIO_SAMPLE_RATE/100) * 2) +#define BYTE_RATE (1 * CONFIG_EXAMPLE_AUDIO_SAMPLE_RATE * ((CONFIG_EXAMPLE_AUDIO_BIT_SAMPLE / 8)) +#define FLASH_RECORD_SIZE (BYTE_RATE * CONFIG_EXAMPLE_REC_TIME)) +#define SD_MOUNT_POINT "/sdcard" +#define SPI_DMA_CHAN (1) + +// When testing SD and SPI modes, keep in mind that once the card has been +// initialized in SPI mode, it can not be reinitialized in SD mode without +// toggling power to the card. +sdmmc_host_t host = SDSPI_HOST_DEFAULT(); +sdmmc_card_t* card; + +static int16_t i2s_readraw_buff[AUDIO_SAMPLE_SIZE]; +size_t bytes_read; +const int WAVE_HEADER_SIZE = 44; + +void mount_sdcard(void) +{ + esp_err_t ret; + // Options for mounting the filesystem. + // If format_if_mount_failed is set to true, SD card will be partitioned and + // formatted in case when mounting fails. + esp_vfs_fat_sdmmc_mount_config_t mount_config = { + .format_if_mount_failed = true, + .max_files = 5, + .allocation_unit_size = 16 * 1024 + }; + ESP_LOGI(TAG, "Initializing SD card"); + + // Use settings defined above to initialize SD card and mount FAT filesystem. + // Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions. + // Please check its source code and implement error recovery when developing + // production applications. + + ESP_LOGI(TAG, "Using SPI peripheral"); + + spi_bus_config_t bus_cfg = { + .mosi_io_num = CONFIG_EXAMPLE_SPI_MOSI_GPIO, + .miso_io_num = CONFIG_EXAMPLE_SPI_MISO_GPIO, + .sclk_io_num = CONFIG_EXAMPLE_SPI_SCLK_GPIO, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + .max_transfer_sz = 4000, + }; + ret = spi_bus_initialize(host.slot, &bus_cfg, SPI_DMA_CHAN); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to initialize bus."); + return; + } + + // This initializes the slot without card detect (CD) and write protect (WP) signals. + // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals. + sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT(); + slot_config.gpio_cs = CONFIG_EXAMPLE_SPI_CS_GPIO; + slot_config.host_id = host.slot; + + ret = esp_vfs_fat_sdspi_mount(SD_MOUNT_POINT, &host, &slot_config, &mount_config, &card); + + if (ret != ESP_OK) { + if (ret == ESP_FAIL) { + ESP_LOGE(TAG, "Failed to mount filesystem. " + "If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option."); + } else { + ESP_LOGE(TAG, "Failed to initialize the card (%s). " + "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret)); + } + return; + } + + // Card has been initialized, print its properties + sdmmc_card_print_info(stdout, card); +} + +void wavHeader(char* wav_header, uint32_t wav_size, uint32_t sample_rate){ + + // See this for reference: http://soundfile.sapp.org/doc/WaveFormat/ + uint32_t file_size = wav_size + WAVE_HEADER_SIZE - 8; + uint32_t byte_rate = 1 * CONFIG_EXAMPLE_AUDIO_SAMPLE_RATE * (CONFIG_EXAMPLE_AUDIO_BIT_SAMPLE / 8); + +const char set_wav_header[] = { + 'R','I','F','F', // ChunkID + file_size, file_size >> 8, file_size >> 16, file_size >> 24, // ChunkSize + 'W','A','V','E', // Format + 'f','m','t',' ', // Subchunk1ID + 0x10, 0x00, 0x00, 0x00, // Subchunk1Size (16 for PCM) + 0x01, 0x00, // AudioFormat (1 for PCM) + 0x01, 0x00, // NumChannels (1 channel) + sample_rate, sample_rate >> 8, sample_rate >> 16, sample_rate >> 24, // SampleRate + byte_rate, byte_rate >> 8, byte_rate >> 16, byte_rate >> 24, // ByteRate + 0x02, 0x00, // BlockAlign + 0x10, 0x00, // BitsPerSample (16 bits) + 'd','a','t','a', // Subchunk2ID + wav_size, wav_size >> 8, wav_size >> 16, wav_size >> 24, // Subchunk2Size +}; + + memcpy(wav_header, set_wav_header, sizeof(set_wav_header)); +} + +void record_wav(void) +{ + // Use POSIX and C standard library functions to work with files. + int flash_wr_size = 0; + ESP_LOGI(TAG, "Opening file"); + + char wav_header_fmt[WAVE_HEADER_SIZE]; + wavHeader(wav_header_fmt, FLASH_RECORD_SIZE, CONFIG_EXAMPLE_AUDIO_SAMPLE_RATE); + + // First check if file exists before creating a new file. + struct stat st; + if (stat(SD_MOUNT_POINT"/record.wav", &st) == 0) { + // Delete it if it exists + unlink(SD_MOUNT_POINT"/record.wav"); + } + + // Create new WAV file + FILE* f = fopen(SD_MOUNT_POINT"/record.wav", "a"); + if (f == NULL) { + ESP_LOGE(TAG, "Failed to open file for writing"); + return; + } + + // Write the header to the WAV file + fwrite(wav_header_fmt, 1, WAVE_HEADER_SIZE, f); + + // Start recording + while (flash_wr_size < FLASH_RECORD_SIZE) { + // Read the RAW samples from the microphone + i2s_read(CONFIG_EXAMPLE_I2S_CH, (char *)i2s_readraw_buff, AUDIO_SAMPLE_SIZE, &bytes_read, portMAX_DELAY); + // Write the samples to the WAV file + fwrite(i2s_readraw_buff, 1, bytes_read, f); + flash_wr_size += bytes_read; + } + + ESP_LOGI(TAG, "Recording done!"); + fclose(f); + ESP_LOGI(TAG, "File written on SDCard"); + + // All done, unmount partition and disable SPI peripheral + esp_vfs_fat_sdcard_unmount(SD_MOUNT_POINT, card); + ESP_LOGI(TAG, "Card unmounted"); + // Deinitialize the bus after all devices are removed + spi_bus_free(host.slot); +} + +void init_microphone(void) +{ + i2s_config_t i2s_config = { + .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM, + .sample_rate = CONFIG_EXAMPLE_AUDIO_SAMPLE_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 64, + .dma_buf_len = 1024, + .use_apll = 1 + }; + + i2s_pin_config_t pin_config; + pin_config.bck_io_num = I2S_PIN_NO_CHANGE; + pin_config.ws_io_num = CONFIG_EXAMPLE_I2S_CLK_GPIO; + pin_config.data_out_num = I2S_PIN_NO_CHANGE; + pin_config.data_in_num = CONFIG_EXAMPLE_I2S_DATA_GPIO; + + i2s_driver_install(CONFIG_EXAMPLE_I2S_CH, &i2s_config, 0, NULL); + i2s_set_pin(CONFIG_EXAMPLE_I2S_CH, &pin_config); + i2s_set_clk(CONFIG_EXAMPLE_I2S_CH, CONFIG_EXAMPLE_AUDIO_SAMPLE_RATE, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO); +} + +void app_main(void) +{ + ESP_LOGI(TAG, "PDM microphone recording Example start"); + // Mount the SDCard for recording the audio file + mount_sdcard(); + // Init the PDM digital microphone + init_microphone(); + ESP_LOGI(TAG, "Starting recording for %d seconds!", CONFIG_EXAMPLE_REC_TIME); + // Start Recording + record_wav(); +} diff --git a/examples/peripherals/i2s/i2s_basic/CMakeLists.txt b/examples/peripherals/i2s/i2s_basic/CMakeLists.txt new file mode 100644 index 0000000000..19c5f88308 --- /dev/null +++ b/examples/peripherals/i2s/i2s_basic/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(esp32-i2s-driver-example) diff --git a/examples/peripherals/i2s/Makefile b/examples/peripherals/i2s/i2s_basic/Makefile similarity index 100% rename from examples/peripherals/i2s/Makefile rename to examples/peripherals/i2s/i2s_basic/Makefile diff --git a/examples/peripherals/i2s/README.md b/examples/peripherals/i2s/i2s_basic/README.md similarity index 100% rename from examples/peripherals/i2s/README.md rename to examples/peripherals/i2s/i2s_basic/README.md diff --git a/examples/peripherals/i2s/main/CMakeLists.txt b/examples/peripherals/i2s/i2s_basic/main/CMakeLists.txt similarity index 100% rename from examples/peripherals/i2s/main/CMakeLists.txt rename to examples/peripherals/i2s/i2s_basic/main/CMakeLists.txt diff --git a/examples/peripherals/i2s/i2s_basic/main/component.mk b/examples/peripherals/i2s/i2s_basic/main/component.mk new file mode 100644 index 0000000000..9706df8e67 --- /dev/null +++ b/examples/peripherals/i2s/i2s_basic/main/component.mk @@ -0,0 +1,6 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) + +COMPONENT_ADD_INCLUDEDIRS := . diff --git a/examples/peripherals/i2s/main/i2s_example_main.c b/examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c similarity index 100% rename from examples/peripherals/i2s/main/i2s_example_main.c rename to examples/peripherals/i2s/i2s_basic/main/i2s_example_main.c diff --git a/tools/ci/mypy_ignore_list.txt b/tools/ci/mypy_ignore_list.txt index a76883839b..bccb501258 100644 --- a/tools/ci/mypy_ignore_list.txt +++ b/tools/ci/mypy_ignore_list.txt @@ -65,7 +65,6 @@ examples/get-started/blink/example_test.py examples/get-started/hello_world/example_test.py examples/peripherals/gpio/generic_gpio/example_test.py examples/peripherals/i2c/i2c_tools/example_test.py -examples/peripherals/i2s_adc_dac/tools/generate_audio_file.py examples/peripherals/rmt/ir_protocols/example_test.py examples/peripherals/sdio/sdio_test.py examples/peripherals/twai/twai_alert_and_recovery/example_test.py