added i2s Device Tree Files and i2s streaming test (esp32->python)

master
Jake 2025-10-27 11:16:54 +08:00
parent 6330d452c1
commit ee92e1a484
6 changed files with 201 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,53 @@
/dts-v1/;
/plugin/;
/ {
metadata {
title = "Enable I2S3-M0 INMP441";
compatible = "radxa,rock-3c", "radxa,zero3";
category = "audio";
description = "Enable INMP441 on I2S3-M0";
/* Hard-coded GPIO numbers for GPIO3_A3/A4/A5/A6 */
exclusive = "99", "100", "102", "101", "i2s3_2ch";
};
};
&{/} {
dummy_codec: dummy-codec {
compatible = "rockchip,dummy-codec";
#sound-dai-cells = <0>;
};
dummy_sound: dummy-sound {
#address-cells = <1>;
#size-cells = <0>;
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = <&i2s3_2ch>;
simple-audio-card,frame-master = <&i2s3_2ch>;
simple-audio-card,mclk-fs = <256>;
simple-audio-card,name = "i2s3-inmp441";
simple-audio-card,dai-link@0 {
reg = <0>;
format = "i2s";
cpu {
sound-dai = <&i2s3_2ch>;
};
codec {
sound-dai = <&dummy_codec>;
};
};
};
};
&i2s3_2ch {
pinctrl-0 = <&i2s3m0_sclk
&i2s3m0_lrck
&i2s3m0_sdi
&i2s3m0_sdo>;
status = "okay";
};
&i2c3 {
status = "disabled";
};

View File

@ -0,0 +1,51 @@
/dts-v1/;
/plugin/;
/ {
metadata {
title = "Enable I2S3-M0 INMP441";
compatible = "radxa,rock-3c", "radxa,zero3";
category = "audio";
description = "Enable INMP441 on I2S3-M0";
/* Hard-coded GPIO numbers for GPIO3_A3/A4/A5/A6 */
exclusive = "99", "100", "102", "101", "i2s3_2ch";
};
};
&{/} {
dummy_codec: dummy-codec {
compatible = "rockchip,dummy-codec";
#sound-dai-cells = <0>;
};
dummy_sound: dummy-sound {
#address-cells = <1>;
#size-cells = <0>;
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,name = "i2s3-inmp441";
simple-audio-card,dai-link@0 {
reg = <0>;
format = "i2s";
cpu {
sound-dai = <&i2s3_2ch>;
};
codec {
sound-dai = <&dummy_codec>;
};
};
};
};
&i2s3_2ch {
pinctrl-0 = <&i2s3m0_sclk
&i2s3m0_lrck
&i2s3m0_sdi
&i2s3m0_sdo>;
status = "okay";
};
&i2c3 {
status = "disabled";
};

View File

@ -0,0 +1,46 @@
import serial
import wave
import struct
# === CONFIGURATION ===
SERIAL_PORT = 'COM7' # Update this to match your system
BAUD_RATE = 1000000
SAMPLE_RATE = 8000
DURATION_SECONDS = 5
OUTPUT_FILE = 'esp32_audio.wav'
# === SETUP SERIAL ===
ser = serial.Serial(SERIAL_PORT, BAUD_RATE, timeout=0.01)
# === PREPARE TO CAPTURE ===
print(f"Recording {DURATION_SECONDS} seconds of audio...")
samples = []
max_samples = SAMPLE_RATE * DURATION_SECONDS
chunk_size = 4096 # bytes
# === CAPTURE LOOP ===
while len(samples) < max_samples:
data = ser.read(chunk_size)
for i in range(0, len(data) - 1, 2):
sample = int.from_bytes(data[i:i+2], byteorder='little', signed=True)
samples.append(sample)
if len(samples) % 1000 == 0:
print(f"{len(samples)} samples captured")
ser.close()
# === NORMALIZE AUDIO ===
peak = max(abs(s) for s in samples)
scale = 32767 / peak if peak > 0 else 1.0
normalized = [int(max(-32768, min(32767, s * scale))) for s in samples]
# === WRITE TO WAV FILE ===
with wave.open(OUTPUT_FILE, 'w') as wav:
wav.setnchannels(1)
wav.setsampwidth(2) # 16-bit
wav.setframerate(SAMPLE_RATE)
for sample in normalized:
wav.writeframes(struct.pack('<h', sample))
print(f"Saved normalized audio to {OUTPUT_FILE}")

View File

@ -0,0 +1,51 @@
#include <driver/i2s.h>
#define I2S_WS 6 // LRCL (Word Select)
#define I2S_SCK 7 // BCLK (Serial Clock)
#define I2S_SD 8 // DOUT (Serial Data from mic)
#define I2S_PORT I2S_NUM_0
#define BUFFER_SIZE 2048 // Larger buffer = fewer calls
void setup() {
Serial.begin(1000000); // High-speed serial for streaming audio
// I2S configuration
const i2s_config_t i2s_config = {
.mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = 8000,
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = BUFFER_SIZE / 4,
.use_apll = false,
.tx_desc_auto_clear = false,
.fixed_mclk = 0
};
const 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);
}
void loop() {
uint8_t buffer[BUFFER_SIZE];
size_t bytes_read;
if (i2s_read(I2S_PORT, &buffer, BUFFER_SIZE, &bytes_read, portMAX_DELAY) == ESP_OK && bytes_read > 0) {
for (int i = 0; i < bytes_read; i += 4) {
int32_t sample_32 = *(int32_t*)&buffer[i];
int16_t sample_16 = sample_32 >> 12; // Less aggressive shift
Serial.write((uint8_t*)&sample_16, 2);
}
}
}

BIN
test.wav Normal file

Binary file not shown.