<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      ESP32 + INMP441 + MAX98357A

      INMP441 引腳 連接 ESP32 引腳 說明
      VDD 3.3V 供電
      GND GND 共地
      SCK (BCLK) GPIO26 I2S BCLK
      WS (LRCLK) GPIO25 I2S LRCLK
      SD (DOUT) GPIO22 I2S 數據輸出(麥到ESP32)
      L/R GND 左聲道(或接3.3V右聲道)
      CHIPEN 3.3V 常開
      MAX98357A 引腳 連接 ESP32 引腳 說明
      VIN 5V 功放電源(喇叭供電)
      GND GND 共地
      BCLK GPIO14 I2S BCLK
      LRC GPIO12 I2S LRCLK
      DIN GPIO27 I2S 數據輸入(ESP32 到功放)
      SD/EN 3.3V 常開(靜音腳,低電平關機)
      GAIN 懸空 默認增益 9dB

      platformio.ini

      [env:esp32dev]
      platform = espressif32
      board = esp32dev
      framework = arduino
      monitor_speed = 115200
      upload_speed = 921600
      ; 可選:更安靜的編譯輸出與更快的串口監視器
      monitor_filters = time
      ; 如果遇到 I2S 兼容性問題,可嘗試固定核心版本,例如:
      ; platform = espressif32@6.11.0
      

      main.cpp

      #include <Arduino.h>
      #include "driver/i2s.h"
      
      /* -------- Pin Map -------- */
      // INMP441 (I2S RX on I2S0)
      #define I2S_RX_PORT     I2S_NUM_0
      #define RX_BCLK         26
      #define RX_LRCLK        25
      #define RX_DOUT         22
      #define CH_FMT_RX       I2S_CHANNEL_FMT_ONLY_LEFT   // L/R=GND=左;若接3V3則改為 ONLY_RIGHT
      
      // MAX98357A (I2S TX on I2S1)
      #define I2S_TX_PORT     I2S_NUM_1
      #define TX_BCLK         14
      #define TX_LRCLK        12
      #define TX_DIN          27
      
      // Amplifier SD/EN (mute control, HIGH=enable, LOW=shutdown)
      #define AMP_SD_PIN      33
      
      /* -------- Audio Params -------- */
      #define SAMPLE_RATE     16000                   // 可改 22050/32000/44100/48000(INMP441常用16k/48k)
      #define RX_SAMPLES      512                     // 每次搬運的“單聲道樣本數”
      #define BITS_PER_SAMPLE I2S_BITS_PER_SAMPLE_32BIT   // INMP441 24bit 裝在 32bit 框
      #define SOFT_GAIN_DB    0.0f                    // 簡單軟件增益(dB),負值為衰減,如 -6.0f
      #define LIMIT_ENABLE    1                       // 開啟簡易限幅(避免溢出爆音)
      #define HPF_ENABLE      1                       // 開啟簡易高通(去直流),一階 IIR
      #define HPF_ALPHA       0.999f                  // 0.99~0.999 間可調;越大越慢
      
      /* -------- Helpers -------- */
      // 計算線性增益系數
      static float db_to_gain(float db) {
        return powf(10.0f, db / 20.0f);
      }
      
      // 將 32bit 框中的 24bit(位于[31:8])取出并符號擴展為 32bit
      static inline int32_t unpack24_from32(int32_t x32) {
        int32_t s24 = x32 >> 8;
        if (s24 & 0x00800000) s24 |= 0xFF000000;
        return s24;
      }
      
      // 把 24bit 有效位放回 32bit 框(左對齊至[31:8])
      static inline int32_t pack24_to32(int32_t s) {
        // 限制到 24bit 范圍
        if (s >  0x7FFFFF) s =  0x7FFFFF;
        if (s < -0x800000) s = -0x800000;
        return (s << 8);
      }
      
      /* -------- I2S Init -------- */
      static void i2s_rx_init() {
        i2s_config_t cfg = {
          .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
          .sample_rate = SAMPLE_RATE,
          .bits_per_sample = BITS_PER_SAMPLE,
          .channel_format = CH_FMT_RX,                // 單聲道(左或右)
          .communication_format = I2S_COMM_FORMAT_I2S,
          .intr_alloc_flags = 0,
          .dma_buf_count = 6,
          .dma_buf_len = 256,                         // 每個 DMA 緩沖的樣本數
          .use_apll = false,
          .tx_desc_auto_clear = false,
          .fixed_mclk = 0
        };
        i2s_pin_config_t pin = {
          .bck_io_num   = RX_BCLK,
          .ws_io_num    = RX_LRCLK,
          .data_out_num = -1,
          .data_in_num  = RX_DOUT
        };
        i2s_driver_install(I2S_RX_PORT, &cfg, 0, nullptr);
        i2s_set_pin(I2S_RX_PORT, &pin);
        i2s_set_clk(I2S_RX_PORT, SAMPLE_RATE, BITS_PER_SAMPLE, I2S_CHANNEL_MONO);
      }
      
      static void i2s_tx_init() {
        i2s_config_t cfg = {
          .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX),
          .sample_rate = SAMPLE_RATE,
          .bits_per_sample = BITS_PER_SAMPLE,         // 給 MAX98357A 32bit frame(里頭放 24bit)
          .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, // 立體聲幀(我們 L=R)
          .communication_format = I2S_COMM_FORMAT_I2S,
          .intr_alloc_flags = 0,
          .dma_buf_count = 6,
          .dma_buf_len = 256,
          .use_apll = false,
          .tx_desc_auto_clear = true,
          .fixed_mclk = 0
        };
        i2s_pin_config_t pin = {
          .bck_io_num   = TX_BCLK,
          .ws_io_num    = TX_LRCLK,
          .data_out_num = TX_DIN,
          .data_in_num  = -1
        };
        i2s_driver_install(I2S_TX_PORT, &cfg, 0, nullptr);
        i2s_set_pin(I2S_TX_PORT, &pin);
        i2s_set_clk(I2S_TX_PORT, SAMPLE_RATE, BITS_PER_SAMPLE, I2S_CHANNEL_STEREO);
      }
      
      /* -------- Simple Audio Processing -------- */
      // 直流阻斷(單通道),y[n] = x[n] - x[n-1] + alpha*y[n-1]
      typedef struct {
        float prev_x;
        float prev_y;
      } DCBlocker;
      
      static DCBlocker dcblk = {0};
      
      static inline float dc_block(float x, float alpha) {
        float y = x - dcblk.prev_x + alpha * dcblk.prev_y;
        dcblk.prev_x = x;
        dcblk.prev_y = y;
        return y;
      }
      
      void setup() {
        Serial.begin(115200);
        delay(300);
      
        // SD/EN 控制腳
        pinMode(AMP_SD_PIN, OUTPUT);
        digitalWrite(AMP_SD_PIN, HIGH);  // 先開機(如需開機靜音可先 LOW,準備好后再 HIGH)
      
        i2s_rx_init();
        i2s_tx_init();
      
        Serial.println("ESP32 INMP441 -> MAX98357A passthrough ready.");
      }
      
      void loop() {
        static int32_t rxBuf[RX_SAMPLES];       // I2S 讀回的 32bit 框
        static int32_t txBuf[RX_SAMPLES * 2];   // 立體聲 L=R
      
        size_t rxBytes = 0;
        // 讀單聲道樣本
        esp_err_t er = i2s_read(I2S_RX_PORT, (void*)rxBuf, sizeof(rxBuf), &rxBytes, portMAX_DELAY);
        if (er != ESP_OK || rxBytes == 0) return;
      
        const size_t n = rxBytes / sizeof(int32_t);
        const float g  = db_to_gain(SOFT_GAIN_DB);
      
        // 處理并復制到雙聲道
        size_t j = 0;
        for (size_t i = 0; i < n; ++i) {
          int32_t s = unpack24_from32(rxBuf[i]);           // [-2^23, 2^23-1]
          float xf = (float)s;                              // 轉浮點做處理
      
          // 簡易高通去直流
          if (HPF_ENABLE) xf = dc_block(xf, HPF_ALPHA);
      
          // 軟件增益
          xf *= g;
      
          // 限幅至 24bit
          if (LIMIT_ENABLE) {
            if (xf >  8388607.0f)  xf =  8388607.0f;
            if (xf < -8388608.0f)  xf = -8388608.0f;
          }
          int32_t s_proc = (int32_t)lrintf(xf);
      
          int32_t s32 = pack24_to32(s_proc);
          txBuf[j++] = s32;   // Left
          txBuf[j++] = s32;   // Right
        }
      
        size_t txBytes = 0;
        i2s_write(I2S_TX_PORT, (const void*)txBuf, j * sizeof(int32_t), &txBytes, portMAX_DELAY);
      
        // (可選)打印一點信息
        // static uint32_t t0 = millis();
        // if (millis() - t0 > 1000) {
        //   Serial.printf("rx %u samp, tx %u bytes\n", (unsigned)n, (unsigned)txBytes);
        //   t0 = millis();
        // }
      }
      
      posted @ 2025-08-12 14:14  huh&uh  閱讀(199)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 精品午夜福利短视频一区| 性色av一区二区三区v视界影院| 又爽又黄又无遮挡的激情视频| 乱人伦中文视频在线| 日韩欧美在线综合网另类 | 日韩中文字幕av有码| 亚洲精品www久久久久久| 成人av久久一区二区三区| 久久午夜无码免费| 欧美另类videossexo高潮| 亚洲综合一区二区三区在线| 精选国产av精选一区二区三区| 97人人模人人爽人人少妇| 69天堂人成无码免费视频| 午夜DY888国产精品影院| 保亭| 亚洲精品动漫一区二区三| 国产精品自在线拍国产手机版| 乱色精品无码一区二区国产盗| 东京热一精品无码av| 国产日韩精品一区二区在线观看播放| 亚洲国产午夜福利精品| 2019香蕉在线观看直播视频| 4399理论片午午伦夜理片| 亚洲www永久成人网站| 欧美亚洲精品中文字幕乱码| 国语精品一区二区三区| 这里只有精品免费视频| 亚洲精品专区永久免费区| 4虎四虎永久在线精品免费| 免费观看全黄做爰大片| 日本精品一区二区不卡| 久99久热精品免费视频| 欧美黑人添添高潮a片www| 无码人妻斩一区二区三区 | 熟女人妻aⅴ一区二区三区电影| 国产精品理论片| 2021国产成人精品久久 | 康定县| 国产精品久久久久久福利69堂| 国产成人精品亚洲午夜|