#ifndef AUDIO_H #define AUDIO_H #include #include "driver/i2s_std.h" #include "driver/gpio.h" #include "FS.h" #include "SPIFFS.h" #define SAMPLE_RATE 48000 #define FREQUENCY 1000 // 1 kHz sine wave #define AMPLITUDE (2147483647 / 4) // Reduce amplitude to 25% max #define BUFFER_SIZE 256 // Number of stereo frames per buffer static const char *TAG = "WAV_PLAYER"; int buttonState; int i = 1; static int32_t audio_buffer[BUFFER_SIZE]; // Mono buffer i2s_chan_handle_t tx_handle; i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); i2s_std_config_t std_cfg = { .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE), .slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_MONO), // Set MONO mode .gpio_cfg = { .mclk = I2S_GPIO_UNUSED, .bclk = GPIO_NUM_15, .ws = GPIO_NUM_3, //7, //21, .dout = GPIO_NUM_16, // GPIO_NUM_47, .din = I2S_GPIO_UNUSED, .invert_flags = { .mclk_inv = false, .bclk_inv = false, .ws_inv = false, }, }, }; void generate_MONO_sine_wave() { static float phase = 0.0f; float phase_increment = 2.0f * M_PI * FREQUENCY / SAMPLE_RATE; for (int i = 0; i < BUFFER_SIZE; i++) { audio_buffer[i] = (int32_t)(AMPLITUDE * sinf(phase)); // Single channel (mono) phase += phase_increment; if (phase >= 2.0f * M_PI) phase -= 2.0f * M_PI; } } void play_MONO_wav_file(const char *file_path) { i2s_channel_enable(tx_handle); File file = SPIFFS.open(file_path, "rb"); // Open file using SPIFFS if (!file) { Serial.printf("Failed to open file: %s\n", file_path); return; } // Read the WAV header uint8_t header[44]; if (file.read(header, 44) != 44) { // Ensure we actually read 44 bytes Serial.println("Failed to read WAV header"); file.close(); return; } // Check if the file is a valid WAV file if (memcmp(header, "RIFF", 4) != 0 || memcmp(header + 8, "WAVE", 4) != 0) { Serial.println("Invalid WAV file"); file.close(); return; } // Extract audio data information uint32_t sample_rate = *(uint32_t *)&header[24]; uint16_t num_channels = *(uint16_t *)&header[22]; uint16_t bit_depth = *(uint16_t *)&header[34]; Serial.printf("Sample Rate: %d, Channels: %d, Bit Depth: %d\n", sample_rate, num_channels, bit_depth); // Adjust I2S configuration for MONO std_cfg.clk_cfg.sample_rate_hz = sample_rate; std_cfg.slot_cfg.slot_mode = I2S_SLOT_MODE_MONO; std_cfg.slot_cfg.data_bit_width = (bit_depth == 16) ? I2S_DATA_BIT_WIDTH_16BIT : I2S_DATA_BIT_WIDTH_32BIT; int16_t audio_buffer[BUFFER_SIZE]; // Mono buffer size_t bytes_read, bytes_written; while ((bytes_read = file.read((uint8_t*)audio_buffer, sizeof(audio_buffer))) > 0) { esp_err_t err = i2s_channel_write(tx_handle, (void*)audio_buffer, bytes_read, &bytes_written, pdMS_TO_TICKS(1000)); if (err != ESP_OK) { Serial.printf("I2S write error: %d\n", err); break; } } file.close(); // Ensure file is closed Serial.println("Finished playing WAV file"); // Stop I2S output to prevent noise after playback i2s_channel_disable(tx_handle); } #endif // AUDIO_H