#include <WiFi.h>
#include <driver/i2s.h>
// ====================================================================
// 1. KULLANICI AYARLARI (BURALARI KENDİNİZE GÖRE DÜZENLEYİN)
// ====================================================================
const char* ssid = "Wokwi-GUEST"; // Wi-Fi Adınız (Wokwi için sabit)
const char* password = ""; // Wi-Fi Şifreniz (Wokwi'de boştur)
const char* host = "morcast.caster.fm"; // Icecast sunucu adresiniz
const int port = 17255; // Icecast port numarası
const char* mount = "/WqJQH"; // Yayın uzantınız (Mount Point)
// ÖNEMLİ: Base64 şifrenizi buraya yazın.
// base64encode.org sitesine gidip "source:SUNUCU_SIFRESI" yazarak ürettiğiniz metindir.
// Örnek format: "c291cmNlOm15cGFzc3dvcmQ="
const String base64_auth = "c291cmNlOnpTR0hiRlg2aE0=";
// ====================================================================
// 2. DONANIM VE SES AYARLARI (INMP441 Pin Kombinasyonu)
// ====================================================================
#define I2S_WS 25
#define I2S_SD 32
#define I2S_SCK 26
#define I2S_PORT I2S_NUM_0
#define SAMPLE_RATE 16000 // İnsan sesi için ideal frekans (16kHz)
#define BUFFER_SIZE 512 // Ağ paket boyutu (Byte)
WiFiClient client;
// ====================================================================
// 3. I2S SÜRÜCÜ BAŞLATMA FONKSİYONU
// ====================================================================
void initI2S() {
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), // Sadece Ses Alımı
.sample_rate = SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, // 16-bit derinlik
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, // Sol kanal etkin
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 8,
.dma_buf_len = BUFFER_SIZE,
.use_apll = false
};
i2s_pin_config_t pin_config = {
.bck_io_num = I2S_SCK,
.ws_io_num = I2S_WS,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = I2S_SD
};
i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
i2s_set_pin(I2S_PORT, &pin_config);
}
// ====================================================================
// 4. ICECAST SUNUCUSUNA BAĞLANTI VE KIMLIK DOĞRULAMA (HANDSHAKE)
// ====================================================================
bool connectToIcecast() {
Serial.print("Icecast sunucusuna baglaniliyor: ");
Serial.println(host);
if (!client.connect(host, port)) {
Serial.println("❌ Sunucuya soket baglantisi basarisiz!");
return false;
}
// Icecast SOURCE Protokolü Başlıkları (HTTP 1.0 Standart Girişi)
client.print(String("SOURCE ") + mount + " HTTP/1.0\r\n");
client.print(String("Authorization: Basic ") + base64_auth + "\r\n");
client.print("User-Agent: ESP32_Wifi_Microphone/1.0\r\n");
client.print("Content-Type: audio/mpeg\r\n"); // Sunucuya ses göndereceğimizi bildiriyoruz
client.print("Ice-Name: ESP32 Wi-Fi Mic\r\n");
client.print("Ice-Public: 0\r\n\r\n"); // Header sonu için çift satır atlama sarttır
// Sunucunun yanıt vermesi için kısa bir süre bekle
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println("❌ Sunucu yanit vermedi (Timeout)!");
client.stop();
return false;
}
delay(10);
}
// Sunucu yanıtını kontrol et
if (client.available()) {
String response = client.readStringUntil('\n');
Serial.println("Sunucu Yaniti: " + response);
// Sunucu 200 OK veya HTTP/1.0 200 dönerse giriş onaylanmıştır
if (response.indexOf("200") != -1 || response.indexOf("OK") != -1) {
Serial.println("✅ Kimlik dogrulama basarili! Yayindasiniz.");
return true;
}
}
client.stop();
return false;
}
// ====================================================================
// 5. ANA KURULUM (SETUP)
// ====================================================================
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n--- ESP32 Wi-Fi Mikrofon Baslatiliyor ---");
// Wi-Fi Bağlantısı
WiFi.begin(ssid, password);
Serial.print("Wi-Fi baglantisi kuruluyor");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\n✅ Wi-Fi Baglandi! Yerel IP: " + WiFi.localIP().toString());
// Donanımı Hazırla
initI2S();
}
// ====================================================================
// 6. ANA DÖNGÜ (LOOP)
// ====================================================================
void loop() {
// Eğer bağlantı yoksa veya koptuysa yeniden bağlanmayı dene
if (!client.connected()) {
Serial.println("Baglanti yok, yeniden baglanilmaya calisiliyor...");
if (!connectToIcecast()) {
delay(5000); // Başarısız olursa 5 saniye sonra tekrar dene
return;
}
}
// Mikrofondan veri okumak için tampon bellek oluştur
int16_t i2s_buffer[BUFFER_SIZE];
size_t bytes_read = 0;
// DMA üzerinden mikrofondan veriyi çek (Bloke olmadan ham ses verisi okunur)
i2s_read(I2S_PORT, &i2s_buffer, sizeof(i2s_buffer), &bytes_read, portMAX_DELAY);
// Veri başarıyla okunduysa doğrudan Icecast'e paket paket fırlat
if (bytes_read > 0 && client.connected()) {
client.write((const uint8_t*)i2s_buffer, bytes_read);
}
}