# ============================================================================= # GENERIC ESP32-S3 VOIP FULL-DUPLEX - native ESPHome audio # ============================================================================= # Standalone voip-only profile for native ESPHome audio. # # Purpose: # - No esp_audio_stack. # - No esp_aec / esp_afe software processing. # - voip_stack talks directly to standard ESPHome microphone/speaker. # - Good starting point for hardware codecs/front-ends that already include # echo cancellation or DSP, such as XMOS-based boards. # - Also useful for simple native-I2S builds where you intentionally accept # no software echo cancellation, and for testing VoIP audio directions. # # Endpoint mode: full_duplex. Mic-only and speaker-only variants live in this # same folder and remove the unrelated compile-time pieces. # # Tested hardware example: # - Generic ESP32-S3 with PSRAM. # - INMP441 microphone on one I2S controller. # - MAX98357A amplifier on a second I2S controller. # This is only the tested wiring example; native ESPHome audio can also be # adapted to hardware that exposes mic/speaker on a different bus layout. # ESPHome native I2S does not add software AEC by itself. # # Tested wiring target: Freenove ESP32-S3-WROOM CAM / FNK0085, camera removed. # Change pins for your board. # # INMP441: # SCK/BCLK -> GPIO9 # WS/LRCLK -> GPIO10 # SD/DOUT -> GPIO11 # L/R -> 3V3, tied locally with VDD so the mic outputs right channel # VDD -> 3V3 # GND -> GND # # MAX98357A: # BCLK -> GPIO12 # LRC/WS -> GPIO13 # DIN -> GPIO14 # SD/EN -> GPIO18 (optional; tie high instead if your module prefers) # VIN -> 5V or 3V3 according to your MAX98357A module # GND -> GND # ============================================================================= # ============================================================================= # PROJECT SETUP # ============================================================================= substitutions: name: generic-native-int-fd friendly_name: Generic S3 Native VoIP Full Duplex ext_components_source: "github://n-IA-hane/esphome-intercom@main" voip_stack_components_source: "github://n-IA-hane/esphome-voip-stack@main" audio_stack_components_source: "github://n-IA-hane/esphome-audio-stack@main" # --------------------------------------------------------------------------- # Pinout: native microphone I2S bus # --------------------------------------------------------------------------- rx_i2s_bclk_pin: GPIO9 rx_i2s_lrclk_pin: GPIO10 rx_i2s_din_pin: GPIO11 # --------------------------------------------------------------------------- # Pinout: native speaker I2S bus # --------------------------------------------------------------------------- tx_i2s_bclk_pin: GPIO12 tx_i2s_lrclk_pin: GPIO13 tx_i2s_dout_pin: GPIO14 # --------------------------------------------------------------------------- # Pinout: speaker amplifier and optional status LED # --------------------------------------------------------------------------- speaker_enable_pin: GPIO18 status_led_pin: GPIO48 status_led_chipset: WS2812 status_led_rgb_order: GRB # Shared voip-only packages: SIP transport, HA phonebook sync, API actions, # basic buttons and native diagnostics. packages: core: github://n-IA-hane/esphome-intercom/packages/voip_only.yaml@main voip_transport: github://n-IA-hane/esphome-intercom/packages/voip/transport.yaml@main phonebook_subscribe: github://n-IA-hane/esphome-intercom/packages/voip/phonebook_subscribe.yaml@main ha_api: github://n-IA-hane/esphome-intercom/packages/voip/ha_api.yaml@main voip_entities_full_duplex: github://n-IA-hane/esphome-intercom/packages/voip/entities_full_duplex.yaml@main call_settings: github://n-IA-hane/esphome-intercom/packages/voip/call_settings.yaml@main speaker_mute: github://n-IA-hane/esphome-intercom/packages/voip/speaker_mute.yaml@main s3_base: github://n-IA-hane/esphome-intercom/packages/platform/esp32s3_base.yaml@main native_diagnostics: github://n-IA-hane/esphome-intercom/packages/diagnostics/native.yaml@main status_led: github://n-IA-hane/esphome-intercom/packages/led/status_ws2812_single.yaml@main # ============================================================================= # BOARD AND MEMORY # ============================================================================= # Device identity exposed to ESPHome, HA and the shared VoIP phonebook. esphome: name: ${name} friendly_name: ${friendly_name} # ESP32-S3 native-audio target. This profile is intentionally independent from # esp_audio_stack, so it validates the standard ESPHome audio contracts. esp32: board: freenove_esp32_s3_wroom variant: esp32s3 flash_size: 8MB framework: type: esp-idf advanced: compiler_optimization: PERF sdkconfig_options: CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC: "y" CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG: "y" CONFIG_ESP_CONSOLE_SECONDARY_NONE: "y" # PSRAM gives VoIP tasks and buffers headroom even on the native ESPHome path. psram: mode: octal speed: 80MHz # Persist user settings without excessive flash writes. preferences: flash_write_interval: 5min # ============================================================================= # EXTERNAL COMPONENTS # ============================================================================= # Project components used by the native path: voip_stack plus the shared # internal VoIP task/ring-buffer helpers, without esp_audio_stack. external_components: - source: ${voip_stack_components_source} components: [voip_stack] # ============================================================================= # CONNECTIVITY # ============================================================================= # Normal Wi-Fi client mode. Power save is disabled for low-latency SIP/RTP and # reliable HA API updates. wifi: ssid: !secret wifi_ssid password: !secret wifi_password power_save_mode: NONE # OTA update endpoint used by ESPHome Dashboard and `esphome upload`. ota: - platform: esphome # USB Serial/JTAG logger. VoIP domains stay visible at INFO; noisy entity # domains stay WARN for normal field use. logger: hardware_uart: USB_SERIAL_JTAG level: INFO logs: voip_stack: INFO voip_stack.fsm: INFO voip_stack.tcp: INFO voip_stack.udp: INFO voip_stack.audio: INFO voip_stack.settings: INFO sensor: WARN text_sensor: WARN binary_sensor: WARN switch: WARN number: WARN button: WARN api: WARN api.connection: WARN component: WARN i2s_audio: INFO microphone: INFO speaker: INFO # ============================================================================= # BUSES # ============================================================================= # Two native ESPHome I2S buses: RX for microphone and TX for speaker. i2s_audio: - id: rx_i2s i2s_bclk_pin: ${rx_i2s_bclk_pin} i2s_lrclk_pin: ${rx_i2s_lrclk_pin} - id: tx_i2s i2s_bclk_pin: ${tx_i2s_bclk_pin} i2s_lrclk_pin: ${tx_i2s_lrclk_pin} # ============================================================================= # OUTPUTS AND LIGHTS # ============================================================================= # Optional amplifier enable pin for MAX98357A-style boards. output: - platform: gpio id: speaker_enable pin: ${speaker_enable_pin} # ============================================================================= # AUDIO PIPELINE # ============================================================================= # Native ESPHome microphone. INMP441 is strapped to the right slot. Keep the # wire as stereo and let MicrophoneSource select channel 1; this matches the # stable esp_audio_stack path and avoids mono-slot silence on some IDF/board # combinations. microphone: - platform: i2s_audio id: mic_main adc_type: external i2s_audio_id: rx_i2s i2s_din_pin: ${rx_i2s_din_pin} channel: stereo sample_rate: 48000 bits_per_sample: 32bit correct_dc_offset: true # Native ESPHome speaker. Keep it at VoIP wire format to avoid a # resampler in this regression profile. speaker: - platform: i2s_audio id: hw_speaker dac_type: external i2s_audio_id: tx_i2s i2s_dout_pin: ${tx_i2s_dout_pin} channel: mono sample_rate: 48000 bits_per_sample: 16bit buffer_duration: 128ms timeout: 500ms # ============================================================================= # MEDIA, ASSIST AND VOIP # ============================================================================= # Local SIP phone in full-duplex mode. It advertises 48 kHz/10 ms PCM because # both native mic and speaker are configured at that rate. voip_stack: id: phone task_stacks_in_psram: true buffers_in_psram: true audio: tx: sample_rate: 48000 pcm_format: s16le channels: 1 frame_ms: 10 rx: sample_rate: 48000 pcm_format: s16le channels: 1 frame_ms: 10 microphone_source: microphone: mic_main bits_per_sample: 16 channels: [1] gain_factor: 1 speaker: hw_speaker dc_offset_removal: false ringing_timeout: 30s delete_contact_missing_from: updates_number: 1 # ============================================================================= # RUNTIME LOGIC AND ENTITIES # ============================================================================= # User-facing amp power switch. It only gates the hardware enable pin. switch: - platform: output id: speaker_power name: Speaker Power output: speaker_enable restore_mode: RESTORE_DEFAULT_ON