---
substitutions:
  device: echo
  name: Echo
  name_short: Echo
  area: Office R
  comment: Speaker

esphome:
  name: mcu-${device}
  friendly_name: ${name}
  area: ${area}
  comment: ${comment}

esp32:
  variant: esp32
  toolchain: esp-idf
  framework:
    type: esp-idf

packages:
  common: !include common/common.yaml

api:
  services:
    # https://github.com/granadaxronos/120-SONG_NOKIA_RTTTL_RINGTONE_PLAYER_FOR_ARDUINO_UNO/blob/master/RTTTL_PLAYER/songs.h
    - service: play_rtttl
      variables:
        song: string
      then:
        - rtttl.play:
            rtttl: !lambda 'return song;'

i2c:
  sda: 26
  scl: 32
  scan: true #false
  frequency: 100kHz

binary_sensor:
  # - platform: gpio
  #   name: On-Board Button
  #   id: button_buildin
  #   pin:
  #     number: 39
  #     inverted: true
  - platform: gpio
    name: Button
    id: button_ext
    pin:
      number: 12
      inverted: true
      mode:
        input: true
        pullup: true
    on_click:
      - media_player.toggle:
          id: media_out

light:
  # - platform: neopixelbus
  #   type: GRB
  #   pin: 27
  #   variant: WS2812
  #   num_leds: 1
  #   name: On-Board LED"
  #   id: neo_buildin
  - platform: rgb
    name: Light
    id: led_light
    red: led_red
    green: led_green
    blue: led_blue
  - platform: status_led
    id: led_status
    pin:
      number: 23
      allow_other_uses: true

output:
  - platform: ledc
    id: led_red
    pin: 21
  - platform: ledc
    id: led_green
    pin: 25
  - platform: ledc
    id: led_blue
    pin:
      number: 23
      allow_other_uses: true

i2s_audio:
  - id: speaker_bus
    i2s_lrclk_pin: 33
    i2s_bclk_pin: 19

speaker:
  - platform: i2s_audio
    id: speaker_id
    i2s_audio_id: speaker_bus
    dac_type: external
    i2s_dout_pin: 22
    channel: mono
    sample_rate: 16000
    buffer_duration: 100ms  # Smaller buffer
  - platform: mixer
    id: mixer_speaker_id
    output_speaker: speaker_id
    num_channels: 1
    task_stack_in_psram: false
    source_speakers:
      - id: announcement_spk_mixer_input
      - id: media_spk_mixer_input
      - id: rtttl_spk_mixer_input
  - platform: resampler
    id: media_spk_resampling_input
    output_speaker: media_spk_mixer_input
  - platform: resampler
    id: announcement_spk_resampling_input
    output_speaker: announcement_spk_mixer_input
  - platform: resampler
    id: rtttl_spk_resampling_input
    output_speaker: rtttl_spk_mixer_input

media_player:
  - platform: speaker
    id: media_out
    name: Player
    codec_support_enabled: false
    buffer_size: 14000
    media_pipeline:
      speaker: media_spk_resampling_input
      # format: WAV
      # num_channels: 1
      # sample_rate: 8000  # Lower sample rate
    announcement_pipeline:
      speaker: announcement_spk_resampling_input
      # format: WAV
      # num_channels: 1
      # sample_rate: 8000  # Lower sample rate
    on_play:
      - light.turn_on: led_light
    on_idle:
      - light.turn_off: led_light

rtttl:
  id: my_rtttl
  speaker: rtttl_spk_resampling_input

button:
  - platform: template
    name: "Jump Sound"
    on_press:
      - if:
          condition:
            lambda: return !id(speaker_id)->is_running();
          then:
            - lambda: id(speaker_id)->start();
            - delay: 50ms
      - lambda: |-
          static std::vector<int16_t> buffer;
          const int duration_ms = 300;
          const int samples = (16000 * duration_ms) / 1000;
          buffer.resize(samples);
          for (int i = 0; i < samples; i++) {
            float progress = i / (float)samples;
            float bounce = sin(progress * M_PI * 3) * 0.3;
            float pitch_freq = 400 + (600 * progress) + (bounce * 200);
            float envelope = exp(-progress * 4);
            float phase = (i * pitch_freq * 2 * M_PI) / 16000;
            buffer[i] = (int16_t)(1024 * sin(phase) * envelope);
          }
          id(speaker_id)->play((uint8_t*)buffer.data(), buffer.size() * 2);
          id(speaker_id)->finish();
  - platform: template
    name: "Coin Sound"
    on_press:
      - if:
          condition:
            lambda: return !id(speaker_id)->is_running();
          then:
            - lambda: id(speaker_id)->start();
            - delay: 50ms
      - lambda: |-
          static std::vector<int16_t> buffer;
          const int duration_ms = 100;
          const int samples = (16000 * duration_ms) / 1000;
          buffer.resize(samples);
          float phase = 0;
          for (int i = 0; i < samples; i++) {
            float progress = i / (float)samples;
            float freq = (progress < 0.5) ? 988 : 1319;
            float envelope = 1.0 - (progress * 0.7);
            phase += (freq * 2 * M_PI) / 16000;
            float square = (sin(phase) > 0) ? 1.0 : -1.0;
            buffer[i] = (int16_t)(2048 * square * envelope);
          }
          id(speaker_id)->play((uint8_t*)buffer.data(), buffer.size() * 2);
          id(speaker_id)->finish();
  - platform: template
    name: "Fireball Sound"
    on_press:
      - if:
          condition:
            lambda: return !id(speaker_id)->is_running();
          then:
            - lambda: id(speaker_id)->start();
            - delay: 50ms
      - lambda: |-
          static std::vector<int16_t> buffer;
          const int duration_ms = 300;
          const int samples = (16000 * duration_ms) / 1000;
          buffer.resize(samples);
          for (int i = 0; i < samples; i++) {
            float progress = i / (float)samples;
            float pitch_freq = 800 * exp(-progress * 3);
            float noise = (rand() % 100) / 100.0 * 0.3;
            float envelope = exp(-progress * 2);
            float phase = (i * pitch_freq * 2 * M_PI) / 16000;
            buffer[i] = (int16_t)(1024 * (sin(phase) * 0.7 + noise) * envelope);
          }
          id(speaker_id)->play((uint8_t*)buffer.data(), buffer.size() * 2);
          id(speaker_id)->finish();

# microphone:
#   - platform: i2s_audio
#     i2s_din_pin: 23

# http_request:
#   useragent: esphome/${device}
#   timeout: 5s

# # Example configuration entry
# interval:
#   - interval: 1min
#     then:
#       # - script.execute: say_hello_server
#       - http_request.get:
#           url: https://esphome.io
#           verify_ssl: false
