#include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/i2s_std.h" #define SAMPLE_RATE 48000 #define PI 3.14159265 #define TABLE_SIZE (SAMPLE_RATE / 440) // 440 Hz #define AMPLITUDE 3000 static i2s_chan_handle_t tx_chan; // TX-Kanal extern "C" void app_main(void) { // Kanal anlegen i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_chan, NULL)); // Standard-Konfiguration i2s_std_config_t std_cfg = { .clk_cfg = { .sample_rate_hz = SAMPLE_RATE, .clk_src = I2S_CLK_SRC_DEFAULT, .mclk_multiple = I2S_MCLK_MULTIPLE_256, }, .slot_cfg = { .data_bit_width = I2S_DATA_BIT_WIDTH_16BIT, .slot_bit_width = I2S_SLOT_BIT_WIDTH_16BIT, .slot_mode = I2S_SLOT_MODE_STEREO, .slot_mask = I2S_STD_SLOT_BOTH, .ws_width = I2S_DATA_BIT_WIDTH_16BIT, .ws_pol = false, .bit_shift = false, .msb_right = false, }, .gpio_cfg = { .mclk = I2S_GPIO_UNUSED, // MCLK nicht genutzt .bclk = GPIO_NUM_5, .ws = GPIO_NUM_25, .dout = GPIO_NUM_26, .din = I2S_GPIO_UNUSED, .invert_flags = { .mclk_inv = false, .bclk_inv = false, .ws_inv = false } } }; // Init & Enable ESP_ERROR_CHECK(i2s_channel_init_std_mode(tx_chan, &std_cfg)); ESP_ERROR_CHECK(i2s_channel_enable(tx_chan)); // Sinustabelle vorbereiten int16_t sine_table[TABLE_SIZE * 2]; // Stereo for (int i = 0; i < TABLE_SIZE; i++) { float phase = 2.0f * PI * i / TABLE_SIZE; int16_t sample = (int16_t)(AMPLITUDE * sinf(phase)); sine_table[2 * i + 0] = sample; // links sine_table[2 * i + 1] = sample; // rechts } printf("🔊 Sinusausgabe startet...\n"); // Endlosschleife while (true) { size_t bytes_written = 0; ESP_ERROR_CHECK(i2s_channel_write(tx_chan, sine_table, sizeof(sine_table), &bytes_written, portMAX_DELAY)); } }