Changes on the recording function

This commit is contained in:
pedro.minatel 2021-08-25 12:09:57 +01:00 committed by laokaiyao
parent 4d1e3a6ed5
commit 5e53ff825e
2 changed files with 33 additions and 29 deletions

View File

@ -36,13 +36,13 @@ menu "Example Configuration"
help help
Set the I2S channel number. Set the I2S channel number.
config EXAMPLE_AUDIO_SAMPLE_RATE config EXAMPLE_SAMPLE_RATE
int "Audio Sample Rate" int "Audio Sample Rate"
default 44100 default 44100
help help
Set the audio sample rate frequency. Usually 16000 or 44100 Hz. Set the audio sample rate frequency. Usually 16000 or 44100 Hz.
config EXAMPLE_AUDIO_BIT_SAMPLE config EXAMPLE_BIT_SAMPLE
int "Audio Bit Sample" int "Audio Bit Sample"
default 16 default 16
help help

View File

@ -25,11 +25,10 @@
static const char* TAG = "pdm_rec_example"; static const char* TAG = "pdm_rec_example";
#define AUDIO_SAMPLE_SIZE (CONFIG_EXAMPLE_AUDIO_BIT_SAMPLE * 1024)
#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) #define SPI_DMA_CHAN (1)
#define SD_MOUNT_POINT "/sdcard"
#define SAMPLE_SIZE (CONFIG_EXAMPLE_BIT_SAMPLE * 1024)
#define BYTE_RATE 1 * CONFIG_EXAMPLE_SAMPLE_RATE * (CONFIG_EXAMPLE_BIT_SAMPLE / 8)
// When testing SD and SPI modes, keep in mind that once the card has been // 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 // initialized in SPI mode, it can not be reinitialized in SD mode without
@ -37,7 +36,7 @@ static const char* TAG = "pdm_rec_example";
sdmmc_host_t host = SDSPI_HOST_DEFAULT(); sdmmc_host_t host = SDSPI_HOST_DEFAULT();
sdmmc_card_t* card; sdmmc_card_t* card;
static int16_t i2s_readraw_buff[AUDIO_SAMPLE_SIZE]; static int16_t i2s_readraw_buff[SAMPLE_SIZE];
size_t bytes_read; size_t bytes_read;
const int WAVE_HEADER_SIZE = 44; const int WAVE_HEADER_SIZE = 44;
@ -104,33 +103,35 @@ void wavHeader(char* wav_header, uint32_t wav_size, uint32_t sample_rate){
uint32_t file_size = wav_size + WAVE_HEADER_SIZE - 8; uint32_t file_size = wav_size + WAVE_HEADER_SIZE - 8;
uint32_t byte_rate = BYTE_RATE; uint32_t byte_rate = BYTE_RATE;
const char set_wav_header[] = { const char set_wav_header[] = {
'R','I','F','F', // ChunkID 'R','I','F','F', // ChunkID
file_size, file_size >> 8, file_size >> 16, file_size >> 24, // ChunkSize file_size, file_size >> 8, file_size >> 16, file_size >> 24, // ChunkSize
'W','A','V','E', // Format 'W','A','V','E', // Format
'f','m','t',' ', // Subchunk1ID 'f','m','t',' ', // Subchunk1ID
0x10, 0x00, 0x00, 0x00, // Subchunk1Size (16 for PCM) 0x10, 0x00, 0x00, 0x00, // Subchunk1Size (16 for PCM)
0x01, 0x00, // AudioFormat (1 for PCM) 0x01, 0x00, // AudioFormat (1 for PCM)
0x01, 0x00, // NumChannels (1 channel) 0x01, 0x00, // NumChannels (1 channel)
sample_rate, sample_rate >> 8, sample_rate >> 16, sample_rate >> 24, // SampleRate sample_rate, sample_rate >> 8, sample_rate >> 16, sample_rate >> 24, // SampleRate
byte_rate, byte_rate >> 8, byte_rate >> 16, byte_rate >> 24, // ByteRate byte_rate, byte_rate >> 8, byte_rate >> 16, byte_rate >> 24, // ByteRate
0x02, 0x00, // BlockAlign 0x02, 0x00, // BlockAlign
0x10, 0x00, // BitsPerSample (16 bits) 0x10, 0x00, // BitsPerSample (16 bits)
'd','a','t','a', // Subchunk2ID 'd','a','t','a', // Subchunk2ID
wav_size, wav_size >> 8, wav_size >> 16, wav_size >> 24, // Subchunk2Size wav_size, wav_size >> 8, wav_size >> 16, wav_size >> 24, // Subchunk2Size
}; };
memcpy(wav_header, set_wav_header, sizeof(set_wav_header)); memcpy(wav_header, set_wav_header, sizeof(set_wav_header));
} }
void record_wav(void) void record_wav(uint32_t rec_time)
{ {
// Use POSIX and C standard library functions to work with files. // Use POSIX and C standard library functions to work with files.
int flash_wr_size = 0; int flash_wr_size = 0;
ESP_LOGI(TAG, "Opening file"); ESP_LOGI(TAG, "Opening file");
char wav_header_fmt[WAVE_HEADER_SIZE]; char wav_header_fmt[WAVE_HEADER_SIZE];
wavHeader(wav_header_fmt, FLASH_RECORD_SIZE, CONFIG_EXAMPLE_AUDIO_SAMPLE_RATE);
uint32_t flash_rec_time = BYTE_RATE * rec_time;
wavHeader(wav_header_fmt, flash_rec_time, CONFIG_EXAMPLE_SAMPLE_RATE);
// First check if file exists before creating a new file. // First check if file exists before creating a new file.
struct stat st; struct stat st;
@ -150,9 +151,9 @@ void record_wav(void)
fwrite(wav_header_fmt, 1, WAVE_HEADER_SIZE, f); fwrite(wav_header_fmt, 1, WAVE_HEADER_SIZE, f);
// Start recording // Start recording
while (flash_wr_size < FLASH_RECORD_SIZE) { while (flash_wr_size < flash_rec_time) {
// Read the RAW samples from the microphone // Read the RAW samples from the microphone
i2s_read(CONFIG_EXAMPLE_I2S_CH, (char *)i2s_readraw_buff, AUDIO_SAMPLE_SIZE, &bytes_read, 100); i2s_read(CONFIG_EXAMPLE_I2S_CH, (char *)i2s_readraw_buff, SAMPLE_SIZE, &bytes_read, 100);
// Write the samples to the WAV file // Write the samples to the WAV file
fwrite(i2s_readraw_buff, 1, bytes_read, f); fwrite(i2s_readraw_buff, 1, bytes_read, f);
flash_wr_size += bytes_read; flash_wr_size += bytes_read;
@ -171,9 +172,11 @@ void record_wav(void)
void init_microphone(void) void init_microphone(void)
{ {
// Set the I2S configuration as PDM 16bits per sample
i2s_config_t i2s_config = { i2s_config_t i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM, .mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_PDM,
.sample_rate = CONFIG_EXAMPLE_AUDIO_SAMPLE_RATE, .sample_rate = CONFIG_EXAMPLE_SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_STAND_I2S, .communication_format = I2S_COMM_FORMAT_STAND_I2S,
@ -183,6 +186,7 @@ void init_microphone(void)
.use_apll = 1, .use_apll = 1,
}; };
// Set the pinout configuration (set using menuconfig)
i2s_pin_config_t pin_config = { i2s_pin_config_t pin_config = {
.mck_io_num = I2S_PIN_NO_CHANGE, .mck_io_num = I2S_PIN_NO_CHANGE,
.bck_io_num = I2S_PIN_NO_CHANGE, .bck_io_num = I2S_PIN_NO_CHANGE,
@ -194,7 +198,7 @@ void init_microphone(void)
// Call driver installation function before any I2S R/W operation. // Call driver installation function before any I2S R/W operation.
ESP_ERROR_CHECK( i2s_driver_install(CONFIG_EXAMPLE_I2S_CH, &i2s_config, 0, NULL) ); ESP_ERROR_CHECK( i2s_driver_install(CONFIG_EXAMPLE_I2S_CH, &i2s_config, 0, NULL) );
ESP_ERROR_CHECK( i2s_set_pin(CONFIG_EXAMPLE_I2S_CH, &pin_config) ); ESP_ERROR_CHECK( i2s_set_pin(CONFIG_EXAMPLE_I2S_CH, &pin_config) );
ESP_ERROR_CHECK( i2s_set_clk(CONFIG_EXAMPLE_I2S_CH, (CONFIG_EXAMPLE_AUDIO_SAMPLE_RATE / 2), I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO) ); ESP_ERROR_CHECK( i2s_set_clk(CONFIG_EXAMPLE_I2S_CH, (CONFIG_EXAMPLE_SAMPLE_RATE / 2), I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_MONO) );
} }
void app_main(void) void app_main(void)
@ -206,7 +210,7 @@ void app_main(void)
init_microphone(); init_microphone();
ESP_LOGI(TAG, "Starting recording for %d seconds!", CONFIG_EXAMPLE_REC_TIME); ESP_LOGI(TAG, "Starting recording for %d seconds!", CONFIG_EXAMPLE_REC_TIME);
// Start Recording // Start Recording
record_wav(); record_wav(CONFIG_EXAMPLE_REC_TIME);
// Stop I2S driver and destroy // Stop I2S driver and destroy
ESP_ERROR_CHECK( i2s_driver_uninstall(CONFIG_EXAMPLE_I2S_CH) ); ESP_ERROR_CHECK( i2s_driver_uninstall(CONFIG_EXAMPLE_I2S_CH) );
} }