Files
vtech/vtech.org
2026-04-20 16:40:49 -04:00

161 KiB
Raw Blame History

C:\Users\moses\Documents\Arduino\ migrated from notes.org [2026-04-19 Sun]

ESP32-DEVKIT-V1

diagram


EN | |_|̅ |_|̅ |_|̅ |_| | D23 VP | | D22 GPIO22 I2C_SCL VN | ┌─────────────┐ | TX0 UART D34 | │ │ | RXO UART D35 | │ │ | D21 GPIO21 I2C_SDA D32 | │ │ | D19 GPIO33 D33 | │ │ | D18 GPIO25 D25 | │ │ | D5 GPIO26 D26 | └─────────────┘ | TX2 D27 | | RX2 D14 | | D4 D12 | | D2 D13 | | D15 GND | | GND VN | | 3V3


en usb boot

pinlist

EN,VP,VN,D34,D35,D32,D33,D25,D26,D27,D14,D12,D13,GND,VN,3V3,GND,D15,D2,D4,RX2,TX2,D5,D18,D19,D21,RX0,TX0,D22,D23

vertical pins

EN VP VN D34 D35 D32 D33 D25 D26 D27 D14 D12 D13 GND VN

3V3 GND D15 D2 D4 RX2 TX2 D5 D18 D19 D21 RX0 TX0 D22 D23

Instructions

Plug-in ESP32 to PC Launch arduino IDE - load "ESP32 Dev Module" Upload sketch, will parse/compile/upload paladin defaults to COM3 (recall this workin in emacs but i forget) plink -serial COM3 -sercfg 115200 | tee-object -FilePath "plink.log" plink -serial COM3 -sercfg 115200 | tee-object -FilePath "plink.log"

Project Expl

intake raw sample words clock in, chop into frames convert sample rate/format wrap in rtp/udp send on schedule

= Running notes =

esp32 + vtech baby monitor [2025-07-27 Sun]

tap speaker to gpio36 need to power (vtech is 6V) esp32wroom vreg is 11 17c / 33 d323; it shoudl be able to take 6v ok consider adding a button to turn on/off the esp32 then add voltage divider bt

baby monitor [2025-09-03 Wed]

this baby monitor (vtech dm221-2) runs at 6V DC, i want to tap a 3V or 5V pin to run an esp32 so i can tap the speaker on an ADC and broadcast it over wifi. here's a pic of the board - i tested some pads and components:

SOT23-3 package: (1pin on top, two on bottom), commong for transistors, diodes, vreg

Q1 lone pin is 3.7V Q6 bottom pins are 3.17V (L) and 3.6V (R) TP20: 3.17V TP12: 3.17V TP21: 3.77V

i might be able to tap an LED? but those are more likely to be current limited right

  • look for 3-pin regulators (SOT23) - middle pin is usually output
  • check caps near the main processor - usually fed by the clean 3.3V rail
  • that U401 chip in the upper section might be a regulator too

also maybe add a small decoupling cap (10uF) close to your tap point bc esp32s are kinda noisy when they boot

https://randomnerdtutorials.com/esp32-pinout-reference-gpios/

https://discord.com/api/webhooks/1411806429576429799/zRFcDio3B_BSxFQ8Rus2gMrJhkpC6olXCGgdZ71L3_7zAxsm2Cy86VBynUxcPNfwq4Xg

wireshark packets

https://support.adder.com/tiki/tiki-index.php?page=Network%3A+Using+Wireshark+to+check+if+IGMP+is+configured

add filter: ip.dst==224.0.0.0/4 IGMP should ounly show traffic to dest 239.255.x.x if someone's listening (me).

  • first few bytes are packet headers! src/dest. bottom left pane, see "Data (172 bytes)" and click, it will highlight the bytes on the right pane. THIS is where your datagram headers are.

RTP headers: byte 0: 0x80 (v=2, p=0, x=0, cc=0) byte 1: 0x00 (m=0, pt=0 → pcmu) byte 2-3: sequence number (big endian) byte 4-7: timestamp (big endian) byte 8-11: ssrc (big endian, arbitrary)

first packet might look like (seq=1,ts=0,ssrc=0x12345678): 80 00 00 01 00 00 00 00 12 34 56 78

my first headers look like WRONG! this was 0000, 0010, not 0000 0001

d8 43 ae 28 55 33 6c c8 00 c8 d3 df after manual construction of headers: d8 43 ae 28 55 33 6c c8 00 c8 b4 b4

should be 0x80 0x00 00 01 00 00 00 01 12 34 56 78

d8 43 ae 28 55 33 6c c8 40 8a bd 80 08 00 45 00

sample - data begins on byte 6!

0000 d8 43 ae 28 55 33 6c c8 40 8a bd 80 08 00 45 00 0010 00 c8 94 45 00 00 40 11 61 9a c0 a8 01 91 c0 a8 0020 01 64 13 8c 13 8c 00 b4 2b 5b 80 00 94 43 00 fc 0030 a9 e0 12 34 56 78 ff ff ff ff ff ff ff ff ff ff 0040 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0050 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0060 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0070 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0080 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 0090 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00a0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00b0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00c0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00d0 ff ff ff ff ff ff ……

DOIT ESP32 DEVKIT V1 Serial: baud 115200

htons() "host-to-network short" converts a short integer from host byte order to network byte order, swapping bytes if needed, for 16-bit values.

htonl() "host-to-network long" converts u_long from host to TCP/IP network order (big-endian)

https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32/api-reference/peripherals/adc.html

For ADC1, configure desired precision and attenuation by calling functions adc1_config_width() and adc1_config_channel_atten().

PCM5102 I2S DAC board?

8000d10f0122a96012345678a198929091969eb33f2319131011161e2fc7a599939091959dad4f261a131011151c2bdda89b949091949baaf92a1b141110141b285aac9c959190939aa6cd2e1d15111013192445b09e9691909398a2be341f1712101218213bb79f97929092979fb73b211

8000d1100122aa00123456781a264dae9d9591909399a4c5301e1611101318223eb49f9792909298a1bb371f17121012171f37bba198929091969eb33f2319131011161e2fc7a599939091959dad4f261a131011151c2bdda89b949091949baaf92a1b141110141b285aac9c959190939aa

8000d1110122aaa012345678131011151d2dcfa69a939091959cab5d281b141011141b2a79aa9b949190949ba8da2c1c151110131a264dae9d9591909399a4c5301e1611101318223eb49f9792909298a1bb371f17121012171f37bba198929091969eb33f2319131011161e2fc7a599939

packet analysis

you lost me. I'm seeing these two bits increment per-packet in byte 6 (first two bits belong to UDP header/checksum): [] [] 80 00 55 fe 00 35 [] [] 80 00 55 ff 00 35 [] [] 80 00 56 00 00 35 [] [] 80 00 56 00 01 35 this looks like bits 2-3 are simply incrementing per packet, which is exactly what our code says ("hdr->seq = htons(seq++)"), only q is whether that's correct?

here's what i'm seeing in the serial out: 80 00 00 00 00 00 00 00 12 34 56 78 80 00 00 01 00 00 00 a0 12 34 56 78 80 00 00 02 00 00 01 40 12 34 56 78 80 00 00 03 00 00 01 e0 12 34 56 78 80 00 00 04 00 00 02 80 12 34 56 78 80 00 00 05 00 00 03 20 12 34 56 78 80 00 00 06 00 00 03 c0 12 34 56 78 80 00 00 07 00 00 04 60 12 34 56 78 80 00 00 08 00 00 05 00 12 34 56 78

another few lines from WS (obv not the same packets): 80 00 08 61 00 05 3c a0 12 34 56 78 80 00 08 62 00 05 3d 40 12 34 56 78 80 00 08 63 00 05 3d e0 12 34 56 78

vlc sdp file - this never worked!

use rtp://192.168.1.100:5004

file

v=0 o=- 0 0 IN IP4 192.168.1.100 s=ESP32 Tone c=IN IP4 192.168.1.100 t=0 0 m=audio 5004 RTP/AVP 0 a=rtpmap:0 PCMU/8000 a=sendonly

new notes vtech [2025-09-04 Thu]

tone2 - claude claude tone works! check the ulaw function deeply, and packet vs payload formation - i dont see memcpy in the functioning tonegen code, just a raw feeding of the packet into the ulaw function, appending header, and firing it off?

Checklist:

  • first 12 bytes: 80 00 SS SS TT TT TT TT XX XX XX XX
  • packet length: 12 + 160 = 172 bytes
  • inter-packet gap: ~20 ms
  • seq monotonic +1; ts monotonic +160; stable ssrc
  • vlc opens via rtp://@:5004 or sdp with a=rtpmap:0 PCMU/8000

working udp-tone2 claude

#include <WiFi.h> #include <WiFiUdp.h> #include <math.h> #include <driver/adc.h>

const char* ssid = "Fios-8EKF5"; const char* password = "hero816cars7050jon"; const char* DEST_IP = "192.168.1.100"; const int UDP_PORT = 5004;

const int OUTPUT_RATE = 8000; / 8kHz const int FRAME_SIZE = 160; / 20ms frames const float TONE_HZ = 440.0;

WiFiUDP udp; uint16_t seq = 0; uint32_t ts = 0;

struct rtp_hdr { uint8_t vpxcc; uint8_t mpt; uint16_t seq; uint32_t ts; uint32_t ssrc; };

static const int16_t exp_lut[256] = { 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 };

uint8_t linear2ulaw(int16_t pcm_val) { int sign = (pcm_val >> 8) & 0x80; if (sign) pcm_val = (short)-pcm_val; if (pcm_val > 32635) pcm_val = 32635; pcm_val = pcm_val + 0x84; int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; return ~(sign | (exponent << 4) | mantissa); }

void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); udp.begin(UDP_PORT); }

float phase = 0; const float phase_inc = 2.0 * M_PI * TONE_HZ / OUTPUT_RATE;

void loop() { static unsigned long last_send = 0; static const unsigned long FRAME_INTERVAL = 20; // 20ms

// only send if it's time unsigned long now = millis(); if (now - last_send < FRAME_INTERVAL) { yield(); return; }

uint8_t packet[12 + FRAME_SIZE]; int16_t samples[FRAME_SIZE];

// generate 20ms tone for (int i=0; i<FRAME_SIZE; i++){ samples[i] = (int16_t)(16000.0 * sinf(phase)); phase += phase_inc; if (phase > 2*M_PI) phase -= 2*M_PI; }

// µ-law encode for (int i=0; i<FRAME_SIZE; i++) packet[12+i] = linear2ulaw(samples[i]);

// build rtp header (fixed) rtp_hdr* hdr = (rtp_hdr*)packet; hdr->vpxcc = 0x80; / v=2, p=0, x=0, cc=0 hdr->mpt = 0x00; / m=0, pt=0 (PCMU) hdr->seq = htons(seq++); hdr->ts = htonl(ts); hdr->ssrc = htonl(0x12345678);

// send packet udp.beginPacket(DEST_IP, UDP_PORT); udp.write(packet, sizeof(packet)); udp.endPacket();

ts += FRAME_SIZE; last_send = now;

yield(); }

orig file to integrate

#include <WiFi.h> // #include <esp_wifi.h> #include <driver/i2s.h> // #include <lwip/sockets.h> #include <WiFiUdp.h>

const char* ssid = "Fios-8EKF5"; const char* password = "hero816cars7050jon"; const char* MULTICAST_IP = "239.255.0.1"; const char* DEST_IP = "192.168.1.100"; const int UDP_PORT = 5004; const int SAMPLE_RATE = 32000; const int OUTPUT_RATE = 8000; const int FRAME_SIZE = 160; static bool blink = false;

const i2s_port_t I2S_PORT = I2S_NUM_0; const adc1_channel_t ADC_CHANNEL = ADC1_CHANNEL_0; //gpio36

char id_str[17]; char status_id[32];

WiFiUDP udp; uint16_t seq = 0; uint32_t ts = 0;

// rtp header struct (minimal) struct rtp_hdr { uint8_t vpxcc; uint8_t mpt; uint16_t seq; uint32_t ts; uint32_t ssrc; };

// µ-law encode uint8_t linear2ulaw(int16_t pcm_val) { const int BIAS = 0x84; const int CLIP = 32635; int mask, seg, uval; pcm_val = pcm_val >> 2; // bitshift right 2^arg (2), unsure if this works? if pcm value is encoded if (pcm_val < 0) { pcm_val = -pcm_val; mask = 0x7F; } else mask = 0xFF; if (pcm_val > CLIP) pcm_val = CLIP; pcm_val += BIAS; seg = 7; for (int v = pcm_val; v > 0x3F; v >>= 1) seg; uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF); return (uval ^ mask); }

void setup_i2s() { i2s_config_t cfg = { .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN), .sample_rate = SAMPLE_RATE, .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, .communication_format = I2S_COMM_FORMAT_I2S_MSB, .intr_alloc_flags = 0, .dma_buf_count = 4, .dma_buf_len = 256, .use_apll = false, .tx_desc_auto_clear = true }; i2s_driver_install(I2S_PORT, &cfg, 0, NULL); i2s_set_adc_mode(ADC_UNIT_1, ADC_CHANNEL); i2s_adc_enable(I2S_PORT); }

void setup() { uint64_t chipid = ESP.getEfuseMac(); snprintf(id_str, sizeof(id_str), "%04X", (uint16_t)(chipid >>32));

Serial.begin(115200); /begin serial connection for debugging / delay(200); // pause for usb host WiFi.begin(ssid, password); Serial.printf("[wifi] "); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.printf(" connected %s with ip %s\n", id_str, WiFi.localIP().toString().c_str());

setup_i2s(); Serial.printf("[udp] "); if (udp.begin(UDP_PORT)) { Serial.printf("listening on port %d\n", UDP_PORT); } else { Serial.println(" failed to bind\n"); } }

void loop() { int16_t samples[FRAME_SIZE*2]; // 320 samples @ 16kHz = 20ms; adc is tied to clock speed size_t bytes_read; i2s_read(I2S_PORT, (char*)samples, sizeof(samples), &bytes_read, portMAX_DELAY);

if (bytes_read == 0) { Serial.println("[i2s] no samples read\n"); return; }

uint8_t payload[FRAME_SIZE]; for (int i=0;i<FRAME_SIZE;i++) { payload[i] = linear2ulaw(samples[i*2]); // take every other sample to keep rtp stream at 8khz }

uint8_t packet[12+FRAME_SIZE]; // rtp_hdr hdr = (rtp_hdr)packet; rtp_hdr* hdr = (rtp_hdr*)packet; hdr->vpxcc = 0x80; / v=2 hdr->mpt = 0x00; / payload type 0 = PCMU hdr->seq = htons(seq++); hdr->ts = htonl(ts); hdr->ssrc = htonl(0x12345678); memcpy(packet+12, payload, FRAME_SIZE);

if (udp.beginPacket(DEST_IP, UDP_PORT)) { udp.write(packet, sizeof(packet)); udp.endPacket(); Serial.print("\r"); Serial.print(blink ? '.' : ' '); Serial.flush(); blink = !blink; };

ts += FRAME_SIZE; // 20ms worth of samples }

compairson bt tonegen and original:

loop()

  • last_send, frame interval

samples[ framesize]

TODO variant tonegen with multicast

circuit descr

the adc (GPIO36) is connected to a vtech pm221 speaker through an RC circuit w/ voltage divider: SP+ to C1 to node A to R1 to node B to Rf to GPIO36; Node B to R2 to node c to SP-; Cf connects node c and node a. GPIO36 is biased with two 1M resistors connected to 3V3 and GND pins. C1 = 1 uF, Cf = 4.7nF, R1 = 22k, R2 = 10k, Rf = 1k SP+ — C1 — a — R1 — b — Rf — GPIO — d — 1M — GND

SP- ——— C2 ——— R2 1M — 3V3

prompt

gravity check this: esp32 script streams udp data (rtp) mode 1: send 440hz default on launch (works) mode 2: (toggle mode on tapping pin) stream from ADC pin

the adc (GPIO36) is connected to a vtech pm221 speaker through an RC circuit w/ voltage divider: SP+ to C1 to node A to R1 to node B to Rf to GPIO36; Node B to R2 to node c to SP-; Cf connects node c and node a. GPIO36 is biased with two 1M resistors connected to 3V3 and GND pins. C1 = 1 uF, Cf = 4.7nF, R1 = 22k, R2 = 10k, Rf = 1k ``` SP+ — C1 — a — R1 — b — Rf — GPIO — d — 1M — GND

SP- ——— Cf ——— R2 1M — 3V3 ```

need to troubleshoot this, either the circuit is wrong, or the ADC implementation. before i redesign the circuit again, i'd like to know how i can test the ADC to be sure it's working; how would i create a 440Hz tone i can feed to the ADC that would be interpreted by our algorithm? the program is right, because I can send the 440hz sine wave through it and it works! so it's almost certainly an issue with the cercuit.

voltage/adc test 1 [2025-09-02 Tue]

  • GND and 43V3 show 4095 range is good! and we're sitting at the midpoint
  • voltage is confirmed (3.3v at 3V3 and 0V at GND)
  • SP+ and SP- sit at 1.6V; ADC sits at 1.6V when idle

data

switched to mic mode 4039-4095 3997-4095 3951-4095 4023-4095 4095-4095 0-1994 0-366 0-366 0-0 0-0 0-0 0-0 0-0 0-0 0-1087 1489-2135 1456-2150 1493-2257 1465-2636 1299-2598 1463-2177 1522-2191 1535-2261

test2

… connected, ip=192.168.1.145 tap pin 4 to switch modes switched to mic mode adcrange:0-4095(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks) adcrange:2698-4095(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks) adcrange:0-1690(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks) adcrange:0-512(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks) adcrange:375-4095(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks) adcrange:0-3909(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks) adcrange:3101-4095(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryfcircuitworks) adcrange:0-3101(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks) adcrange:509-4095(shouldvaryifcircuitworks) adcrange:0-4095(shouldvaryifcircuitworks)

after 1M bias both directions

948-2559 1376-2645 1776-2866 1535-2976 1411-2640 895-2093 921-2638 1119-2496 1719-2878 1422-3535 1383-2812 1041-2290 991-2496 956-2641 1503-2837 1731-2797 1307-2951 1055-2778 976-2686 983-2559 1535-2870 1475-2987 1452-2896 812-2272 1019-2096 852-2596 1616-2867 1739-2805 1417-2734 951-2380 911-2245 855-2549 1611-2992 1733-3344 1236-2799 976-2190 1011-2503 959-2526 1702-2976 1489-2839 1215-3424 959-2206 956-2691 1214-2480 1645-2801 1437-2989 847-2551 1126-2176 849-2590 1486-2879 1655-2837 1424-2881 763-2232 976-2128 975-2734 1555-2876 1711-3258 1232-3037 1104-2457 808-2144 799-2854 1535-3453 1653-3236 1313-2811 934-2172 1006-2784 969-2588 1525-3474 1573-2872 1329-3504 829-2864 921-2156 1040-2542 1136-2985 1682-2921 1495-2895 1033-2694(shouldvar yifcircuitworks) 912-2123 998-2606 1294-2541 1617-3219 1390-3737 1383-2992 1023-2309 948-2391 1043-2490 1731-2804 1567-2835 1391-2976 917-2224 884-2262 1111-2534 1725-2976 1500-2797 1406-2653 787-2205 1023-2486 1189-2517 1580-2915 1509-2954

after circuit swap (this is way worse)

adc range: 0-602 (should vary if circuit works) adc range: 0-487 (should vary if circuit works) adc range: 0-400 (should vary if circuit works) adc range: 0-112 (should vary if circuit works) adc range: 0-621 (should vary if circuit works) adc range: 0-570 (should vary if circuit works) adc range: 0-659 (should vary if circuit works) adc range: 0-325 (should vary if circuit works) adc range: 0-63 (should vary if circuit works) adc range: 0-418 (should vary if circuit works)

[2025-09-03 Wed]

1687/1746 to 2041

… connected, ip=192.168.1.145 tap pin 4 to switch modes switched to mic mode adc range: 1746-1971 (should vary if circuit works) adc range: 1733-1966 (should vary if circuit works) adc range: 1754-1965 (should vary if circuit works) adc range: 1755-1965 (should vary if circuit works) adc range: 1702-2009 (should vary if circuit works) adc range: 1675-1957 (should vary if circuit works) adc range: 1696-2041 (should vary if circuit works) adc range: 1686-1962 (should vary if circuit works) adc range: 1741-2004 (should vary if circuit works) adc range: 1687-1965 (should vary if circuit works) adc range: 1735-1957 (should vary if circuit works) adc range: 1718-2031 (should vary if circuit works) adc range: 1714-2000 (should vary if circuit works)

funcgen

FG- to ESP32 ground FG+ to GPIO36, then to SP+ recognizable tone once DC offset turned on (~halfway bt 0/+) (anything above this resets ESP32) amplitude knob made little/no difference (too high resets the ESP32)

tone very choppy and not 440Hz no tone difference bt GPIO and SP+; either wired wrong (possible) or circuit is functioning (not impacting input)

i'm thinking, we shouldnt expect adc serialout to be useful, unless i send a value ~1Hz so let's generate that first: add a function to generate a 0.5 or .25Hz wave, so that we can see the ADC values change in the serial out; we should see values fluctuate between 0 and 4096, and if we sync the timing right, should get a proper sense of the range right?

ok ran some basic tests

  • ADC confirmed w dmm: 3.3v when ADC-3V3 and 0V when ADC-GND
  • SP+ and SP- sit at 1.6V; ADC sits at 1.6V when idle
  • ADC shows 0 at GND and 4095 at 3V3; midpoint ~2k when idle, with some noise
  • FG- to ESP32 ground; FG+ to GPIO36, then to SP+. recognizable tone once DC offset turned on (~halfway bt "0"/"+")

tone very choppy and not 440Hz, still comes in pulses where the audio cuts ~twice/sec. no tone difference bt connecting FG+ to GPIO vs SP+, indicating the code has more impact than the circuit. Upping to 540 and 640 Hz, I can hear streaming tone go up - good sign! However the ESP-generated 440Hz tone in tone_mode also walks around a bit - this could be another (separate) problem in the ulaw/packetization logic.

i removed the sampling limiter and moved the print to output adv_val directly after: samples[i] = int16_t)((adv_val-2048)*16); So this is actually upstream of packetization… but it's still crazy noisy, here's some data:

  • 0.1Hz wave ranges from ~2100-2650, with noise usually +/-80, but spikes as big as 150 in both directions
  • 1Hz wave ranges from ~2075-2650, with noise usually +/-80
  • 440Hz wave is essentially unrecognizable, though sample rate is def playing a role; range is the same (2075-2750).

So we're currently using 25% of available bandwidth; need to scale ADC better. First, we need to look closely at the ADC reader/scale at lines 115-125: is this doing what we want?

    static int debug_counter = 0;
    int min_val = 4095, max_val = 0;
    for (int i = 0; i < FRAME_SIZE; i++) {
      int adc_val = adc1_get_raw(ADC1_CHANNEL_0);
      if (adc_val < min_val) min_val = adc_val;
      if (adc_val > max_val) max_val = adc_val;
      // convert 12-bit adc (0-4095) to signed 16-bit (-32768 to 32767)
      samples[i] = (int16_t)((adc_val - 2048) * 16); // center around 0, scale up
      Serial.printf("%d\n", adc_val); //remove
    }

Then, at the ulaw encoder:

uint8_t linear2ulaw(int16_t pcm_val) {
  int sign = (pcm_val >> 8) & 0x80;
  if (sign) pcm_val = (short)-pcm_val;
  if (pcm_val > 32635) pcm_val = 32635;
  pcm_val = pcm_val + 0x84;
  int exponent = exp_lut[(pcm_val >> 7) & 0xFF];
  int mantissa = (pcm_val >> (exponent + 3)) & 0x0F;
  return ~(sign | (exponent << 4) | mantissa);
}

claude_v3_functionaladc - decent 440hz tone, still walks a little; music playing through monitor is audible but chops every ~1s, and a high-pitched whiny tone is on top

python plot simple - see final version ~/Documents/Arduino/udp-tone-ai/plots

s = <data>
title = ""
import plotly.graph_objects as go
import pandas as pd

data = [(int(x.split(',')[0]), int(x.split(',')[1])) for x in s.split('\n')]
lows, highs = zip(*data)
x = list(range(len(data)))
go.Figure([go.Scatter(x=x, y=lows, name='low'),go.Scatter(x=x, y=highs, name='high')],title=title).show()

putty output

$ plink -serial COM3 -sercfg 115200 | tee-object -FilePath "plink.log" this is the winner!

other variants untested

putty -serial COM3 -sercfg 115200,8,n,1,N | -sessionlog C:\users\moses\putty.log -logoverwrite plink -serial COM3 -sercfg 115200 > plink.log

$port = new-Object System.IO.Ports.SerialPort COM3,115200,None,8,one
$port.Open()
while($true) {
    if($port.BytesToRead -gt 0) {
        $data = $port.ReadLine()
        "$data" | Tee-Object -Append -FilePath serial.log
    }
}

data

2096 2073 2095 2081 2095 2096 2095 2086 2096 2096 2083 2093 2083 2080 2073 2078 2098 2077 2096 2093 2096 2101 2006 2096 2160 2096 2079 2090 2093 2077 2097 2064 2096 2092 2076 2085 2087 2096 2090 2086 2096 2082 2135 2183 2087 2090 2087 2058 2091 2091 2082 2151 2088 2083 2105 2082 2094 2077 2095 2091 2085 2066 2086 2096 2139 2078 2096 2096 2097 2098 2093 2109 2096 2098 2096 2085 2096 2075 2076 2096 2094 2095 2095 2067 2097 2083 2089 2107 2134 2107 2080 2096 2094 2197 2043 2176 2133 2007 2032 2045 2114 2075 2117 2087 2145 2104 2106 2096 2086 2065 2096 2117 2094 2108 2109 2105 2097 2097 2096 2087 2079 2096 2007 2101 2111 2096 2089 1990 2087 2081 2082 2100 2101 2089 2097 2097 2092 2105 2091 2071 2096 2057 2096 2098 2095 2096 2096 2085 2093 2123 2080 2090 2096 2089 2089 2119 2087 2083 2071 2087 2010 2046 2084 2074 2083 2085 2096 2079 2064 2080 2095 2094 2139 2090 2085 2081 2089 2075 2095 2090 2032 2090 2096 2090 2082 2085 2097 2096 2074 2083 2075 2115 2079 2125 2096 2082 2192 2091 2103 2080 2174 2083 2093 2096 2097 2096 2086 2100 2061 2092 2091 2094 2096 2091 2085 2092 2085 1977 2092 2102 2091 2079 2096 2002 2096 2103 2065 2083 2096 2094 2171 2088 2098 2112 2096 2095 2090 2105 2054 2096 1972 2119 2096 2083 2103 2078 2036 2097 2083 2090 2066 2091 2099 2080 2112 2082 2104 2099 2160 2097 2109 2093 2093 2096 2087 2117 1984 2096 2063 2061 2096 2112 2078 2102 2099 2081 2099 2103 2066 2098 2103 2187 2102 2095 2097 2093 2086 2126 2063 2088 2096 2043 2106 2073 2105 2114 2099 2099 2107 2096 2086 2100 2103 2215 2101 2119 2102 2055 2096 2101 2086 2101 2128 2061 2099 2109 2109 2100 2097 2115 2046 2055 2093 2083 2135 2081 1997 2073 2096 2103 2098 2081 2085 2096 2099 2103 2081 2096 2096 2100 2074 2100 2105 2096 2073 2069 2097 2097 2068 2085 2096 2096 2091 2095 2137 2095 2096 2096 2096 2096 2097 2089 2116 2106 2111 2096 2111 2044 2112 2080 2075 2097 2106 2064 2105 2093 2032 2114 2076 2083 2095 2103 2160 2112 2098 2098 2098 2102 2091 2089 2096 2096 2115 2091 2094 2074 2112 2090 2096 2096 2116 2083 2094 2096 2091 2094 2129 2089 2105 2116 2096 2098 2085 2096 2087 2135 2085 2096 2101 2093 2115 2101 2101 2103 2107 2106 2080 1989 2070 2097 2144 2099 2117 2064 2096 2038 2106 2096 2120 2097 2096 2205 2113 2099 2103 2096 2098 2108 2087 2108 2097 2106 2109 2110 2097 2107 2111 2188 2130 2105 2206 2112 2101 2112 2089 2095 2112 2098 2103 2121 2072 2119 2114 2100 2106 2113 2112 2119 2103 2098 2104 2119 2103 2041 2143 2096 2112 2105 2106 2109 2097 2091 2055 2128 2109 2101 2097 2135 2064 2057 2094 2106 2096 2092 2090 2143 2090 2097 2094 2092 2074 2118 2113 2119 2112 2107 2128 2095 2096 2158 2094 2106 2112 2092 2073 2085 2041 2098 2095 2096 2202 2074 2110 2103 2105 2126 2096 2122 2163 2071 2109 2115 2109 2068 2096 2037 2105 2108 2133 2128 2085 2107 2105 2194 2065 2103 2112 2093 2079 2118 2103 2103 2107 2070 2113 2091 2105 2085 2090 2111 2112 2192 2110 2097 2098 2107 2087 2121 2091 2114 2108 2094 2096 2128 2110 2117 2109 1971 2145 2092 2098 2078 2086 2093 2079 2107 2096 2161 2111 2096 2102 2097 2102 2096 2015 2107 2094 2034 2101 2032 2141 2097 2090 2085 2000 2107 2175 2005 2105 2220 2096 2123 2117 2112 2122 2103 2089 2113 2124 2025 2147 2117 2111 2058 2102 2102 2096 2106 2109 2111 2111 2112 2094 2112 2109 2095 2118 2106 2091 2098 2111 2033 2105 2106 2109 2093 2114 2096 2100 2112 2109 2106 2109 2117 2066 2070 2065 2110 2080 2129 2093 2100 2106 2111 2115 2142 2124 2101 2045 2125 2212 2139 2105 2128 2103 2121 2104 2107 2102 2117 2107 2096 2094 2106 2105 2110 2128 2103 2084 2099 2096 2250 2119 2099 2107 2109 2096 2121 2108 2091 2097 2122 2043 2095 2102 2119 2112 2097 2108 2103 2105 2105 2192 2084 2116 2098 2110 2081 2096 2125 2146 2227 2099 2114 2112 2131 2087 2112 2207 2112 2096 2084 2096 2112 2108 2097 2137 2113 2145 2123 2112 2133 2097 2102 2231 2098 2098 2118 2119 2106 2111 2103 2097 2128 2155 2112 2140 2109 2111 2099 2116 2096 2103 2113 2107 2111 2110 2002 2105 2115 2159 2109 2102 2112 2110 2125 2131 2117 2116 2110 2110 2131 2021 2112 2122 2097 2130 2116 2112 2109 2043 2113 2113 2128 2096 2119 2114 2093 2109 2122 2096 2099 2118 2115 2112 2112 2071 2127 2139 2128 2137 2094 2108 2117 2115 2096 2116 2094 2127 2113 2231 2111 2112 2105 2087 2112 2128 2045 2110 2095 2114 2115 2127 2150 2111 2099 2119 2119 2112 2124 2244 2119 2127 2067 2112 2007 2107 2046 2024 2125 2064 2114 2109 2114 2118 2117 2112 2210 2251 2125 2125 2115 2123 2031 2110 2111 2114 2117 2103 2112 2112 2121 2098 2112 2108 2112 2096 2121 2103 2112 2111 2064 2113 2107 2096 2106 2237 2110 2101 2091 2104 2115 2117 2128 2114 2121 2114 2102 2064 2068 2131 2096 2144 2091 2118 2167 2095 2123 2093 2119 2115 2146 2112 2115 2139 2102 2126 2093 2130 2016 2103 2015 2119 2125 2119 2112 2117 2118 2124 2044 2117 2111 2119 2113 2126 2113 2115 2110 2103 2118 2114 2106 2121 2102 2092 2116 2176 2216 2127 2112 2146 2128 2094 2115 2112 2126 2128 2110 2111 2143 2130 2125 2117 2127 2124 2128 2117 2064 2109 2107 2148 2117 1929 2096 2133 2121 2112 2128 2114 2128 2129 2116 2112 2126 2114 2130 2111 2042 2122 2119 2127 2123 2166 2198 2118 2130 2105 2174 2062 2125 2155 2116 2137 2119 2104 2125 2119 2127 2113 2119 2102 2131 2119 2113 2127 2112 2111 2117 2128 2126 2114 2125 2129 2122 2255 2114 2139 2119 2126 2126 2123 2091 1969 2115 2111 2118 2109 2089 2144 2148 2127 2069 2116 2118 2084 2091 2123 2112 2114 2126 2117 2128 2130 2087 2111 2125 2163 2126 2127 2128 2125 2122 2128 2221 2096 2118 2119 2107 2128 2125 2123 2131 2122 2128 2122 2175 2128 2162 2142 2102 2121 2127 2113 2123 2118 2128 2116 2128 2119 2126 2138 2129 2128 2158 2153 2141 2121 2120 2125 2114 2092 2128 2151 2128 2128 2128 2121 2122 2137 2118 2098 2127 2125 2129 2123 2124 2095 2119 2107 2107 2126 2129 2125 2084 2103 2124 2118 2169 2112 2128 2118 2123 2125 2128 2119 2138 2144 2067 2127 2107 2115 2113 2139 2139 2126 2129 2101 2081 2128 2147 2128 2141 2129 2128 2112 2158 2131 2123 2102 2176 2130 2121 2101 2131 2133 2122 2095 2114 2202 2128 2125 2101 2128 2096 2131 2128 2128 2137 2131 2121 2128 2137 2102 2115 2129 2127 2131 2153 2127 2128 2133 2109 2129 2127 2013 2137 2109 2134 2148 2105 2125 2151 2128 2117 2124 2113 2101 2128 2131 2144 2126 2025 2125 2119 2130 2130 2138 2125 2126 2118 2131 2124 2117 2136 2125 2097 2126 2133 2111 2121 2118 2126 2131 2131 2144 2131 2129 2132 2128 2155 2127 2145 2171 2128 2135 2145 2151 2149 2140 2138 2167 2128 2137 2105 2150 2127 2134 2137 2128 2133 2073 2154 2114 2136 2142 2135 2146 2150 2182 2122 2118 2147 2128 2107 2125 2129 2119 2123 2118 2128 2138 2134 2125 2149 2135 2129 2138 2111 2138 2134 2142 2146 2094 2069 2141 2128 2174 2128 2127 2128 2136 2075 2115 2135 2148 2143 2064 2128 2133 2134 2129 2140 2133 2100 2030 2150 2043 2129 2135 2146 2142 2116 2132 2146 2138 2138 2177 2089 2145 2146 2138 2256 2157 2131 2189 2134 2151 2144 2141 2139 2148 2148 2145 2134 2033 2157 2145 2064 2132 2132 2181 2137 2144 2135 2125 2141 2118 2165 2143 2157 2150 2133 2131 2150 2138 2146 2129 2240 2145 2133 2129 2099 2115 2160 2143 2160 2128 2160 2069 2142 2133 2149 2134 2125 2147 2142 2139 2151 2066 2135 2143 2133 2128 2128 2140 2140 2147 2122 2149 2147 2156 2144 2150 2071 2141 2063 2144 2141 2141 2151 2145 2141 2143 2151 2142 2147 2147 2139 2081 2155 2147 2091 2154 2147 2149 2142 2128 2130 2159 2154 2149 2146 2120 2111 2134 2133 2144 2133 2147 2156 2162 2145 2139 2149 2133 2141 2150 2107 2166 2142 2174 2148 2155 2129 2128 2151 2136 2149 2153 2054 2129 2149 2174 2191 2155 2146 2167 2158 2036 2142 2130 2149 2141 2130 2145 2139 2138 2151 2142 2150 2145 2161 2145 2145 2145 2145 2180 2127 2143 2143 2155 2107 2145 2148 2143 2143 2149 2131 2147 2128 2226 2145 2146 2193 2071 2158 2155 2142 2160 2290 2137 2146 2141 2143 2144 2081 2160 2145 2150 2137 2143 2128 2160 2135 2160 2150 2127 2174 2161 2131 2140 2166 2157 2128 2141 2145 2194 2128 2160 2160 2141 2221 2150 2157 2148 2148 2128 2136 2148 2182 2146 2153 2155 2094 2208 2143 2158 2158 2137 2172 2155 2265 2139 2154 2151 2149 2139 2136 2148 2146 2137 2167 2155 2143 2160 2159 2174 2157 2154 2151 2162 2032 2159 2202 2128 2148 2176 2160 2153 2196 2143 2157 2158 2142 2149 2155 2128 2164 2156 2157 2162 2144 2158 2160 2156 2191 2144 2151 2133 2243 2173 2143 2146 2183 2154 2151 2167 2158 2088 2150 2129 2175 2227 2147 2155 2151 2155 2149 2192 2159 2152 2156 2150 2160 2111 2160 2160 2156 2140 2158 2162 2148 2159 2118 2139 2117 2128 2163 2148 2156 2171 2147 2138 2160 2149 2251 2151 2147 2155 2153 2159 2155 2160 2149 2155 2114 2154 2085 2212 2160 2160 2137 2165 2155 2160 2179 2027 2143 2167 2156 2164 2072 2158 2160 2167 2165 2161 2159 2157 2161 2173 2178 2158 2179 2141 2165 2171 2169 2133 2161 2160 2160 2198 2160 2154 2160 2171 2160 2160 2160 2170 2159 2135 2157 2104 2147 2111 2141 2256 2147 2147 2169 2148 2157 2170 2174 2160 2149 2135 2159 2143 2162 2214 2189 2160 2160 2165 2130 2169 2154 2186 2158 2186 2160 2144 2160 2170 2169 2171 2161 2143 2157 2160 2160 2176 2173 2155 2178 2160 2158 2143 2154 2143 2129 2160 2157 2163 2195 2161 2167 2155 2170 2173 2171 2160 2039 2089 2161 2201 2175 2163 2285 2173 2155 2158 2157 2102 2169 2122 2160 2160 2174 2167 2163 2170 2176 2133 2160 2166 2117 2164 2163 2161 2151 2172 2139 2165 2185 2173 2120 2177 2164 2156 2176 2163 2160 2160 2161 2164 2177 2160 2185 2160 2168 2143 2173 2157 2195 2161 2163 2163 2162 2142 2131 2175 2174 2166 2160 2154 2147 2171 2164 1974 2160 2039 2160 2160 2176 2175 2163 2157 2157 2187 2182 2161 2171 2166 2152 2165 2164 2179 2162 2138 2171 2176 2162 2170 2160 2162 2162 2180 2160 2155 2166 2165 2174 2173 2160 2153 2138 2165 2185 2167 2153 2174 2175 2131 2165 2174 2167 2289 2180 2170 2171 2301 2187 2176 2123 2170 2175 2175 2154 2178 2158 2174 2107 2185 2112 2127 2159 2171 2170 2171 2268 2176 2190 2169 2189 2161 2161 2168 2170 2170 2176 2170 2179 2167 2158 2160 2154 2098 2160 2167 2077 2192 2160 2176 2160 2150 2135 2157 2158 2166 2148 2169 2167 2187 2198 2176 2173 2170 2160 2206 2160 2175 2160 2177 2187 2174 2175 2164 2185 2161 2175 2173 2171 2182 2177 2175 2165 2178 2176 2175 2178 2165 2170 2178 2173 2155 2161 2171 2189 2175 2173 2162 2191 2169 2162 2186 2137 2162 2180 2175 2209 2173 2176 2165 2171 2037 2178 2175 2166 2174 2167 2174 2171 2187 2085 2186 2165 2163 2175 2182 2171 2148 2160 2167 2181 2214 2160 2176 2179 2160 2179 2166 2168 2178 2187 2176 2118 2171 2162 2161 2183 2191 2187 2160 2170 2181 2098 2191 2176 2144 2160 2178 2190 2182 2170 2179 2181 2177 2190 2176 2224 2192 2169 2192 2190 2126 2193 2164 2170 2177 2139 2181 2176 2182 2183 2180 2185 2201 2195 2161 2191 2181 2176 2173 2170 2186 2256 2178 2275 2174 2177 2182 2166 2172 2173 2131 2166 2183 2169 2183 2160 2179 2179 2171 2187 2189 2183 2174 2121 2166 2173 2096 2160 2176 2163 2117 2160 2178 2179 2189 2190 2178 2171 2221 2174 2179 2176 2170 2192 2188 2261 2196 2175 2190 2201 2194 2185 2186 2127 2171 2288 2188 2192 2192 2174 2102 2149 2186 2187 2187 2192 2173 2177 2231 2169 2183 2178 2011 2189 2225 2182 2147 2137 2221 2103 2182 2083 2183 2196 2190 2192 2187 2186 2199 2181 2187 2185 2180 2193 2192 2192 2179 2192 2199 2176 2202 2188 2186 2195 2190 2176 2163 2183 2176 2192 2195 2190 2174 2192 2185 2311 2218 2169 2194 2186 2197 2155 2259 2192 2190 2209 2191 2177 2196 2181 2200 2196 2181 2240 2192 2282 2259 2189 2195 2204 2200 2176 2161 2191 2237 2186 2182 2076 2197 2198 2187 2207 2190 2213 2177 2178 2173 2142 2192 2185 2186 2187 2192 2174 2182 2194 2215 2170 2191 2194 2192 2176 2188 2210 2173 2192 2164 2145 2191 2182 2182 2194 2227 2082 2206 2191 2173 2174 2206 2192 2183 2187 2192 2160 2239 2208 2194 2151 2192 2196 2190 2187 2185 2192 2190 2201 2187 2223 2193 2191 2182 2185 2195 2192 2135 2160 2286 2176 2192 2191 2192 2234 2195 2226 2223 2020 2198 2203 2199 2202 2182 2199 2185 2193 2237 2197 2192 2192 2188 2192 2176 2197 2203 2156 2204 2174 2192 2197 2194 2181 2192 2180 2192 2245 2196 2188 2195 2198 2242 2166 2192 2099 2192 2196 2191 2203 2176 2196 2180 2194 2205 2192 2192 2192 2197 2192 2219 2192 2166 2215 2194 2203 2214 2200 2196 2241 2197 2240 2223 2205 2139 2187 2192 2171 2201 2185 2198 2187 2213 2192 2194 2193 2208 2202 2131 2203 2197 2194 2180 2198 2194 2182 2204 2172 2158 2192 2203 2197 2198 2204 2181 2240 2265 2208 2202 2214 2187 2176 2241 2099 2163 2209 2196 2205 2190 2238 2215 2205 2205 2197 2199 2218 2224 2212 2197 2207 2294 2199 2288 2309 2192 2209 2135 2203 2192 2203 2198 2147 2170 2203 2206 2197 2162 2193 2205 2199 2206 2332 2199 2207 2194 2191 2151 2288 2206 2206 2192 2219 2198 2187 2224 2201 2211 2210 2195 2192 2201 2202 2211 2199 2201 2174 2198 2206 2176 2222 2205 2209 2192 2205 2192 2205 2192 2188 2209 2213 2210 2192 2206 2212 2205 2203 2208 2228 2208 2224 2209 2204 2212 2205 2278 2210 2202 2200 2193 2203 2224 2254 2197 2212 2210 2222 2224 2207 2227 2204 2203 2213 2204 2192 2208 2176 2192 2199 2203 2219 2203 2192 2195 2206 2207 2215 2224 2224 2197 2203 2200 2181 2194 2188 2204 2207 2131 2192 2206 2198 2203 2204 2221 2213 2224 2207 2203 2182 2199 2166 2191 2195 2215 2203 2208 2252 2186 2207 2224 2195 2224 2247 2315 2181 2369 2192 2203 2117 2206 2226 2229 2214 2218 2224 2199 2214 2193 2209 2206 2208 2217 2240 2211 2202 2208 2211 2217 2208 2229 2240 2215 2222 2192 2213 2199 2198 2192 2207 2206 2215 2224 2267 2208 2340 2213 2218 2211 2173 2214 2241 2220 2224 2208 2213 2198 2209 2224 2213 2223 2240 2213 2219 2215 2219 2201 2213 2202 2215 2208 2208 2213 2163 2185 2230 2217 2215 2224 2181 2224 2225 2205 2236 2253 2225 2215 2192 2225 2209 2203 2207 2210 2222 2207 2222 2222 2199 2237 2223 2224 2224 2204 2209 2224 2231 2231 2210 2224 2217 2219 2219 2224 2256 2218 2215 2209 2198 2224 2231 2222 2221 2236 2274 2187 2149 2254 2223 2210 2240 2187 2201 2220 2207 2224 2213 2150 2199 2192 2224 2235 2213 2215 2222 2224 2237 2224 2240 2316 2223 2303 2241 2171 2191 2221 2211 2190 2192 2187 2217 2220 2221 2225 2215 2215 2222 2219 2224 2255 2223 2209 2205 2218 2285 2219 2195 2198 2145 2211 2224 2224 2223 2215 2202 2224 2224 2240 2223 2206 2219 2224 2202 2192 2256 2223 2222 2227 2224 2142 2218 2320 2209 2215 2162 2223 2227 2214 2226 2221 2159 2255 2224 2227 2224 2218 2226 2240 2228 2229 2230 2277 2206 2255 2231 2254 2212 2223 2275 2237 2224 2207 2203 2225 2225 2222 2257 2230 2154 2229 2222 2220 2218 2227 2227 2224 2209 2209 2192 2219 2239 2255 2206 2218 2224 2213 2192 2230 2219 2229 2246 2223 2224 2239 2141 2232 2226 2207 2223 2202 2336 2224 2146 2223 2216 2217 2235 2222 2272 2242 2228 2227 2240 2229 2256 2223 2225 2161 2245 2251 2198 2234 2160 2224 2226 2240 2229 2215 2243 2243 2138 2224 2226 2229 2228 2217 2234 2222 2233 2229 2224 2240 2194 2223 2231 2230 2167 2236 2226 2231 2225 2235 2307 2240 2235 2234 2256 2234 2217 2227 2224 2239 2230 2254 2228 2254 2231 2224 2192 2224 2229 2226 2303 2229 2224 2259 2227 2225 2240 2321 2224 2225 2223 2231 2224 2230 2231 2227 2235 2251 2224 2224 2223 2269 2232 2229 2231 2199 2235 2240 2193 2206 2274 2244 2282 2236 2241 2256 2240 2240 2235 2234 2234 2219 2253 2227 2238 2256 2182 2229 2184 2244 2207 2241 2246 2238 2274 2233 2224 2230 2240 2256 2235 2354 2240 2235 2239 2254 2256 2240 2288 2238 2237 2238 2241 2240 2238 2246 2240 2242 2250 2243 2230 2253 2224 2277 2238 2234 2228 2241 2256 2256 2230 2223 2233 2239 2207 2240 2233 2162 2097 2240 2237 2190 2185 2231 2230 2359 2241 2215 2241 2224 2226 2235 2239 2245 2240 2246 2256 2266 2244 2271 2275 2252 2240 2242 2245 2236 2264 2253 2245 2380 2193 2246 2261 2237 2253 2221 2251 2243 2246 2246 2249 2249 2254 2246 2256 2254 2246 2240 2253 2244 2238 2162 2135 2256 2308 2256 2247 2240 2220 2241 2250 2246 2225 2243 2242 2224 2255 2262 2267 2239 2239 2229 2240 2318 2240 2245 2203 2237 2205 2190 2239 2266 2293 2349 2247 2195 2253 2222 2244 2250 2256 2222 2245 2231 2243 2227 2256 2290 2222 2227 2247 2245 2347 2241 2249 2224 2250 2245 2245 2271 2239 2256 2238 2255 2268 2255 2235 2247 2250 2245 2236 2240 2253 2255 2259 2245 2259 2265 2253 2251 2257 2241 2256 2256 2253 2246 2261 2239 2275 2241 2256 2243 2216 2222 2246 2253 2246 2246 2275 2269 2250 2286 2240 2253 2265 2254 2261 2256 2285 2249 2250 2256 2238 2253 2253 2256 2256 2272 2259 2254 2367 2262 2246 2263 2358 2306 2267 2263 2202 2257 2256 2256 2212 2262 2271 2257 2259 2261 2257 2240 2251 2236 2152 2258 2259 2240 2229 2257 2257 2259 2254 2345 2240 2256 2256 2255 2256 2254 2252 2242 2256 2246 2217 2256 2256 2235 2267 2271 2254 2245 2249 2247 2254 2257 2271 2220 2256 2255 2247 2250 2262 2257 2219 2259 2257 2258 2288 2256 2253 2256 2262 2247 2272 2262 2269 2259 2166 2263 2287 2247 2256 2255 2259 2229 2247 2244 2263 2233 2272 2236 2256 2256 2256 2261 2240 2253 2250 2234 2251 2255 2263 2258 2294 2256 2256 2256 2165 2243 2264 2256 2261 2257 2228 2253 2250 2283 2242 2259 2268 2273 2353 2163 2258 2250 2271 2267 2270 2385 2243 2261 2263 2273 2305 2273 2247 2315 2256 2231 2301 2262 2256 2256 2295 2293 2316 2256 2241 2265 2257 2262 2257 2247 2251 2256 2271 2274 2260 2394 2209 2260 2269 2261 2247 2260 2257 2263 2260 2273 2253 2256 2253 2272 2235 2265 2263 2309 2269 2262 2277 2279 2267 2254 2310 2279 2218 2263 2307 2260 2276 2267 2267 2286 2273 2270 2243 2380 2274 2271 2267 2261 2194 2283 2291 2273 2270 2268 2285 2289 2261 2231 2271 2270 2279 2273 2243 2260 2267 2320 2278 2263 2253 2265 2336 2281 2253 2271 2267 2273 2256 2256 2265 2261 2195 2259 2271 2311 2263 2160 2347 2278 2185 2302 2259 2265 2273 2208 2302 2259 2256 2267 2269 2246 2254 2267 2271 2193 2265 2272 2236 2266 2260 2265 2339 2263 2346 2261 2273 2278 2256 2281 2272 2305 2257 2274 2279 2278 2258 2242 2270 2256 2271 2256 2274 2273 2272 2255 2283 2275 2256 2281 2303 2213 2283 2261 2268 2267 2279 2244 2267 2265 2279 2389 2340 2281 2276 2275 2256 2290 2278 2268 2278 2305 2320 2271 2348 2298 2295 2283 2282 2256 2290 2277 2263 2251 2277 2279 2225 2288 2282 2289 2227 2282 2224 2286 2291 2288 2276 2284 2254 2271 2267 2270 2286 2276 2277 2287 2254 2285 2277 2271 2265 2269 2288 2355 2267 2285 2307 2365 2286 2277 2311 2269 2283 2273 2289 2285 2287 2275 2286 2288 2272 2278 2239 2293 2283 2286 2288 2272 2227 2271 2295 2289 2285 2287 2253 2292 2282 2285 2284 2281 2288 2285 2277 2267 2405 2327 2267 2305 2320 2361 2275 2288 2281 2288 2289 2275 2283 2267 2312 2288 2292 2283 2274 2285 2277 2295 2279 2321 2282 2283 2274 2291 2274 2287 2277 2289 2268 2288 2277 2282 2284 2283 2420 2257 2283 2282 2278 2352 2272 2288 2294 2285 2269 2290 2290 2306 2293 2241 2284 2267 2298 2266 2272 2261 2287 2303 2284 2314 2273 2283 2287 2311 2278 2284 2284 2280 2259 2285 2297 2151 2246 2285 2288 2279 2294 2288 2286 2341 2299 2297 2294 2399 2287 2289 2285 2335 2274 2291 2337 2288 2285 2295 2334 2302 2277 2290 2275 2288 2288 2289 2283 2217 2275 2290 2306 2300 2348 2288 2293 2288 2298 2295 2303 2297 2289 2299 2292 2286 2280 2295 2288 2288 2303 2288 2281 2290 2291 2295 2285 2281 2233 2282 2301 2268 2338 2289 2290 2281 2284 2291 2291 2286 2280 2296 2301 2310 2305 2330 2292 2271 2398 2299 2195 2187 2349 2304 2287 2273 2291 2289 2296 2289 2305 2299 2290 2304 2250 2272 2311 2311 2295 2295 2240 2299 2299 2293 2301 2369 2298 2300 2406 2295 2245 2337 2301 2383 2302 2307 2311 2299 2331 2306 2290 2287 2303 2297 2295 2283 2294 2302 2292 2330 2288 2315 2298 2339 2317 2289 2314 2293 2289 2301 2303 2290 2299 2292 2292 2317 2290 2316 2320 2298 2256 2289 2321 2323 2320 2309 2311 2298 2304 2427 2314 2305 2415 2319 2305 2331 2295 2303 2304 2303 2290 2314 2293 2318 2286 2320 2304 2288 2313 2304 2307 2321 2341 2300 2310 2357 2299 2420 2309 2320 2256 2299 2349 2307 2304 2244 2293 2304 2299 2227 2291 2307 2311 2293 2304 2303 2306 2306 2319 2335 2305 2307 2309 2306 2301 2311 2412 2311 2295 2256 2306 2323 2310 2320 2301 2301 2285 2313 2293 2306 2304 2304 2320 2304 2306 2283 2331 2327 2321 2298 2313 2316 2322 2297 2465 2338 2306 2305 2331 2346 2303 2311 2316 2317 2317 2305 2304 2313 2311 2346 2295 2311 2319 2320 2270 2310 2308 2245 2322 2284 2299 2307 2290 2302 2327 2298 2306 2318 2287 2320 2313 2309 2310 2283 2303 2317 2304 2215 2307 2327 2315 2341 2308 2319 2304 2309 2334 2320 2309 2319 2310 2426 2304 2295 2316 2298 2287 2318 2314 2311 2322 2307 2274 2319 2295 2311 2330 2318 2320 2311 2319 2320 2319 2311 2306 2320 2314 2398 2308 2315 2323 2301 2320 2309 2428 2320 2320 2315 2366 2321 2334 2317 2321 2309 2317 2304 2320 2245 2319 2320 2318 2321 2321 2329 2351 2319 2315 2320 2325 2331 2320 2312 2352 2306 2307 2315 2320 2288 2320 2286 2320 2327 2325 2313 2314 2320 2289 2354 2320 2317 2323 2417 2325 2298 2331 2317 2323 2330 2331 2317 2327 2319 2301 2317 2320 2291 2323 2317 2325 2311 2316 2309 2325 2336 2315 2305 2321 2311 2320 2290 2331 2335 2205 2346 2319 2320 2314 2236 2320 2323 2311 2334 2320 2350 2326 2322 2321 2317 2363 2323 2314 2318 2335 2316 2325 2343 2336 2328 2327 2333 2335 2330 2287 2323 2325 2325 2333 2330 2333 2323 2325 2297 2325 2325 2238 2289 2335 2318 2326 2305 2310 2455 2317 2337 2329 2320 2322 2275 2335 2333 2322 2334 2358 2335 2400 2320 2322 2225 2326 2325 2321 2347 2323 2323 2339 2350 2327 2336 2352 2323 2331 2350 2335 2337 2333 2322 2461 2303 2343 2329 2347 2233 2341 2241 2351 2334 2333 2329 2342 2326 2319 2330 2350 2322 2337 2331 2325 2333 2320 2321 2325 2325 2326 2336 2333 2419 2349 2446 2302 2331 2335 2339 2328 2335 2321 2288 2333 2320 2373 2334 2329 2325 2353 2330 2367 2270 2329 2331 2329 2329 2347 2327 2334 2331 2281 2322 2337 2335 2331 2341 2334 2343 2333 2341 2330 2338 2339 2330 2346 2331 2337 2329 2323 2356 2315 2329 2310 2333 2336 2352 2350 2327 2320 2338 2428 2332 2325 2335 2332 2331 2325 2327 2323 2351 2320 2333 2345 2332 2263 2341 2331 2323 2334 2316 2309 2337 2363 2366 2285 2346 2311 2339 2323 2225 2335 2330 2346 2337 2357 2352 2343 2334 2332 2331 2350 2349 2320 2340 2321 2321 2305 2339 2343 2353 2279 2331 2345 2352 2341 2336 2339 2352 2361 2338 2346 2361 2355 2389 2334 2342 2333 2342 2341 2352 2333 2357 2355 2300 2343 2338 2337 2341 2331 2352 2322 2477 2346 2339 2329 2311 2347 2345 2345 2287 2338 2352 2354 2342 2346 2346 2407 2339 2343 2342 2352 2307 2342 2347 2333 2485 2350 2352 2336 2334 2336 2477 2255 2333 2347 2338 2336 2338 2337 2363 2346 2354 2362 2286 2330 2340 2345 2331 2343 2406 2345 2363 2446 2346 2342 2337 2296 2320 2347 2363 2349 2356 2349 2352 2343 2342 2433 2352 2348 2343 2350 2343 2302 2352 2382 2352 2334 2383 2349 2362 2366 2347 2351 2352 2359 2337 2342 2352 2352 2341 2357 2347 2355 2347 2315 2348 2353 2379 2257 2366 2338 2291 2478 2293 2371 2353 2353 2374 2352 2340 2295 2347 2417 2336 2365 2339 2356 2363 2352 2364 2349 2356 2519 2333 2355 2357 2359 2305 2351 2359 2353 2368 2353 2371 2354 2341 2352 2352 2356 2351 2363 2359 2358 2299 2378 2326 2377 2351 2357 2365 2390 2352 2382 2351 2331 2301 2339 2353 2350 2357 2353 2352 2332 2357 2338 2352 2334 2350 2354 2352 2299 2314 2347 2342 2371 2333 2352 2350 2379 2359 2390 2352 2299 2353 2343 2353 2358 2363 2352 2363 2353 2331 2373 2357 2343 2353 2367 2363 2368 2352 2341 2411 2353 2361 2364 2354 2514 2353 2352 2353 2355 2350 2356 2351 2355 2356 2358 2350 2288 2355 2358 2349 2364 2370 2366 2346 2353 2374 2435 2410 2351 2357 2361 2354 2371 2369 2361 2367 2358 2364 2341 2367 2352 2326 2378 2370 2346 2352 2353 2352 2361 2350 2394 2368 2354 2369 2357 2286 2359 2361 2380 2363 2368 2352 2349 2368 2367 2377 2358 2311 2341 2362 2365 2361 2367 2355 2352 2372 2589 2368 2352 2350 2352 2359 2383 2370 2363 2384 2363 2364 2345 2368 2372 2353 2358 2341 2277 2379 2373 2368 2377 2378 2371 2384 2368 2367 2375 2369 2335 2389 2375 2371 2377 2417 2378 2370 2384 2332 2195 2388 2369 2409 2377 2355 2289 2365 2369 2372 2397 2503 2366 2339 2365 2366 2368 2384 2366 2369 2450 2367 2367 2371 2342 2366 2377 2368 2354 2367 2371 2366 2219 2381 2352 2368 2352 2379 2368 2271 2487 2369 2295 2356 2349 2342 2384 2369 2368 2415 2320 2362 2287 2451 2368 2368 2365 2320 2384 2356 2357 2365 2376 2345 2346 2351 2369 2352 2365 2352 2365 2364 2353 2368 2366 2371 2378 2374 2377 2372 2320 2370 2368 2400 2364 2369 2543 2358 2304 2368 2395 2321 2368 2383 2372 2371 2375 2321 2382 2386 2382 2307 2366 2379 2372 2368 2382 2365 2374 2374 2379 2321 2294 2371 2372 2365 2304 2371 2386 2369 2367 2375 2386 2374 2372 2375 2386 2361 2378 2368 2375 2378 2363 2381 2384 2385 2383 2390 2384 2387 2386 2348 2375 2422 2373 2386 2358 2327 2362 2384 2384 2402 2389 2378 2370 2379 2368 2386 2382 2393 2423 2381 2401 2378 2359 2359 2379 2395 2359 2382 2384 2365 2363 2384 2395 2381 2371 2480 2420 2379 2342 2383 2357 2379 2382 2340 2372 2391 2351 2386 2430 2354 2375 2383 2368 2389 2361 2380 2374 2398 2373 2386 2375 2363 2395 2385 2459 2373 2384 2377 2384 2373 2379 2372 2381 2389 2378 2380 2384 2387 2376 2403 2379 2371 2395 2378 2384 2381 2378 2291 2387 2378 2359 2386 2398 2379 2372 2290 2382 2389 2391 2385 2368 2381 2373 2404 2385 2382 2386 2375 2493 2336 2397 2387 2428 2391 2413 2403 2391 2430 2401 2398 2384 2384 2367 2389 2416 2377 2387 2377 2385 2363 2386 2391 2385 2391 2396 2398 2391 2386 2378 2384 2384 2382 2386 2387 2383 2382 2373 2411 2420 2385 2383 2384 2384 2389 2366 2384 2386 2401 2350 2386 2397 2400 2384 2391 2389 2382 2386 2377 2383 2414 2390 2366 2390 2391 2383 2389 2402 2388 2395 2401 2326 2394 2390 2387 2415 2382 2384 2384 2382 2375 2386 2387 2368 2384 2368 2386 2383 2452 2379 2416 2379 2384 2385 2384 2478 2408 2390 2402 2388 2398 2444 2365 2384 2387 2369 2399 2393 2419 2393 2385 2378 2374 2398 2399 2389 2398 2374 2389 2394 2526 2391 2391 2407 2401 2388 2397 2387 2394 2393 2386 2394 2339 2398 2384 2397 2400 2387 2384 2399 2394 2394 2385 2394 2425 2421 2405 2402 2397 2395 2379 2397 2419 2409 2387 2405 2384 2390 2384 2372 2395 2348 2385 2415 2403 2401 2385 2395 2399 2384 2400 2396 2405 2384 2386 2355 2384 2421 2395 2401 2397 2398 2416 2313 2448 2413 2413 2403 2416 2320 2406 2385 2417 2433 2403 2405 2406 2399 2419 2402 2389 2222 2403 2405 2403 2398 2400 2416 2416 2384 2398 2415 2389 2438 2411 2411 2409 2372 2415 2373 2421 2387 2401 2395 2395 2418 2410 2416 2352 2409 2432 2397 2413 2404 2395 2393 2355 2400 2403 2393 2402 2542 2416 2402 2398 2433 2326 2395 2416 2391 2375 2454 2410 2384 2415 2395 2397 2395 2412 2378 2403 2397 2389 2416 2393 2352 2378 2394 2399 2395 2374 2418 2382 2406 2395 2401 2416 2407 2434 2352 2419 2397 2403 2449 2404 2352 2409 2411 2403 2382 2311 2314 2365 2400 2404 2417 2422 2416 2405 2416 2411 2402 2429 2406 2416 2416 2490 2462 2416 2405 2416 2355 2450 2420 2414 2342 2402 2337 2538 2386 2519 2416 2419 2417 2416 2416 2395 2329 2411 2416 2390 2399 2427 2418 2406 2421 2417 2407 2396 2417 2401 2411 2406 2354 2397 2412 2415 2419 2416 2350 2409 2417 2400 2405 2402 2410 2389 2415 2406 2416 2388 2406 2419 2450 2432 2416 2427 2413 2418 2413 2324 2341 2390 2494 2427 2420 2414 2422 2417 2421 2397 2399 2427 2373 2416 2419 2422 2419 2416 2415 2428 2420 2434 2368 2447 2430 2388 2403 2413 2433 2423 2416 2422 2416 2415 2431 2434 2415 2402 2421 2431 2409 2420 2416 2423 2435 2418 2412 2419 2412 2395 2411 2437 2410 2415 2432 2417 2399 2417 2416 2420 2427 2489 2416 2482 2422 2414 2415 2416 2432 2514 2411 2380 2418 2399 2411 2423 2415 2414 2411 2421 2439 2432 2465 2430 2483 2416 2410 2416 2416 2437 2415 2416 2449 2417 2425 2417 2458 2351 2422 2431 2400 2419 2426 2423 2421 2431 2416 2442 2425 2403 2421 2419 2462 2430 2423 2416 2431 2441 2439 2432 2437 2421 2510 2426 2421 2432 2406 2427 2414 2396 2480 2461 2427 2352 2418 2421 2445 2423 2441 2437 2416 2419 2425 2427 2433 2425 2435 2431 2414 2424 2432 2433 2421 2425 2430 2425 2374 2385 2434 2418 2401 2423 2416 2607 2439 2427 2479 2416 2448 2359 2429 2405 2429 2430 2435 2460 2460 2430 2423 2433 2416 2416 2421 2448 2429 2448 2512 2431 2420 2402 2429 2455 2423 2423 2434 2421 2432 2415 2443 2426 2435 2371 2417 2421 2430 2439 2434 2434 2431 2423 2422 2408 2432 2433 2428 2435 2475 2427 2426 2469 2413 2440 2457 2420 2438 2439 2441 2443 2429 2416 2444 2480 2427 2429 2433 2450 2427 2416 2433 2424 2447 2432 2422 2403 2423 2433 2414 2516 2414 2435 2431 2393 2433 2428 2441 2434 2362 2429 2434 2445 2434 2432 2400 2431 2442 2426 2435 2429 2433 2420 2435 2416 2416 2441 2494 2363 2443 2399 2434 2439 2533 2423 2438 2433 2453 2426 2466 2448 2430 2435 2534 2436 2439 2445 2443 2438 2442 2435 2539 2434 2431 2427 2422 2430 2441 2438 2420 2443 2436 2429 2436 2435 2443 2444 2447 2438 2433 2459 2440 2446 2437 2418 2445 2486 2444 2432 2459 2447 2449 2449 2439 2470 2439 2438 2419 2436 2439 2438 2448 2450 2448 2439 2436 2453 2419 2416 2447 2447 2447 2418 2476 2447 2442 2447 2433 2439 2426 2439 2432 2433 2369 2442 2445 2459 2478 2407 2447 2384 2477 2443 2446 2437 2459 2441 2442 2448 2483 2439 2387 2442 2403 2454 2433 2437 2421 2438 2439 2442 2430 2585 2440 2450 2441 2413 2450 2427 2444 2450 2459 2445 2469 2423 2429 2446 2441 2477 2448 2445 2448 2434 2460 2448 2431 2431 2395 2431 2444 2416 2442 2439 2445 2448 2438 2448 2443 2480 2432 2439 2448 2384 2344 2438 2404 2446 2448 2602 2445 2446 2443 2440 2461 2448 2448 2447 2448 2461 2438 2461 2448 2516 2441 2464 2347 2448 2473 2446 2460 2462 2455 2459 2448 2435 2437 2448 2432 2434 2453 2425 2443 2432 2439 2412 2454 2465 2504 2455 2446 2351 2447 2448 2469 2448 2486 2473 2466 2465 2448 2445 2455 2434 2449 2448 2385 2460 2446 2466 2454 2405 2449 2448 2378 2449 2435 2453 2442 2450 2450 2451 2469 2448 2458 2465 2462 2461 2552 2351 2496 2448 2411 2453 2469 2453 2557 2471 2470 2389 2489 2448 2449 2448 2451 2454 2448 2452 2455 2461 2451 2459 2438 2448 2356 2443 2466 2491 2406 2448 2465 2459 2462 2505 2454 2442 2443 2474 2457 2451 2471 2471 2459 2529 2453 2384 2453 2442 2451 2435 2457 2437 2454 2413 2450 2448 2450 2446 2448 2469 2480 2369 2457 2458 2468 2448 2438 2452 2445 2442 2453 2513 2454 2463 2457 2448 2373 2458 2496 2458 2453 2428 2462 2459 2451 2450 2461 2448 2463 2448 2459 2464 2442 2448 2453 2448 2455 2496 2463 2457 2459 2453 2496 2459 2450 2465 2463 2473 2473 2472 2391 2469 2444 2455 2400 2490 2496 2458 2459 2452 2443 2421 2387 2463 2390 2426 2489 2451 2455 2480 2470 2466 2476 2469 2458 2497 2448 2385 2454 2462 2464 2453 2455 2458 2461 2471 2464 2454 2454 2481 2527 2544 2449 2468 2480 2423 2459 2476 2521 2491 2479 2451 2435 2461 2460 2458 2434 2447 2465 2559 2451 2451 2461 2436 2448 2475 2465 2477 2473 2448 2470 2470 2458 2467 2452 2463 2403 2459 2475 2475 2374 2466 2489 2493 2463 2454 2397 2464 2461 2467 2462 2455 2447 2543 2467 2481 2483 2481 2383 2469 2479 2474 2469 2462 2380 2458 2595 2416 2458 2463 2480 2466 2551 2479 2466 2445 2487 2598 2478 2478 2480 2467 2473 2475 2449 2468 2479 2462 2462 2473 2463 2468 2508 2467 2497 2470 2471 2469 2423 2448 2489 2461 2463 2555 2465 2480 2480 2453 2471 2465 2476 2480 2458 2476 2464 2479 2480 2423 2453 2384 2477 2475 2450 2487 2473 2473 2398 2466 2474 2413 2492 2498 2501 2477 2496 2494 2463 2473 2448 2480 2481 2502 2478 2479 2480 2485 2467 2533 2478 2477 2479 2434 2487 2489 2493 2467 2483 2480 2442 2478 2467 2479 2467 2469 2482 2467 2480 2466 2482 2448 2462 2475 2480 2480 2480 2417 2462 2455 2474 2479 2465 2500 2477 2478 2597 2465 2477 2463 2470 2495 2475 2458 2471 2483 2474 2433 2470 2471 2471 2475 2467 2469 2486 2471 2477 2481 2485 2419 2481 2460 2471 2479 2499 2490 2463 2480 2494 2489 2469 2485 2480 2479 2416 2489 2482 2451 2484 2497 2512 2485 2487 2420 2484 2497 2483 2483 2579 2473 2554 2466 2506 2482 2474 2502 2481 2453 2478 2374 2448 2490 2495 2500 2503 2528 2474 2502 2480 2473 2480 2487 2480 2483 2493 2480 2467 2407 2485 2503 2480 2484 2489 2480 2479 2482 2502 2506 2480 2487 2463 2486 2471 2493 2490 2544 2486 2478 2479 2480 2496 2483 2485 2481 2483 2491 2474 2480 2486 2481 2475 2487 2502 2484 2492 2510 2495 2464 2493 2498 2482 2474 2496 2495 2526 2498 2496 2485 2500 2467 2461 2466 2503 2494 2517 2427 2510 2483 2487 2480 2455 2505 2626 2483 2485 2495 2493 2487 2544 2478 2498 2487 2479 2496 2480 2550 2471 2501 2480 2506 2481 2496 2504 2482 2491 2495 2418 2494 2491 2493 2493 2496 2526 2492 2490 2486 2486 2470 2418 2496 2490 2510 2490 2472 2503 2480 2482 2330 2530 2495 2486 2603 2478 2485 2490 2519 2501 2489 2502 2497 2419 2486 2482 2500 2503 2493 2537 2497 2516 2496 2496 2495 2508 2443 2490 2502 2559 2496 2487 2499 2516 2491 2497 2494 2497 2483 2497 2497 2532 2515 2512 2500 2501 2491 2499 2493 2501 2509 2505 2501 2503 2503 2522 2512 2635 2493 2506 2508 2487 2496 2465 2512 2496 2425 2499 2479 2503 2503 2498 2494 2505 2512 2652 2480 2528 2493 2503 2581 2501 2489 2509 2384 2515 2503 2509 2506 2512 2515 2516 2502 2559 2514 2506 2517 2511 2610 2515 2498 2499 2458 2511 2521 2513 2496 2507 2544 2507 2528 2501 2559 2491 2515 2489 2496 2517 2509 2485 2512 2461 2503 2502 2457 2513 2531 2499 2495 2502 2499 2506 2511 2416 2510 2529 2506 2503 2494 2499 2512 2497 2506 2498 2512 2499 2507 2496 2507 2512 2518 2521 2506 2475 2509 2513 2605 2505 2495 2509 2501 2503 2481 2511 2511 2503 2499 2506 2375 2505 2505 2506 2543 2533 2501 2593 2499 2608 2512 2510 2516 2510 2501 2505 2512 2512 2512 2506 2507 2500 2416 2512 2509 2512 2451 2523 2502 2500 2457 2515 2496 2513 2506 2534 2585 2599 2512 2498 2506 2523 2505 2503 2509 2535 2513 2517 2471 2537 2502 2512 2503 2379 2494 2502 2514 2512 2518 2512 2507 2511 2501 2448 2587 2507 2512 2405 2506 2493 2507 2496 2507 2512 2505 2510 2525 2506 2531 2506 2498 2501 2517 2493 2514 2511 2515 2516 2512 2497 2512 2641 2529 2503 2518 2492 2513 2512 2450 2515 2489 2507 2496 2508 2512 2499 2504 2404 2523 2593 2515 2513 2516 2511 2509 2511 2496 2512 2529 2529 2512 2518 2524 2505 2464 2512 2507 2513 2559 2511 2491 2514 2516 2523 2448 2519 2517 2502 2512 2513 2589 2539 2503 2517 2533 2510 2559 2527 2512 2506 2653 2505 2515 2511 2512 2517 2528 2509 2518 2501 2512 2508 2482 2525 2435 2531 2512 2495 2463 2513 2516 2448 2542 2529 2507 2507 2512 2527 2507 2516 2512 2530 2497 2512 2509 2513 2519 2473 2512 2529 2521 2513 2517 2517 2517 2662 2523 2522 2530 2513 2516 2514 2540 2526 2517 2515 2524 2512 2512 2512 2534 2527 2514 2531 2528 2518 2519 2537 2477 2508 2542 2535 2610 2522 2528 2507 2593 2532 2522 2521 2510 2526 2529 2559 2545 2513 2508 2522 2559 2532 2608 2518 2523 2512 2502 2439 2502 2535 2511 2538 2526 2526 2513 2588 2541 2496 2511 2527 2515 2551 2544 2515 2591 2486 2511 2546 2548 2497 2519 2448 2517 2516 2559 2524 2507 2509 2528 2512 2521 2529 2519 2498 2496 2518 2701 2546 2525 2528 2512 2531 2518 2511 2487 2532 2481 2525 2527 2501 2514 2559 2526 2529 2502 2539 2515 2514 2515 2542 2519 2522 2543 2531 2538 2540 2512 2533 2532 2519 2522 2515 2523 2518 2530 2535 2517 2534 2525 2537 2538 2531 2462 2537 2492 2433 2528 2512 2523 2512 2519 2555 2508 2543 2527 2583 2527 2526 2533 2502 2553 2542 2551 2577 2522 2559 2544 2454 2480 2530 2529 2512 2519 2524 2530 2511 2533 2469 2513 2509 2512 2531 2538 2523 2531 2499 2512 2523 2513 2524 2524 2535 2541 2537 2542 2514 2544 2555 2531 2506 2529 2515 2523 2544 2463 2528 2590 2535 2559 2538 2535 2545 2531 2529 2535 2609 2543 2555 2555 2531 2553 2544 2528 2535 2529 2530 2526 2544 2514 2528 2515 2535 2553 2542 2529 2531 2498 2541 2466 2529 2495 2541 2586 2543 2526 2482 2531 2537 2544 2521 2525 2540 2527 2536 2540 2518 2530 2526 2544 2517 2526 2539 2531 2529 2535 2528 2538 2543 2531 2545 2533 2529 2529 2533 2533 2537 2542 2543 2541 2544 2537 2489 2595 2542 2521 2518 2613 2554 2544 2529 2544 2559 2535 2540 2538 2544 2534 2548 2535 2537 2593 2525 2559 2530 2541 2640 2535 2532 2549 2531 2535 2544 2529 2555 2513 2559 2544 2543 2559 2555 2526 2559 2537 2545 2544 2544 2544 2480 2547 2517 2537 2559 2531 2559 2541 2462 2586 2538 2534 2545 2457 2539 2543 2544 2544 2533 2559 2542 2687 2533 2512 2555 2549 2645 2535 2544 2545 2535 2549 2541 2448 2585 2543 2544 2554 2545 2557 2581 2555 2556 2554 2557 2544 2551 2539 2607 2555 2551 2610 2544 2546 2605 2531 2550 2552 2494 2557 2541 2523 2528 2547 2548 2544 2505 2550 2539 2539 2540 2521 2547 2541 2544 2543 2535 2546 2537 2467 2539 2544 2516 2544 2559 2533 2547 2538 2559 2545 2542 2538 2559 2528 2545 2549 2551 2559 2534 2486 2559 2559 2551 2544 2457 2542 2519 2538 2543 2548 2530 2544 2532 2545 2544 2557 2526 2550 2554 2678 2559 2544 2528 2539 2535 2538 2539 2555 2506 2531 2549 2555 2559 2559 2554 2557 2543 2549 2555 2559 2510 2549 2543 2544 2538 2554 2549 2541 2559 2539 2460 2544 2547 2553 2559 2555 2550 2550 2479 2496 2528 2543 2527 2537 2554 2557 2556 2542 2518 2543 2599 2544 2545 2551 2547 2559 2553 2549 2519 2544 2466 2557 2544 2686 2559 2559 2554 2557 2555 2556 2559 2449 2592 2559 2541 2544 2519 2550 2640 2525 2559 2559 2559 2559 2559 2550 2559 2582 2559 2559 2544 2550 2544 2545 2555 2559 2559 2544 2559 2614 2547 2608 2553 2534 2559 2555 2559 2522 2547 2559 2559 2555 2586 2557 2559 2559 2537 2519 2558 2554 2546 2544 2558 2528 2550 2496 2534 2467 2550 2558 2544 2558 2559 2546 2557 2545 2490 2546 2545 2549 2559 2552 2559 2547 2547 2559 2557 2546 2544 2550 2474 2544 2549 2587 2544 2551 2597 2559 2512 2555 2559 2556 2545 2559 2558 2559 2547 2626 2469 2559 2431 2559 2558 2546 2543 2448 2548 2601 2550 2545 2549 2543 2559 2501 2559 2559 2554 2559 2613 2559 2559 2559 2559 2543 2559 2549 2559 2559 2559 2554 2559 2546 2559 2559 2581 2611 2544 2557 2579 2559 2559 2555 2559 2540 2555 2559 2559 2559 2559 2559 2559 2559 2614 2511 2624 2559 2544 2559 2559 2591 2580 2555 2544 2544 2599 2559 2507 2543 2545 2559 2559 2559 2580 2559 2559 2559 2581 2559 2559 2559 2548 2559 2559 2559 2559 2559 2608 2606 2559 2554 2559 2559 2555 2549 2551 2529 2547 2455 2558 2523 2602 2549 2558 2550 2558 2559 2559 2556 2559 2559 2559 2557 2559 2559 2559 2491 2559 2559 2559 2559 2589 2512 2559 2559 2559 2559 2559 2559 2559 2559 2554 2524 2559 2555 2502 2545 2547 2559 2581 2558 2559 2581 2555 2673 2540 2559 2558 2559 2596 2587 2553 2559 2556 2603 2519 2552 2559 2559 2559 2559 2590 2554 2557 2559 2559 2547 2559 2586 2554 2482 2559 2559 2611 2583 2559 2587 2559 2559 2559 2541 2559 2583 2558 2559 2559 2559 2559 2559 2494 2559 2559 2551 2512 2559 2559 2594 2559 2587 2503 2581 2559 2559 2559 2559 2559 2559 2548 2545 2559 2602 2559 2559 2559 2591 2559 2487 2559 2559 2539 2559 2559 2559 2589 2604 2559 2583 2587 2583 2556 2736 2586 2591 2587 2539 2585 2559 2559 2559 2604 2513 2559 2583 2559 2583 2558 2599 2582 2559 2555 2605 2559 2590 2527 2559 2499 2559 2559 2559 2559 2613 2559 2559 2591 2559 2590 2559 2559 2590 2581 2558 2579 2724 2593 2583 2622 2559 2559 2582 2559 2583 2559 2559 2608 2609 2559 2557 2608 2582 2593 2581 2589 2704 2591 2559 2559 2533 2587 2593 2559 2503 2618 2593 2592 2559 2556 2559 2585 2559 2589 2549 2582 2614 2622 2559 2559 2551 2559 2559 2693 2607 2581 2583 2617 2559 2559 2559 2559 2598 2559 2587 2583 2559 2704 2581 2585 2591 2581 2592 2559 2589 2588 2582 2512 2622 2524 2559 2586 2559 2555 2592 2554 2583 2559 2605 2559 2559 2610 2583 2579 2559 2592 2559 2597 2559 2559 2559 2603 2586 2559 2590 2589 2591 2559 2534 2585 2581 2606 2559 2535 2602 2582 2628 2587 2587 2597 2559 2559 2587 2591 2608 2583 2592 2588 2590 2602 2625 2597 2559 2587 2559 2619 2614 2604 2630 2598 2594 2590 2553 2595 2603 2583 2546 2608 2590 2559 2559 2624 2581 2581 2559 2559 2608 2587 2592 2585 2582 2593 2590 2559 2588 2619 2583 2593 2544 2559 2604 2595 2557 2647 2559 2582 2589 2583 2588 2579 2593 2590 2588 2582 2582 2559 2586 2590 2595 2592 2501 2559 2619 2591 2585 2583 2559 2559 2608 2559 2559 2598 2539 2601 2559 2621 2559 2559 2689 2585 2559 2609 2605 2553 2589 2608 2559 2581 2593 2581 2642 2594 2589 2597 2592 2623 2608 2592 2622 2599 2599 2601 2585 2559 2587 2524 2585 2582 2559 2582 2559 2585 2594 2624 2609 2587 2589 2559 2582 2608 2599 2608 2585 2584 2590 2598 2503 2648 2559 2610 2597 2602 2559 2592 2505 2597 2559 2599 2591 2559 2588 2559 2593 2601 2598 2591 2559 2608 2559 2535 2595 2611 2589 2591 2592 2594 2755 2602 2591 2601 2604 2608 2559 2599 2590 2624 2598 2608 2615 2607 2599 2612 2599 2600 2599 2587 2492 2602 2607 2602 2592 2608 2608 2594 2592 2559 2602 2589 2521 2594 2624 2521 2624 2687 2595 2592 2590 2588 2507 2608 2527 2603 2601 2496 2602 2624 2559 2599 2598 2587 2587 2595 2598 2586 2611 2595 2595 2599 2606 2589 2745 2615 2587 2599 2715 2603 2710 2599 2559 2653 2594 2595 2545 2653 2607 2599 2597 2583 2590 2599 2595 2619 2554 2587 2559 2513 2589 2590 2559 2607 2607 2598 2606 2559 2587 2559 2624 2608 2602 2595 2691 2592 2613 2598 2609 2608 2595 2559 2512 2605 2603 2590 2591 2597 2602 2601 2519 2586 2593 2587 2588 2586 2603 2595 2602 2559 2609 2603 2559 2596 2599 2594 2602 2704 2624 2591 2617 2600 2477 2598 2622 2600 2604 2559 2602 2596 2586 2583 2593 2590 2608 2608 2608 2593 2582 2608 2596 2593 2609 2597 2587 2599 2559 2613 2580 2604 2596 2589 2531 2608 2595 2607 2603 2597 2606 2602 2610 2541 2614 2552 2672 2603 2674 2598 2599 2599 2559 2608 2608 2607 2608 2607 2624 2610 2608 2597 2603 2606 2596 2606 2615 2604 2589 2606 2609 2605 2607 2608 2609 2607 2583 2550 2607 2603 2716 2608 2559 2595 2600 2624 2607 2595 2609 2608 2599 2619 2695 2559 2603 2622 2595 2589 2603 2606 2742 2608 2606 2620 2603 2608 2618 2601 2608 2610 2601 2606 2604 2601 2601 2613 2602 2619 2609 2609 2448 2607 2608 2597 2607 2601 2606 2611 2595 2606 2624 2624 2611 2607 2597 2592 2595 2591 2612 2621 2621 2619 2607 2595 2539 2614 2609 2626 2589 2611 2615 2603 2559 2615 2622 2615 2599 2611 2547 2615 2587 2613 2608 2619 2621 2554 2611 2599 2623 2599 2616 2614 2607 2613 2617 2559 2626 2597 2608 2608 2625 2597 2613 2608 2617 2613 2595 2608 2608 2624 2640 2619 2524 2537 2619 2619 2615 2608 2614 2609 2610 2603 2610 2512 2609 2598 2626 2559 2613 2609 2701 2605 2615 2608 2619 2637 2598 2583 2625 2603 2590 2608 2587 2605 2612 2622 2643 2612 2610 2609 2619 2611 2599 2619 2621 2594 2614 2639 2615 2608 2603 2630 2615 2632 2585 2630 2619 2615 2608 2598 2608 2601 2615 2625 2615 2625 2612 2736 2644 2586 2619 2510 2595 2617 2614 2611 2614 2619 2608 2697 2609 2627 2637 2606 2608 2605 2612 2610 2599 2627 2605 2619 2594 2609 2621 2622 2657 2627 2614 2627 2623 2608 2606 2594 2559 2624 2607 2667 2724 2608 2615 2613 2537 2605 2611 2627 2669 2605 2609 2585 2606 2604 2625 2613 2607 2619 2624 2598 2631 2610 2665 2618 2608 2637 2613 2609 2630 2704 2642 2606 2611 2620 2734 2590 2624 2603 2611 2618 2611 2607 2620 2615 2617 2549 2614 2595 2591 2736 2634 2627 2608 2608 2612 2686 2607 2610 2606 2624 2585 2647 2612 2608 2610 2640 2594 2607 2559 2611 2621 2623 2596 2627 2613 2613 2607 2611 2559 2538 2665 2608 2614 2618 2624 2608 2586 2624 2614 2608 2615 2612 2624 2625 2610 2611 2608 2619 2734 2611 2644 2608 2630 2640 2608 2625 2611 2589 2615 2602 2624 2618 2615 2559 2619 2623 2621 2614 2615 2618 2635 2624 2625 2642 2622 2635 2557 2630 2599 2624 2595 2615 2608 2624 2619 2608 2614 2623 2642 2608 2617 2618 2618 2635 2615 2627 2615 2625 2607 2624 2555 2624 2608 2613 2622 2640 2627 2615 2626 2623 2634 2623 2623 2549 2611 2617 2640 2605 2621 2622 2613 2629 2645 2620 2621 2624 2623 2710 2591 2621 2612 2641 2631 2625 2619 2626 2620 2619 2783 2640 2582 2592 2559 2625 2614 2637 2608 2624 2608 2640 2559 2622 2622 2625 2631 2631 2631 2640 2636 2637 2558 2639 2617 2743 2631 2647 2616 2645 2625 2633 2647 2605 2552 2609 2624 2613 2559 2640 2623 2624 2612 2619 2545 2610 2625 2627 2628 2644 2619 2626 2624 2624 2607 2626 2614 2690 2631 2630 2624 2623 2634 2635 2622 2615 2625 2623 2607 2607 2610 2630 2635 2559 2817 2639 2705 2758 2619 2603 2607 2609 2625 2608 2641 2641 2624 2581 2615 2593 2630 2629 2614 2615 2608 2628 2618 2721 2619 2608 2614 2657 2544 2609 2641 2637 2633 2582 2305 2654 2617 2608 2524 2624 2622 2640 2631 2624 2635 2651 2608 2639 2608 2628 2624 2629 2629 2624 2632 2639 2641 2613 2608 2631 2643 2624 2630 2638 2622 2626 2628 2612 2608 2624 2726 2624 2617 2641 2629 2557 2626 2636 2651 2559 2626 2601 2629 2614 2599 2631 2643 2601 2635 2633 2630 2628 2706 2629 2634 2764 2631 2627 2617 2639 2637 2593 2638 2630 2631 2634 2609 2634 2649 2608 2635 2625 2627 2559 2638 2637 2677 2631 2559 2627 2636 2546 2624 2603 2628 2607 2681 2559 2640 2619 2629 2633 2531 2646 2623 2631 2640 2634 2626 2637 2671 2620 2679 2617 2639 2559 2624 2623 2637 2624 2651 2613 2633 2639 2589 2663 2619 2615 2500 2631 2414 2608 2609 2615 2624 2624 2641 2622 2591 2635 2647 2625 2623 2627 2663 2614 2655 2603 2593 2635 2633 2648 2639 2624 2800 2636 2637 2749 2621 2636 2770 2625 2622 2633 2671 2640 2636 2631 2618 2615 2635 2631 2663 2630 2587 2630 2638 2641 2640 2630 2506 2633 2559 2628 2647 2639 2597 2608 2630 2598 2638 2609 2633 2542 2631 2637 2636 2647 2640 2624 2670 2627 2633 2874 2629 2642 2638 2637 2645 2639 2647 2625 2637 2639 2652 2640 2640 2558 2672 2641 2583 2635 2636 2635 2612 2634 2639 2613 2631 2617 2639 2624 2644 2639 2763 2634 2662 2559 2624 2507 2645 2647 2638 2588 2630 2629 2645 2593 2615 2634 2633 2628 2545 2627 2663 2634 2627 2641 2621 2642 2628 2635 2640 2627 2640 2626 2614 2608 2640 2646 2623 2635 2640 2621 2623 2615 2642 2645 2643 2665 2642 2634 2640 2641 2640 2640 2634 2635 2640 2632 2618 2559 2633 2631 2627 2638 2639 2642 2667 2551 2687 2629 2613 2640 2655 2626 2632 2640 2554 2625 2512 2640 2634 2632 2630 2636 2663 2623 2633 2644 2559 2625 2630 2651 2641 2642 2639 2640 2631 2633 2634 2636 2624 2639 2622 2641 2640 2643 2634 2643 2628 2613 2636 2644 2544 2647 2640 2642 2653 2541 2631 2652 2641 2633 2630 2559 2646 2663 2641 2756 2608 2640 2642 2638 2639 2630 2637 2638 2655 2655 2644 2623 2635 2656 2623 2655 2651 2647 2627 2630 2640 2638 2642 2627 2653 2636 2641 2641 2626 2626 2717 2544 2641 2642 2639 2754 2649 2656 2639 2621 2640 2605 2559 2633 2636 2644 2640 2624 2645 2635 2624 2647 2640 2631 2634 2550 2625 2701 2625 2639 2644 2667 2667 2632 2628 2624 2639 2618 2634 2646 2647 2633 2640 2635 2642 2657 2633 2590 2643 2626 2641 2638 2654 2643 2640 2646 2611 2629 2642 2634 2559 2694 2639 2650 2640 2620 2637 2646 2645 2641 2641 2642 2644 2639 2669 2620 2636 2660 2663 2755 2592 2640 2640 2635 2624 2637 2640 2640 2633 2619 2647 2643 2627 2618 2629 2642 2636 2636 2641 2643 2640 2657 2611 2626 2641 2624 2643 2654 2639 2640 2656 2635 2640 2637 2647 2645 2671 2644 2637 2622 2638 2639 2641 2641 2716 2631 2639 2649 2637 2640 2626 2651 2668 2646 2646 2645 2640 2653 2640 2640 2634 2646 2641 2646 2640 2649 2653 2663 2645 2653 2631 2646 2656 2661 2753 2701 2655 2645 2647 2672 2655 2656 2693 2655 2659 2649 2646 2653 2640 2652 2653 2640 2640 2659 2670 2647 2650 2654 2621 2639 2646 2630 2657 2638 2642 2647 2672 2665 2684 2640 2661 2647 2643 2667 2656 2650 2798 2641 2667 2656 2639 2637 2651 2644 2642 2626 2637 2646 2652 2627 2651 2637 2642 2642 2661 2641 2657 2640 2591 2634 2640 2651 2713 2800 2640 2645 2646 2645 2559 2644 2646 2653 2645 2640 2652 2554 2654 2647 2640 2640 2643 2657 2659 2657 2643 2653 2663 2629 2602 2602 2661 2683 2661 2640 2651 2654 2537 2647 2641 2669 2642 2755 2668 2651 2637 2628 2624 2640 2646 2652 2647 2681 2636 2645 2627 2648 2636 2628 2650 2645 2648 2640 2651 2654 2645 2654 2653 2656 2653 2559 2646 2634 2642 2651 2611 2663 2657 2639 2640 2659 2665 2640 2640 2645 2559 2627 2695 2640 2645 2658 2640 2649 2655 2653 2646 2662 2647 2640 2647 2641 2644 2672 2659 2669 2659 2647 2710 2637 2656 2667 2662 2652 2672 2653 2635 2651 2702 2663 2642 2647 2678 2665 2663 2645 2643 2640 2649 2655 2656 2653 2658 2682 2662 2627 2653 2643 2636 2731 2640 2662 2674 2635 2662 2641 2626 2640 2655 2622 2647 2645 2640 2672 2655 2586 2649 2655 2626 2657 2645 2674 2671 2647 2657 2667 2629 2640 2647 2651 2743 2677 2640 2657 2650 2661 2666 2650 2656 2550 2643 2663 2643 2644 2641 2688 2592 2646 2559 2635 2659 2651 2649 2659 2661 2643 2647 2647 2647 2651 2655 2631 2661 2658 2640 2642 2585 2669 2650 2647 2650 2640 2599 2652 2663 2655 2649 2611 2666 2662 2671 2668 2649 2656 2646 2632 2657 2661 2672 2634 2629 2653 2639 2644 2723 2659 2671 2694 2653 2653 2651 2653 2647 2658 2648 2643 2667 2650 2657 2634 2743 2655 2663 2641 2666 2652 2559 2637 2688 2643 2643 2646 2657 2651 2636 2640 2664 2640 2669 2646 2657 2677 2667 2668 2642 2655 2646 2673 2683 2656 2670 2652 2660 2669 2654 2656 2653 2659 2672 2649 2653 2646 2650 2653 2672 2653 2658 2591 2624 2663 2654 2661 2648 2651 2672 2667 2652 2657 2655 2662 2666 2606 2686 2615 2642 2656 2655 2647 2627 2658 2643 2671 2694 2639 2655 2645 2642 2635 2636 2555 2656 2645 2651 2659 2598 2556 2606 2635 2634 2674 2642 2655 2649 2643 2649 2645 2659 2647 2669 2559 2635 2660 2658 2673 2674 2655 2653 2653 2658 2665 2639 2642 2621 2657 2643 2637 2670 2786 2653 2645 2655 2665 2654 2607 2637 2666 2608 2656 2636 2667 2652 2657 2669 2683 2637 2621 2652 2674 2675 2649 2645 2657 2638 2582 2652 2632 2679 2672 2641 2651 2682 2672 2666 2629 2654 2657 2677 2672 2672 2750 2654 2663 2738 2640 2480 2768 2641 2707 2665 2676 2682 2672 2649 2659 2663 2653 2670 2628 2667 2659 2654 2665 2658 2659 2660 2634 2654 2661 2623 2661 2653 2656 2674 2653 2633 2655 2657 2559 2655 2646 2639 2663 2663 2672 2677 2653 2654 2689 2672 2643 2665 2654 2668 2671 2656 2646 2656 2651 2559 2672 2657 2656 2662 2635 2667 2650 2651 2636 2687 2655 2647 2605 2704 2654 2649 2681 2663 2786 2659 2656 2657 2626 2656 2656 2634 2663 2730 2682 2647 2646 2635 2656 2644 2666 2652 2644 2653 2651 2643 2640 2643 2650 2665 2609 2653 2655 2662 2665 2679 2655 2656 2655 2661 2695 2668 2658 2678 2656 2622 2649 2646 2662 2655 2653 2641 2644 2663 2667 2664 2642 2646 2619 2658 2672 2661 2656 2658 2653 2743 2672 2649 2666 2676 2645 2642 2671 2672 2658 2648 2587 2663 2646 2647 2652 2655 2642 2672 2654 2653 2684 2608 2663 2661 2672 2626 2781 2659 2658 2663 2606 2646 2650 2658 2642 2665 2661 2662 2663 2675 2663 2663 2663 2716 2625 2639 2643 2663 2635 2637 2663 2657 2688 2663 2693 2702 2640 2662 2655 2635 2719 2658 2653 2658 2559 2671 2640 2663 2666 2646 2640 2674 2663 2651 2621 2691 2661 2673 2651 2659 2640 2666 2662 2658 2640 2647 2620 2662 2650 2608 2675 2690 2672 2650 2634 2656 2659 2615 2635 2653 2661 2622 2662 2674 2669 2656 2650 2667 2676 2671 2654 2654 2657 2661 2696 2667 2673 2654 2635 2672 2654 2662 2652 2653 2636 2672 2759 2623 2649 2667 2630 2693 2701 2672 2655 2651 2641 2611 2661 2640 2639 2653 2667 2631 2646 2663 2643 2667 2655 2720 2717 2671 2653 2658 2622 2559 2657 2704 2651 2663 2649 2666 2693 2645 2658 2634 2657 2665 2625 2658 2642 2657 2654 2657 2659 2734 2602 2647 2659 2641 2615 2655 2671 2663 2651 2650 2599 2654 2667 2695 2663 2708 2640 2688 2667 2672 2671 2669 2682 2659 2630 2665 2701 2660 2681 2673 2657 2666 2671 2558 2658 2660 2646 2658 2641 2611 2757 2629 2651 2655 2610 2661 2653 2674 2656 2621 2677 2667 2608 2663 2666 2639 2655 2662 2790 2658 2658 2640 2677 2654 2700 2669 2647 2640 2655 2685 2631 2595 2659 2656 2663 2671 2655 2633 2670 2594 2615 2662 2676 2655 2669 2656 2658 2653 2665 2659 2671 2658 2653 2667 2653 2669 2657 2661 2647 2656 2629 2650 2765 2659 2769 2653 2640 2645 2671 2645 2699 2656 2646 2662 2658 2659 2657 2652 2646 2658 2650 2661 2707 2559 2665 2788 2666 2590 2653 2668 2640 2605 2661 2640 2669 2648 2624 2635 2646 2661 2658 2683 2661 2647 2663 2662 2631 2672 2661 2660 2670 2651 2670 2653 2658 2665 2654 2671 2672 2688 2655 2637 2647 2661 2661 2659 2659 2679 2688 2686 2659 2666 2655 2623 2681 2672 2663 2659 2659 2665 2675 2637 2665 2688 2652 2704 2626 2607 2656 2667 2671 2665 2647 2650 2670 2644 2671 2629 2651 2640 2639 2649 2661 2656 2640 2580 2663 2671 2688 2655 2650 2647 2653 2662 2662 2716 2659 2611 2669 2652 2657 2660 2672 2667 2639 2645 2640 2676 2654 2643 2662 2684 2672 2669 2666 2714 2659 2654 2659 2666 2663 2672 2658 2641 2661 2740 2659 2658 2673 2655 2659 2667 2656 2737 2655 2665 2660 2655 2620 2657 2667 2655 2662 2586 2654 2662 2670 2665 2661 2663 2656 2655 2663 2668 2651 2677 2660 2654 2638 2661 2674 2643 2642 2654 2667 2652 2679 2674 2649 2647 2662 2683 2643 2734 2673 2651 2559 2666 2662 2654 2650 2661 2653 2657 2649 2662 2656 2659 2669 2658 2703 2662 2735 2675 2640 2678 2666 2655 2655 2671 2780 2665 2661 2657 2654 2623 2602 2652 2672 2662 2648 2722 2663 2655 2644 2666 2607 2624 2667 2655 2678 2448 2659 2670 2559 2655 2635 2668 2668 2672 2685 2589 2661 2663 2666 2678 2677 2646 2649 2657 2651 2647 2663 2645 2646 2653 2662 2579 2670 2653 2645 2646 2650 2649 2544 2647 2690 2655 2654 2590 2591 2657 2667 2661 2639 2679 2659 2646 2418 2671 2640 2669 2651 2663 2629 2654 2665 2640 2675 2661 2669 2666 2659 2673 2657 2659 2671 2658 2666 2671 2653 2658 2654 2693 2655 2655 2722 2656 2667 2659 2672 2661 2667 2655 2663 2819 2655 2669 2655 2658 2663 2643 2675 2661 2653 2661 2702 2657 2658 2634 2640 2727 2661 2663 2666 2667 2663 2663 2657 2676 2658 2625 2657 2644 2635 2659 2646 2669 2669 2706 2647 2659 2653 2688 2651 2659 2658 2642 2663 2658 2658 2668 2666 2669 2653 2666 2652 2672 2662 2670 2640 2651 2673 2657 2657 2589 2658 2655 2661 2663 2654 2656 2659 2643 2641 2667 2654 2649 2651 2669 2640 2640 2559 2670 2667 2666 2861 2691 2672 2669 2666 2652 2654 2640 2669 2640 2671 2682 2661 2588 2690 2643 2662 2667 2602 2660 2642 2666 2663 2657 2629 2663 2748 2658 2640 2669 2647 2655 2646 2649 2672 2672 2670 2690 2659 2647 2663 2652 2657 2741 2642 2655 2663 2662 2642 2663 2656 2658 2662 2645 2647 2661 2656 2646 2665 2608 2624 2775 2659 2669 2670 2655 2654 2656 2640 2653 2674 2660 2656 2660 2675 2672 2593 2658 2678 2662 2666 2652 2663 2668 2644 2646 2651 2657 2655 2679 2663 2665 2657 2671 2676 2651 2654 2657 2655 2559 2650 2647 2544 2651 2687 2637 2658 2523 2678 2671 2666 2659 2656 2652 2667 2649 2658 2657 2649 2652 2661 2674 2663 2658 2733 2673 2683 2699 2647 2692 2659 2667 2612 2655 2666 2657 2666 2670 2655 2669 2672 2669 2675 2664 2687 2657 2695 2704 2693 2662 2639 2657 2627 2672 2666 2672 2663 2681 2649 2672 2681 2663 2643 2671 2670 2597 2659 2667 2649 2659 2681 2637 2667 2672 2662 2654 2764 2638 2649 2661 2650 2649 2675 2661 2679 2656 2677 2663 2596 2647 2659 2623 2663 2687 2667 2665 2662 2640 2639 2662 2646 2655 2639 2669 2661 2670 2655 2672 2659 2675 2639 2665 2659 2661 2605 2590 2624 2662 2663 2614 2657 2678 2662 2670 2654 2656 2672 2672 2663 2667 2651 2662 2676 2649 2678 2649 2670 2672 2662 2640 2659 2656 2665 2656 2734 2672 2670 2703 2660 2559 2657 2658 2647 2662 2657 2669 2618 2651 2655 2661 2657 2670 2672 2665 2662 2641 2593 2674 2658 2667 2672 2663 2666 2620 2662 2669 2659 2657 2695 2655 2591 2641 2658 2661 2640 2670 2790 2657 2655 2768 2653 2667 2671 2662 2640 2654 2743 2658 2659 2657 2779 2651 2650 2670 2647 2660 2663 2675 2690 2654 2652 2655 2646 2647 2665 2525 2669 2650 2654 2659 2666 2650 2672 2602 2666 2659 2659 2674 2658 2666 2679 2667 2665 2624 2658 2688 2661 2656 2674 2651 2704 2658 2666 2646 2661 2652 2653 2662 2655 2643 2677 2646 2611 2704 2663 2653 2665 2647 2658 2641 2671 2659 2637 2653 2624 2641 2666 2666 2678 2653 2661 2657 2644 2661 2662 2662 2656 2657 2653 2593 2644 2651 2654 2659 2665 2640 2656 2672 2657 2601 2653 2640 2661 2659 2629 2642 2671 2662 2591 2663 2641 2677 2687 2639 2648 2704 2559 2671 2559 2647 2623 2649 2657 2640 2667 2663 2657 2649 2585 2559 2659 2666 2627 2674 2658 2647 2667 2650 2661 2918 2672 2661 2599 2663 2657 2657 2646 2660 2665 2644 2657 2661 2653 2645 2658 2601 2641 2666 2659 2653 2670 2661 2671 2647 2661 2559 2647 2701 2669 2647 2663 2645 2655 2662 2670 2674 2674 2669 2667 2620 2693 2751 2662 2660 2656 2659 2559 2662 2668 2654 2678 2661 2656 2629 2662 2683 2666 2661 2669 2631 2642 2645 2667 2702 2656 2631 2647 2673 2647 2667 2608 2663 2653 2658 2635 2645 2640 2661 2658 2644 2665 2647 2666 2672 2639 2655 2658 2670 2669 2531 2655 2667 2651 2559 2650 2646 2646 2651 2718 2669 2639 2664 2664 2655 2784 2655 2681 2672 2658 2662 2635 2643 2669 2662 2656 2651 2646 2640 2660 2657 2659 2662 2659 2640 2663 2662 2656 2559 2622 2638 2642 2652 2614 2661 2666 2657 2656 2704 2662 2653 2640 2645 2635 2655 2608 2657 2666 2634 2659 2661 2655 2638 2653 2653 2646 2673 2658 2656 2677 2624 2671 2653 2653 2593 2667 2703 2653 2768 2640 2641 2631 2659 2651 2640 2658 2659 2659 2654 2703 2559 2672 2672 2647 2637 2646 2653 2635 2640 2663 2662 2642 2646 2659 2647 2638 2653 2635 2625 2637 2645 2652 2675 2656 2656 2627 2699 2651 2666 2651 2656 2649 2640 2626 2635 2636 2678 2651 2663 2655 2674 2643 2679 2620 2614 2526 2650 2611 2649 2641 2643 2651 2636 2632 2653 2642 2665 2665 2642 2671 2665 2654 2651 2671 2645 2672 2656 2643 2656 2645 2651 2663 2650 2652 2662 2651 2640 2651 2678 2652 2637 2589 2640 2640 2647 2657 2599 2652 2656 2647 2645 2662 2643 2650 2626 2640 2656 2608 2661 2658 2707 2606 2646 2589 2640 2603 2655 2646 2662 2636 2645 2640 2651 2659 2637 2658 2645 2658 2665 2667 2736 2670 2638 2559 2595 2666 2671 2654 2654 2689 2646 2650 2672 2654 2687 2645 2656 2667 2650 2691 2659 2590 2646 2609 2587 2640 2658 2659 2642 2656 2647 2657 2654 2651 2647 2637 2626 2675 2649 2647 2640 2667 2659 2650 2653 2667 2654 2636 2640 2639 2624 2646 2647 2649 2640 2596 2644 2650 2645 2663 2641 2642 2658 2661 2547 2657 2640 2650 2625 2651 2663 2660 2656 2652 2645 2639 2667 2652 2655 2650 2674 2646 2658 2656 2646 2651 2766 2661 2650 2638 2650 2645 2658 2615 2547 2643 2643 2658 2640 2672 2640 2643 2648 2655 2663 2663 2666 2631 2655 2642 2656 2645 2646 2656 2788 2644 2640 2650 2642 2690 2657 2641 2641 2640 2646 2631 2641 2640 2640 2650 2657 2633 2614 2602 2643 2645 2651 2637 2601 2643 2658 2635 2657 2646 2660 2593 2645 2645 2649 2647 2657 2653 2776 2652 2649 2640 2654 2640 2646 2672 2640 2651 2643 2647 2639 2618 2645 2640 2641 2702 2653 2646 2647 2647 2643 2653 2640 2649 2644 2627 2608 2630 2646 2602 2653 2654 2542 2640 2663 2660 2642 2624 2640 2646 2646 2665 2641 2624 2640 2637 2644 2641 2638 2647 2643 2632 2647 2641 2651 2624 2651 2660 2646 2671 2644 2667 2651 2647 2650 2652 2601 2633 2656 2658 2637 2637 2627 2735 2653 2595 2656 2647 2629 2640 2672 2655 2582 2640 2646 2645 2559 2643 2659 2653 2646 2743 2636 2654 2655 2654 2658 2645 2650 2655 2652 2636 2657 2639 2647 2613 2559 2665 2651 2652 2653 2642 2662 2647 2743 2662 2649 2654 2644 2674 2649 2646 2649 2714 2666 2643 2645 2647 2654 2640 2633 2639 2640 2590 2559 2645 2688 2635 2677 2638 2655 2637 2640 2608 2649 2655 2641 2641 2640 2642 2640 2640 2662 2559 2654 2655 2646 2638 2648 2611 2646 2669 2640 2649 2638 2634 2637 2668 2715 2651 2640 2659 2634 2627 2651 2630 2625 2651 2663 2640 2642 2643 2643 2637 2639 2605 2606 2653 2643 2645 2629 2647 2672 2647 2640 2638 2559 2641 2666 2670 2640 2644 2639 2643 2639 2624 2648 2651 2635 2559 2637 2614 2651 2624 2713 2607 2668 2655 2611 2644 2631 2634 2697 2640 2640 2641 2651 2658 2718 2663 2652 2640 2641 2651 2649 2644 2643 2658 2637 2699 2644 2645 2645 2643 2654 2653 2544 2645 2665 2634 2640 2640 2640 2631 2605 2623 2650 2638 2631 2749 2618 2637 2642 2654 2559 2647 2619 2559 2633 2631 2634 2644 2645 2641 2640 2628 2663 2640 2661 2639 2645 2593 2641 2640 2642 2606 2640 2640 2644 2644 2645 2594 2660 2647 2669 2639 2640 2640 2644 2649 2640 2634 2639 2639 2641 2647 2640 2642 2653 2656 2631 2641 2649 2639 2672 2637 2640 2639 2649 2645 2629 2629 2661 2656 2639 2634 2649 2640 2635 2594 2651 2633 2631 2626 2640 2644 2640 2639 2631 2634 2631 2640 2618 2642 2640 2662 2640 2646 2642 2636 2608 2637 2629 2637 2640 2646 2643 2639 2624 2603 2643 2641 2645 2643 2633 2655 2635 2613 2533 2627 2643 2559 2736 2642 2647 2606 2640 2623 2637 2671 2626 2642 2647 2639 2629 2640 2657 2640 2649 2659 2635 2641 2619 2647 2641 2651 2651 2655 2640 2640 2645 2640 2672 2635 2641 2639 2641 2640 2634 2677 2643 2590 2645 2624 2640 2640 2612 2668 2652 2663 2626 2609 2639 2634 2638 2635 2651 2636 2634 2638 2650 2634 2643 2640 2638 2635 2585 2624 2635 2652 2485 2635 2768 2631 2603 2639 2640 2638 2641 2630 2640 2654 2582 2625 2638 2625 2651 2732 2635 2634 2644 2635 2647 2639 2640 2631 2643 2678 2636 2662 2631 2629 2641 2604 2643 2640 2631 2638 2614 2635 2640 2845 2670 2638 2646 2635 2640 2596 2640 2624 2638 2628 2662 2640 2623 2623 2634 2640 2624 2640 2650 2636 2539 2633 2629 2726 2640 2659 2626 2645 2682 2599 2628 2636 2626 2640 2635 2650 2634 2625 2621 2640 2637 2640 2638 2637 2631 2617 2590 2641 2665 2634 2627 2634 2637 2640 2624 2629 2643 2630 2626 2656 2554 2615 2641 2639 2606 2657 2617 2637 2626 2647 2649 2624 2626 2634 2624 2644 2627 2640 2640 2721 2617 2639 2590 2658 2628 2628 2644 2608 2625 2670 2638 2623 2634 2694 2629 2623 2640 2608 2641 2651 2637 2633 2681 2640 2624 2608 2631 2635 2637 2608 2624 2614 2626 2630 2628 2654 2637 2637 2630 2646 2631 2639 2618 2629 2613 2610 2640 2619 2624 2623 2622 2662 2626 2634 2636 2663 2640 2614 2623 2627 2634 2637 2637 2639 2623 2559 2644 2639 2640 2646 2627 2641 2622 2675 2631 2631 2640 2581 2634 2627 2629 2608 2704 2643 2672 2624 2627 2608 2559 2613 2631 2586 2639 2634 2624 2627 2640 2630 2639 2640 2624 2640 2623 2633 2607 2739 2639 2627 2621 2756 2636 2559 2633 2607 2627 2555 2628 2639 2643 2626 2633 2637 2640 2627 2609 2626 2617 2634 2608 2637 2638 2643 2629 2634 2625 2639 2615 2643 2631 2627 2788 2643 2628 2641 2631 2647 2599 2634 2635 2624 2627 2537 2640 2627 2592 2625 2551 2633 2640 2640 2620 2627 2689 2636 2639 2559 2634 2617 2621 2640 2633 2614 2639 2630 2480 2591 2619 2628 2544 2637 2619 2636 2608 2612 2559 2586 2620 2667 2625 2627 2615 2624 2640 2639 2559 2621 2641 2620 2611 2592 2620 2603 2624 2614 2637 2631 2624 2617 2625 2614 2559 2618 2609 2615 2615 2619 2622 2618 2638 2639 2612 2581 2637 2633 2621 2624 2640 2622 2635 2730 2629 2621 2626 2591 2619 2610 2621 2618 2607 2643 2624 2621 2628 2643 2623 2630 2624 2672 2559 2608 2625 2639 2622 2608 2624 2627 2609 2762 2624 2625 2608 2559 2630 2619 2631 2625 2631 2615 2624 2625 2736 2624 2609 2611 2618 2594 2623 2615 2612 2645 2603 2619 2624 2617 2619 2619 2625 2624 2608 2579 2631 2644 2628 2631 2621 2719 2620 2618 2617 2608 2652 2544 2615 2634 2630 2622 2635 2637 2630 2631 2622 2623 2643 2636 2621 2640 2631 2640 2607 2625 2638 2671 2622 2615 2605 2608 2435 2615 2510 2624 2625 2629 2727 2615 2625 2619 2629 2614 2604 2623 2613 2747 2630 2613 2623 2418 2618 2620 2612 2608 2585 2618 2611 2608 2631 2640 2619 2590 2613 2630 2608 2622 2602 2559 2559 2640 2608 2559 2642 2620 2613 2619 2615 2606 2623 2617 2671 2593 2631 2639 2640 2582 2617 2620 2599 2637 2633 2621 2619 2626 2625 2647 2608 2618 2618 2579 2623 2606 2618 2629 2623 2617 2609 2631 2632 2639 2624 2619 2623 2607 2645 2627 2603 2613 2643 2607 2610 2619 2624 2769 2613 2559 2613 2609 2634 2618 2617 2559 2603 2611 2624 2608 2630 2548 2615 2608 2603 2605 2608 2597 2608 2608 2610 2615 2620 2617 2619 2614 2618 2538 2732 2608 2619 2601 2547 2603 2619 2602 2623 2619 2624 2628 2613 2620 2673 2617 2645 2625 2625 2624 2623 2623 2614 2608 2625 2610 2625 2589 2628 2624 2694 2624 2611 2619 2602 2611 2606 2609 2617 2624 2607 2608 2603 2527 2613 2436 2656 2593 2595 2607 2602 2607 2617 2616 2608 2559 2622 2608 2611 2619 2665 2608 2597 2659 2682 2617 2609 2583 2622 2607 2437 2621 2612 2767 2612 2608 2617 2602 2606 2612 2613 2608 2650 2610 2610 2608 2602 2612 2616 2645 2596 2608 2621 2621 2608 2603 2603 2609 2599 2598 2591 2609 2608 2594 2615 2559 2646 2596 2606 2607 2505 2617 2607 2596 2610 2601 2705 2613 2646 2605 2585 2607 2603 2559 2618 2608 2608 2534 2614 2613 2614 2626 2594 2638 2609 2612 2617 2603 2598 2606 2604 2608 2591 2607 2607 2626 2608 2603 2608 2607 2608 2596 2615 2611 2559 2637 2613 2619 2611 2606 2646 2601 2601 2527 2613 2614 2622 2617 2624 2619 2608 2614 2782 2607 2622 2624 2619 2616 2606 2620 2614 2637 2624 2601 2583 2625 2631 2630 2640 2608 2622 2603 2610 2597 2606 2588 2608 2608 2611 2614 2604 2597 2608 2613 2603 2585 2602 2583 2592 2608 2605 2603 2614 2590 2626 2606 2602 2716 2585 2587 2588 2624 2624 2608 2606 2595 2587 2611 2595 2559 2615 2606 2603 2608 2599 2542 2598 2592 2599 2608 2581 2604 2621 2602 2609 2605 2613 2609 2597 2559 2592 2616 2661 2559 2559 2613 2608 2516 2608 2559 2587 2605 2624 2599 2608 2583 2592 2585 2603 2605 2585 2608 2605 2608 2711 2609 2598 2559 2559 2603 2622 2603 2589 2594 2606 2591 2597 2515 2601 2603 2605 2496 2594 2508 2597 2559 2609 2615 2604 2592 2559 2640 2593 2599 2591 2543 2603 2630 2605 2598 2583 2623 2599 2591 2582 2608 2551 2595 2559 2658 2582 2581 2544 2664 2587 2595 2592 2627 2594 2605 2606 2596 2595 2588 2593 2559 2597 2609 2606 2590 2598 2593 2639 2615 2559 2608 2596 2593 2590 2611 2590 2595 2602 2591 2592 2559 2606 2607 2548 2559 2598 2605 2591 2591 2597 2596 2590 2608 2589 2586 2594 2595 2587 2582 2615 2603 2594 2597 2598 2597 2529 2593 2604 2757 2595 2589 2591 2554 2608 2594 2599 2593 2609 2587 2593 2608 2605 2602 2603 2592 2603 2602 2607 2598 2595 2619 2516 2592 2608 2598 2614 2559 2559 2606 2583 2594 2591 2618 2589 2522 2603 2597 2606 2613 2599 2559 2626 2605 2590 2587 2589 2600 2594 2559 2586 2641 2595 2586 2597 2599 2594 2559 2590 2587 2583 2593 2501 2590 2589 2559 2559 2585 2591 2597 2593 2613 2592 2559 2559 2585 2580 2559 2592 2641 2592 2615 2608 2618 2509 2597 2582 2593 2527 2559 2593 2596 2524 2599 2603 2585 2605 2583 2599 2682 2587 2591 2559 2539 2595 2624 2601 2624 2559 2591 2587 2559 2559 2597 2603 2594 2594 2601 2512 2591 2604 2585 2593 2559 2598 2559 2604 2601 2603 2608 2586 2594 2595 2579 2545 2591 2583 2558 2579 2585 2594 2559 2593 2559 2583 2583 2559 2660 2588 2595 2559 2585 2583 2591 2598 2705 2545 2587 2556 2583 2559 2605 2603 2559 2588 2586 2589 2559 2586 2590 2603 2606 2603 2617 2595 2619 2590 2559 2640 2587 2559 2736 2557 2555 2559 2586 2592 2602 2586 2593 2555 2598 2554 2586 2595 2592 2590 2602 2603 2605 2592 2587 2480 2596 2592 2532 2589 2602 2608 2590 2559 2589 2594 2589 2599 2626 2599 2559 2512 2594 2592 2596 2603 2655 2559 2527 2589 2594 2588 2559 2501 2559 2559 2414 2586 2590 2663 2559 2559 2559 2582 2583 2559 2554 2678 2589 2559 2474 2586 2598 2559 2594 2582 2559 2559 2590 2481 2599 2587 2692 2595 2559 2587 2586 2600 2592 2496 2579 2559 2623 2624 2559 2583 2559 2559 2485 2581 2597 2581 2559 2591 2596 2588 2582 2559 2591 2678 2583 2588 2559 2494 2608 2583 2583 2653 2586 2583 2582 2586 2524 2582 2593 2606 2559 2619 2586 2586 2585 2559 2591 2559 2559 2594 2712 2581 2533 2635 2559 2559 2589 2581 2559 2559 2559 2559 2559 2614 2581 2653 2559 2584 2583 2559 2608 2559 2559 2590 2559 2559 2580 2678 2559 2559 2544 2581 2616 2559 2534 2617 2559 2559 2557 2559 2559 2559 2683 2553 2559 2626 2559 2607 2559 2559 2679 2582 2588 2559 2581 2559 2583 2588 2581 2559 2583 2559 2589 2559 2629 2559 2559 2579 2559 2554 2558 2559 2559 2559 2590 2558 2581 2559 2559 2582 2559 2559 2583 2499 2547 2534 2491 2559 2559 2559 2559 2559 2559 2559 2549 2557 2608 2559 2591 2559 2559 2602 2559 2583 2586 2586 2587 2531 2559 2581 2559 2610 2614 2508 2559 2557 2559 2590 2558 2559 2594 2559 2541 2558 2559 2559 2551 2592 2582 2559 2608 2586 2538 2559 2559 2559 2559 2559 2559 2559 2559 2549 2559 2589 2559 2549 2559 2559 2559 2555 2555 2559 2557 2628 2559 2559 2559 2554 2473 2559 2559 2559 2556 2559 2559 2559 2582 2550 2559 2559 2586 2559 2559 2559 2475 2592 2559 2559 2557 2559 2559 2531 2559 2559 2559 2559 2559 2600 2559 2550 2551 2547 2559 2553 2589 2559 2559 2559 2559 2592 2559 2690 2468 2512 2534 2597 2558 2533 2559 2559 2559 2559 2559 2559 2559 2551 2551 2559 2547 2549 2556 2581 2559 2559 2559 2584 2559 2559 2593 2555 2545 2559 2543 2557 2559 2608 2559 2550 2559 2548 2559 2554 2559 2549 2559 2559 2559 2559 2586 2558 2559 2559 2559 2700 2559 2559 2521 2559 2550 2553 2544 2713 2559 2554 2559 2559 2533 2559 2541 2541 2559 2537 2557 2555 2451 2559 2559 2530 2559 2545 2559 2559 2543 2559 2585 2453 2557 2559 2557 2551 2594 2546 2559 2455 2480 2557 2551 2548 2523 2545 2557 2586 2511 2559 2514 2544 2559 2559 2544 2543 2555 2554 2559 2551 2559 2558 2558 2469 2559 2556 2555 2544 2515 2559 2550 2554 2553 2493 2557 2505 2558 2512 2547 2549 2546 2549 2443 2543 2550 2543 2621 2559 2559 2554 2587 2555 2554 2500 2552 2556 2559 2549 2559 2555 2538 2559 2559 2559 2559 2559 2558 2490 2556 2559 2545 2559 2559 2559 2539 2608 2545 2546 2549 2550 2549 2605 2555 2554 2544 2559 2552 2547 2557 2591 2557 2544 2548 2551 2521 2545 2448 2547 2475 2544 2559 2559 2544 2559 2559 2549 2552 2549 2546 2586 2553 2439 2551 2548 2608 2544 2480 2546 2559 2525 2555 2556 2547 2549 2546 2544 2559 2541 2544 2557 2553 2522 2544 2541 2541 2540 2531 2483 2545 2548 2559 2545 2544 2559 2559 2554 2544 2528 2549 2553 2503 2581 2542 2616 2484 2559 2544 2557 2527 2559 2523 2555 2546 2527 2590 2532 2487 2556 2530 2547 2542 2557 2480 2542 2546 2545 2583 2544 2526 2544 2559 2559 2544 2546 2544 2550 2509 2553 2539 2549 2545 2654 2542 2534 2542 2708 2551 2544 2548 2544 2546 2542 2539 2559 2559 2551 2582 2544 2543 2559 2558 2527 2544 2529 2544 2656 2539 2544 2545 2550 2491 2541 2549 2534 2554 2543 2544 2496 2551 2532 2580 2545 2544 2544 2550 2534 2559 2559 2550 2539 2546 2545 2541 2551 2656 2553 2538 2549 2528 2544 2542 2455 2540 2538 2480 2544 2518 2507 2538 2544 2544 2480 2559 2534 2525 2543 2559 2535 2531 2672 2547 2550 2533 2542 2481 2539 2530 2526 2557 2550 2535 2559 2529 2500 2591 2547 2545 2535 2597 2546 2545 2539 2473 2535 2544 2549 2548 2481 2535 2530 2544 2545 2559 2481 2463 2557 2541 2551 2531 2548 2547 2547 2558 2543 2559 2537 2537 2506 2544 2527 2550 2547 2541 2530 2477 2535 2547 2534 2527 2539 2531 2544 2534 2528 2533 2530 2527 2534 2551 2547 2548 2544 2544 2542 2493 2535 2518 2512 2527 2593 2544 2528 2535 2557 2519 2540 2541 2559 2541 2531 2534 2669 2546 2549 2539 2503 2534 2518 2538 2530 2542 2534 2512 2530 2611 2543 2528 2518 2532 2534 2402 2545 2512 2559 2544 2528 2515 2545 2525 2521 2534 2543 2525 2534 2541 2547 2535 2535 2541 2530 2534 2525 2538 2559 2523 2530 2518 2555 2543 2529 2534 2473 2495 2500 2542 2522 2495 2439 2534 2537 2527 2531 2480 2545 2539 2544 2559 2526 2512 2528 2515 2527 2527 2504 2459 2530 2517 2512 2521 2559 2526 2517 2526 2511 2538 2527 2515 2672 2523 2678 2535 2457 2509 2522 2507 2515 2416 2528 2514 2526 2608 2510 2529 2515 2507 2529 2522 2527 2533 2527 2513 2530 2525 2491 2532 2499 2524 2517 2478 2524 2474 2512 2530 2500 2531 2657 2530 2514 2539 2533 2533 2529 2554 2527 2513 2594 2531 2522 2415 2544 2529 2513 2515 2547 2530 2515 2526 2517 2530 2389 2522 2529 2559 2531 2532 2518 2526 2559 2514 2525 2499 2524 2527 2528 2512 2506 2542 2509 2533 2512 2512 2518 2497 2519 2513 2481 2522 2512 2545 2521 2545 2534 2512 2512 2518 2509 2524 2516 2541 2523 2551 2512 2477 2523 2529 2526 2493 2521 2515 2521 2545 2535 2541 2525 2519 2518 2403 2512 2514 2438 2512 2511 2528 2521 2525 2559 2507 2538 2559 2535 2523 2522 2462 2543 2524 2512 2507 2493 2516 2508 2512 2549 2538 2453 2523 2535 2522 2542 2546 2512 2515 2557 2536 2522 2531 2507 2509 2544 2502 2523 2522 2549 2522 2512 2522 2525 2521 2529 2526 2517 2526 2512 2522 2509 2512 2509 2521 2513 2512 2523 2510 2418 2497 2512 2520 2512 2516 2529 2529 2522 2519 2679 2529 2519 2527 2531 2491 2448 2501 2512 2543 2506 2529 2494 2506 2542 2509 2522 2501 2494 2491 2650 2518 2513 2512 2527 2515 2523 2538 2511 2480 2510 2517 2512 2511 2510 2505 2513 2526 2522 2504 2513 2522 2594 2539 2519 2509 2512 2544 2527 2508 2442 2513 2538 2518 2516 2511 2521 2550 2523 2513 2529 2557 2522 2505 2507 2507 2509 2507 2542 2505 2512 2509 2483 2514 2506 2516 2521 2515 2513 2505 2510 2509 2477 2512 2501 2512 2522 2511 2510 2499 2506 2498 2499 2512 2479 2489 2506 2510 2514 2557 2451 2495 2512 2502 2491 2525 2465 2512 2506 2519 2494 2502 2503 2496 2465 2512 2559 2523 2497 2495 2512 2497 2494 2486 2517 2514 2509 2519 2512 2514 2522 2508 2445 2510 2525 2503 2509 2519 2509 2496 2495 2506 2458 2510 2496 2530 2509 2506 2512 2505 2407 2506 2505 2501 2518 2494 2523 2510 2510 2501 2510 2559 2506 2512 2512 2457 2509 2512 2493 2503 2505 2494 2503 2501 2459 2491 2506 2513 2482 2426 2496 2505 2512 2495 2503 2494 2492 2499 2505 2512 2503 2498 2505 2409 2489 2516 2512 2559 2504 2487 2544 2504 2512 2499 2559 2510 2485 2531 2653 2535 2491 2502 2510 2509 2501 2481 2509 2501 2512 2512 2491 2501 2492 2511 2496 2502 2498 2559 2527 2548 2531 2512 2500 2434 2529 2498 2502 2509 2550 2491 2513 2540 2527 2544 2506 2475 2559 2502 2494 2549 2423 2502 2511 2540 2509 2495 2494 2496 2498 2583 2518 2507 2497 2501 2485 2507 2496 2496 2500 2557 2502 2497 2497 2495 2494 2486 2497 2507 2495 2498 2421 2474 2499 2496 2508 2498 2481 2493 2499 2470 2512 2491 2479 2502 2498 2497 2496 2492 2527 2455 2510 2502 2509 2531 2502 2496 2499 2500 2444 2503 2512 2512 2409 2512 2498 2499 2501 2506 2509 2526 2510 2506 2478 2463 2621 2494 2495 2491 2496 2482 2486 2508 2498 2517 2501 2496 2530 2480 2496 2508 2487 2474 2480 2485 2423 2486 2489 2624 2498 2496 2500 2490 2499 2503 2482 2490 2477 2500 2487 2493 2491 2497 2625 2467 2485 2491 2488 2497 2497 2486 2491 2486 2491 2497 2497 2512 2469 2496 2493 2513 2495 2497 2491 2506 2489 2496 2487 2490 2489 2496 2416 2525 2480 2489 2491 2487 2480 2496 2513 2497 2491 2490 2395 2491 2482 2483 2498 2471 2489 2493 2485 2490 2496 2497 2388 2483 2496 2448 2506 2473 2485 2479 2480 2480 2477 2475 2482 2522 2511 2495 2448 2489 2406 2507 2547 2486 2447 2489 2487 2476 2495 2480 2480 2427 2530 2491 2479 2481 2483 2321 2477 2480 2479 2461 2489 2478 2494 2480 2486 2489 2461 2427 2482 2508 2484 2527 2484 2482 2485 2414 2487 2487 2487 2385 2482 2482 2479 2480 2505 2497 2507 2484 2477 2507 2386 2480 2483 2481 2485 2470 2470 2486 2467 2480 2485 2493 2416 2461 2477 2482 2491 2462 2468 2487 2481 2507 2480 2480 2457 2478 2608 2459 2503 2480 2487 2517 2471 2479 2483 2471 2376 2476 2448 2484 2354 2459 2541 2448 2480 2479 2477 2477 2474 2478 2475 2480 2479 2460 2430 2495 2493 2459 2462 2475 2477 2477 2478 2485 2480 2480 2455 2416 2481 2439 2476 2467 2485 2478 2475 2474 2486 2470 2485 2461 2480 2511 2483 2482 2481 2480 2461 2465 2479 2475 2472 2487 2475 2487 2393 2481 2417 2482 2474 2419 2486 2512 2448 2471 2480 2386 2478 2642 2485 2480 2462 2492 2451 2513 2480 2469 2471 2473 2417 2477 2479 2475 2481 2503 2527 2470 2471 2473 2470 2469 2465 2480 2475 2469 2465 2480 2467 2475 2475 2468 2455 2465 2464 2480 2473 2451 2480 2479 2484 2459 2430 2480 2448 2484 2470 2435 2476 2496 2475 2480 2462 2477 2460 2467 2480 2475 2468 2495 2464 2473 2471 2466 2512 2461 2510 2466 2473 2485 2496 2471 2467 2489 2471 2454 2491 2423 2493 2461 2469 2519 2477 2469 2481 2427 2475 2471 2472 2479 2455 2471 2479 2466 2464 2475 2429 2477 2453 2384 2467 2473 2511 2415 2469 2463 2453 2463 2464 2475 2459 2380 2476 2448 2453 2465 2457 2449 2478 2467 2411 2453 2466 2469 2451 2451 2474 2465 2505 2437 2478 2433 2463 2466 2463 2486 2478 2463 2467 2470 2462 2471 2471 2483 2455 2474 2475 2461 2468 2438 2456 2389 2464 2470 2463 2451 2453 2485 2455 2448 2433 2463 2467 2468 2448 2469 2459 2463 2471 2463 2384 2468 2471 2463 2466 2475 2465 2483 2463 2469 2468 2457 2464 2414 2480 2462 2468 2458 2473 2473 2449 2469 2464 2467 2405 2443 2489 2518 2367 2464 2467 2494 2467 2403 2480 2467 2460 2374 2448 2471 2450 2448 2442 2448 2445 2539 2448 2448 2453 2448 2464 2455 2485 2448 2480 2468 2449 2466 2454 2463 2459 2455 2457 2452 2466 2481 2466 2448 2459 2481 2551 2464 2466 2458 2495 2466 2450 2455 2435 2447 2435 2434 2455 2464 2601 2469 2451 2463 2459 2447 2462 2457 2459 2332 2459 2459 2455 2434 2453 2442 2472 2463 2462 2448 2451 2461 2464 2449 2455 2461 2467 2438 2454 2454 2452 2448 2457 2474 2441 2458 2495 2458 2464 2434 2433 2418 2559 2442 2448 2449 2464 2448 2453 2450 2448 2451 2449 2416 2451 2463 2440 2559 2449 2528 2608 2452 2448 2448 2465 2384 2432 2439 2442 2419 2447 2464 2433 2451 2436 2463 2438 2444 2460 2451 2494 2450 2459 2448 2448 2461 2457 2410 2448 2399 2447 2434 2447 2454 2448 2470 2448 2445 2439 2448 2448 2402 2459 2432 2451 2463 2462 2467 2448 2450 2453 2485 2422 2535 2431 2445 2442 2449 2541 2442 2447 2441 2430 2445 2457 2447 2371 2451 2448 2430 2426 2678 2435 2367 2445 2446 2448 2434 2368 2450 2428 2442 2464 2432 2461 2546 2384 2427 2447 2476 2441 2451 2439 2416 2434 2453 2455 2534 2438 2447 2453 2439 2474 2455 2438 2441 2550 2443 2437 2437 2437 2432 2447 2431 2445 2512 2512 2448 2447 2448 2435 2482 2429 2453 2416 2448 2485 2436 2445 2423 2447 2443 2454 2448 2448 2448 2448 2545 2445 2443 2453 2429 2453 2453 2417 2432 2433 2437 2432 2442 2446 2449 2387 2427 2439 2448 2442 2433 2438 2403 2438 2451 2417 2409 2441 2443 2471 2475 2425 2439 2428 2418 2398 2437 2439 2431 2439 2395 2454 2439 2431 2422 2432 2458 2436 2422 2435 2446 2437 2428 2436 2435 2447 2437 2435 2448 2425 2442 2445 2386 2441 2441 2445 2447 2439 2449 2440 2435 2432 2437 2405 2448 2521 2494 2446 2465 2433 2470 2404 2431 2256 2431 2353 2430 2433 2432 2499 2422 2432 2414 2430 2361 2441 2430 2442 2445 2431 2432 2411 2384 2438 2396 2529 2428 2369 2416 2423 2433 2427 2408 2493 2407 2425 2436 2374 2425 2411 2395 2430 2431 2434 2446 2431 2425 2369 2423 2435 2457 2399 2431 2418 2434 2407 2418 2418 2434 2419 2417 2427 2429 2441 2467 2425 2416 2427 2441 2447 2426 2432 2428 2429 2438 2417 2426 2333 2435 2407 2422 2439 2430 2400 2438 2411 2428 2440 2451 2458 2427 2427 2426 2435 2439 2430 2371 2454 2431 2429 2470 2418 2354 2435 2439 2432 2427 2421 2416 2431 2419 2558 2416 2438 2404 2425 2441 2351 2375 2419 2427 2352 2421 2418 2423 2443 2421 2442 2420 2424 2432 2422 2432 2411 2433 2443 2439 2387 2434 2407 2441 2436 2438 2427 2399 2434 2421 2419 2432 2432 2416 2434 2421 2432 2443 2400 2414 2432 2435 2429 2423 2427 2419 2411 2427 2426 2513 2420 2391 2455 2416 2432 2432 2426 2427 2430 2415 2425 2429 2416 2414 2417 2418 2397 2412 2419 2406 2410 2414 2381 2425 2450 2407 2416 2401 2420 2416 2411 2419 2379 2416 2391 2434 2407 2397 2416 2351 2405 2426 2415 2402 2419 2415 2413 2433 2416 2427 2412 2559 2386 2416 2365 2443 2291 2397 2419 2432 2409 2415 2432 2415 2426 2377 2410 2417 2418 2452 2460 2416 2529 2404 2386 2416 2422 2423 2416 2416 2417 2416 2416 2410 2377 2401 2416 2352 2402 2414 2530 2405 2407 2403 2418 2395 2411 2311 2407 2406 2446 2411 2416 2332 2415 2413 2399 2423 2416 2417 2415 2417 2423 2421 2432 2307 2425 2415 2413 2397 2384 2410 2406 2431 2421 2416 2410 2410 2401 2394 2436 2416 2399 2400 2353 2405 2407 2398 2401 2400 2401 2413 2411 2404 2408 2411 2413 2411 2406 2422 2416 2410 2390 2416 2512 2409 2411 2326 2415 2395 2349 2423 2395 2394 2404 2397 2375 2369 2419 2414 2358 2390 2400 2406 2384 2398 2397 2395 2410 2403 2466 2430 2386 2421 2411 2397 2413 2410 2415 2380 2403 2390 2405 2391 2297 2423 2394 2470 2384 2346 2398 2405 2405 2397 2391 2399 2397 2398 2402 2389 2395 2421 2367 2375 2396 2401 2416 2404 2414 2403 2391 2302 2463 2421 2387 2425 2405 2410 2426 2401 2404 2425 2406 2395 2409 2395 2432 2407 2402 2543 2400 2417 2416 2403 2416 2351 2403 2403 2379 2379 2409 2409 2409 2425 2394 2397 2399 2503 2333 2411 2439 2401 2390 2401 2395 2517 2418 2387 2498 2402 2406 2395 2408 2362 2394 2391 2404 2403 2416 2399 2387 2405 2421 2400 2398 2284 2397 2405 2402 2398 2395 2449 2401 2410 2401 2409 2407 2378 2412 2411 2394 2402 2423 2387 2393 2382 2413 2401 2409 2388 2403 2397 2400 2395 2395 2393 2406 2326 2393 2385 2428 2389 2395 2398 2386 2387 2310 2352 2394 2393 2369 2383 2381 2403 2381 2407 2401 2393 2400 2398 2395 2370 2395 2390 2383 2429 2375 2429 2387 2385 2493 2399 2384 2385 2397 2391 2351 2416 2397 2409 2381 2393 2382 2391 2320 2384 2384 2390 2380 2380 2384 2393 2387 2384 2383 2381 2383 2507 2387 2393 2369 2392 2370 2375 2384 2384 2387 2346 2404 2384 2385 2366 2393 2395 2390 2387 2400 2394 2383 2385 2311 2382 2373 2397 2384 2386 2394 2384 2370 2389 2378 2391 2320 2384 2388 2517 2394 2389 2389 2438 2385 2421 2384 2423 2390 2390 2383 2394 2492 2384 2391 2381 2384 2418 2385 2411 2395 2389 2305 2394 2390 2389 2384 2384 2384 2397 2394 2384 2320 2526 2396 2384 2381 2524 2341 2393 2388 2403 2339 2413 2371 2400 2365 2401 2343 2405 2384 2291 2319 2397 2397 2389 2384 2364 2373 2373 2397 2339 2383 2389 2379 2375 2390 2362 2314 2398 2464 2535 2393 2402 2384 2381 2382 2381 2343 2375 2335 2394 2368 2375 2385 2359 2368 2395 2384 2383 2352 2380 2384 2391 2381 2339 2404 2386 2450 2384 2369 2484 2395 2448 2382 2377 2384 2379 2385 2370 2384 2422 2375 2455 2385 2363 2384 2385 2375 2389 2382 2374 2383 2309 2378 2374 2385 2426 2330 2379 2362 2373 2370 2377 2343 2379 2373 2372 2371 2378 2384 2281 2368 2369 2369 2374 2389 2342 2435 2368 2363 2375 2387 2373 2384 2364 2382 2373 2375 2366 2369 2375 2373 2364 2358 2342 2384 2321 2337 2383 2358 2371 2384 2307 2320 2358 2371 2379 2378 2366 2387 2368 2374 2382 2374 2367 2384 2381 2383 2352 2311 2389 2382 2397 2366 2397 2375 2384 2382 2387 2362 2377 2378 2368 2398 2258 2380 2356 2384 2408 2400 2381 2375 2384 2359 2381 2370 2349 2369 2315 2322 2371 2363 2342 2383 2361 2384 2364 2386 2365 2315 2304 2367 2354 2384 2352 2335 2370 2366 2294 2259 2367 2371 2372 2372 2355 2368 2365 2365 2382 2368 2384 2367 2373 2353 2368 2368 2384 2371 2383 2368 2359 2382 2352 2369 2363 2355 2370 2348 2366 2418 2367 2352 2434 2365 2321 2367 2347 2364 2351 2383 2384 2352 2374 2167 2371 2372 2385 2367 2385 2385 2350 2359 2379 2362 2375 2366 2305 2367 2366 2471 2361 2365 2363 2381 2357 2356 2384 2378 2390 2362 2364 2363 2352 2365 2364 2361 2353 2358 2354 2352 2358 2349 2367 2352 2358 2368 2298 2352 2368 2365 2369 2352 2384 2333 2377 2363 2311 2349 2377 2360 2352 2369 2353 2395 2357 2357 2355 2350 2366 2359 2357 2362 2367 2359 2365 2350 2361 2354 2360 2353 2285 2352 2363 2349 2355 2399 2355 2361 2352 2393 2362 2357 2351 2368 2315 2357 2360 2367 2365 2279 2357 2368 2363 2359 2361 2368 2363 2358 2480 2367 2279 2341 2366 2403 2353 2366 2309 2323 2352 2367 2336 2408 2357 2347 2358 2351 2420 2357 2369 2335 2375 2354 2373 2367 2352 2348 2355 2355 2368 2352 2377 2331 2460 2364 2336 2351 2345 2350 2301 2375 2355 2351 2323 2352 2353 2494 2354 2362 2367 2353 2482 2384 2355 2363 2352 2337 2275 2462 2354 2355 2391 2350 2352 2355 2328 2347 2278 2358 2359 2275 2365 2352 2368 2359 2353 2350 2354 2351 2359 2352 2365 2368 2333 2279 2350 2362 2353 2353 2358 2354 2375 2350 2347 2343 2353 2365 2343 2354 2363 2357 2343 2340 2345 2354 2346 2353 2355 2354

Mic branch [2026-04-19 Sun]

INMP441 heres my overall (very messy) notes.

i need a stepwise checklist of work to do, picking up this project after 6mo.

i think broadest steps are:

  1. remind myself of circuit state, how to hookup and test
  2. implement inmp441 - may need to retool the circuit?

    1. will this functino on the existing power (big goal)
    2. remove/modify any inline circuitry to make this work?
  3. ??? test?

Goal: replace noisy speaker-tap adc path with an inmp441 mic path

  • reuse existing esp32 + wifi + rtp stack
  • reuse existing 3.17v power tap

checklist

Bench Check

  • the exact esp32 board
  • the vtech dm221-2 / pm221
  • known-good firmware that can stream the 440hz tone over rtp to vlc
  • the current ip/ssid/port expectations
  • success = you can flash, boot, and hear tone mode again in vlc. this revalidates the network/rtp side before you perturb the input path

Confirm live circuit:

  • take clear photos of pcb top/bottom
  • mark current power tap location
  • mark current speaker/adc wiring
  • note whether gpio36 speaker-tap circuit is still installed
  • note whether touch pin mode switching is still wired
  • your notes show enough circuit churn that future-you will otherwise get gaslit by Past You.

Verify power in isolation:

  • measure the 3.17v rail again at tp20/tp12/q6
  • confirm esp32 still boots stably from that rail
  • add/confirm local decoupling near esp32 power if needed
  • success = stable boot, wifi connect, no brownout/reboot weirdness. you already concluded the 3.17v tap was viable and a major goal is to keep it.

Verify s/w baseline

keep hardware input out of it for a minute:

  • flash the known-good tone generator
  • confirm seq/ts behavior and vlc playback
  • optionally disable wifi power save while testing
  • success = tone stream sounds clean enough that any later ugliness is input-side, not transport-side.

hardware cutover

assume the old speaker-to-gpio36 analog front end gets bypassed or removed:

  • gpio36 adc path is no longer the primary input
  • the RC/divider/bias network for speaker tap is not needed for the mic path
  • keep it only if you explicitly want fallback mode later
  • this is the big topology change. dont half-migrate and leave yourself ambiguous failure modes. your notes already point to the speaker tap being the pain source.

bench-test the inmp441 off the existing esp32 power

  • power inmp441 from the same esp32 3.xv rail
  • wire only power + ground + i2s lines
  • capture raw samples / stream audio with the mic sitting on the bench
  • success = it powers and produces stable audio without resets/noise disasters.

inmp441 table

PIN NAME FUNCTION
1 SCK Serial-Data Clock for I²S Interface
2 SD Serial-Data Output for I²S Interface. This pin tri-states when not actively driving the appropriate output channel. The SD trace should have a 100 kΩ pulldown resistor to discharge the line during the time that all microphones on the bus have tri-stated their outputs.
3 WS Serial Data-Word Select for I²S Interface
4 L/R Left/Right Channel Select. When set low, the microphone outputs its signal in the left channel of the I²S frame. When set high, the microphone outputs its signal in the right channel.
5 GND Ground. Connect to ground on the PCB.
6 GND Ground. Connect to ground on the PCB.
7 VDD Power, 1.8 V to 3.3 V. This pin should be decoupled to Pin 6 with a 0.1 μF capacitor.
8 CHIPEN Microphone Enable. When set low (ground), the microphone is disabled and put in power-down mode. When set high (VDD), the microphone is enabled.
9 GND Ground. Connect to ground on the PCB
  • added sketch to /proj/vtech/mic

couple caveats, bc esp32 audio loves being a goblin: the >> 11 unpack line is the bit most likely to need fiddling on your exact board/core, and I2S_COMM_FORMAT_STAND_I2S vs one of the older enum names can vary by installed core.

script

#include <WiFi.h>
#include <WiFiUdp.h>
#include <math.h>
#include <driver/i2s.h>
#include <driver/touch_pad.h>

const char* ssid = "Fios-8EKF5";
const char* password = "hero816cars7050jon";
const char* DEST_IP = "192.168.1.190";
const int UDP_PORT = 5004;

const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate
const int MIC_RATE = 16000;   // capture rate inmp441
const int FRAME_SIZE  = 160;  // 20ms frames @ 8kHz
const float TONE_HZ   = 440.0;

const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13
const int TOUCH_THRESHOLD = 800; // adjust as needed

// inmp441 pins - change as needed
const int I2S_WS  = 25; // 
const int I2S_SCK = 26; // 
const int I2S_SD  = 33; // data from mic to esp32 

WiFiUDP udp;
uint16_t seq = 0;
uint32_t ts = 0;
bool tone_mode = true; // start with tone

struct rtp_hdr {
  uint8_t vpxcc;
  uint8_t mpt;
  uint16_t seq;
  uint32_t ts;
  uint32_t ssrc;
};

static const int16_t exp_lut[256] = {
  0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};

uint8_t linear2ulaw(int16_t pcm_val) {
  int sign = (pcm_val >> 8) & 0x80;
  if (sign) pcm_val = (short)-pcm_val;
  if (pcm_val > 32635) pcm_val = 32635;
  pcm_val = pcm_val + 0x84;
  int exponent = exp_lut[(pcm_val >> 7) & 0xFF];
  int mantissa = (pcm_val >> (exponent + 3)) & 0x0F;
  return ~(sign | (exponent << 4) | mantissa);
}

void setup_i2s_mic() {
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = MIC_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 8,
    .dma_buf_len = 256,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0
  };

  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_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
  i2s_zero_dma_buffer(I2S_NUM_0);
}

void setup() {
  Serial.begin(115200);
  
  // init touch
  touch_pad_init();
  touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
  touch_pad_config(TOUCH_PIN, 0);
  
  setup_i2s_mic();

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
  Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str());
  udp.begin(UDP_PORT);
  
  Serial.println("tap pin 13 to switch modes");
}

void loop() {
  static unsigned long last_send = 0;
  static unsigned long last_touch_check = 0;
  static bool last_touch_state = false;
  static const unsigned long FRAME_INTERVAL = 20; // 20ms
  static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms
  
  // check touch state periodically
  unsigned long now = millis();
  if (now - last_touch_check > TOUCH_CHECK_INTERVAL) {
    uint16_t touch_val;
    touch_pad_read(TOUCH_PIN, &touch_val);
    bool touched = touch_val < TOUCH_THRESHOLD;
    
    // detect touch press (not hold)
    if (touched && !last_touch_state) {
      tone_mode = !tone_mode;
      Serial.printf("switched to %s mode\n", tone_mode ? "tone" : "mic");
      delay(200); // debounce
    }
    
    last_touch_state = touched;
    last_touch_check = now;
  }
  
  // only send if it's time
  if (now - last_send < FRAME_INTERVAL) {
    yield();
    return;
  }
  
  uint8_t packet[12 + FRAME_SIZE];
  int16_t samples[FRAME_SIZE];
  
  if (tone_mode) {
    // fixed tone generation with integer phase accumulator
    static uint32_t phase_acc = 0;
    const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE);
    
    for (int i = 0; i < FRAME_SIZE; i++) {
      float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0);
      samples[i] = (int16_t)(16000.0 * sinf(phase));
      phase_acc += phase_inc_int;
    }
    
  } else {

    // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz
    int32_t mic_buf[FRAME_SIZE * 2];
    size_t bytes_read = 0;
    i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY);

    int frames_read = bytes_read / sizeof(int32_t);
    if (frames_read < FRAME_SIZE * 2) {
      for (int i = 0; i < FRAME_SIZE; i++) samples[i] = 0;
    } else {
      static float dc = 0.0f;
      static float lpf = 0.0f;

      for (int i = 0; i < FRAME_SIZE; i++) {
        // inmp441 data is typically left-justified in 32-bit words; shift may need
        // minor tweaking on your exact board/core
        int32_t raw = mic_buf[i * 2] >> 14;   // collapse toward 16-bit-ish range
        float x = (float)raw;

        dc = dc * 0.999f + x * 0.001f;
        x -= dc;

        lpf = lpf * 0.7f + x * 0.3f;
        float y = lpf * 1.0f; // gain trim try 8.0f?

        if (y > 32767.0f) y = 32767.0f;
        if (y < -32768.0f) y = -32768.0f;
        samples[i] = (int16_t)y;
        }
        //DEBUG
        static unsigned long last_dbg = 0;
        int16_t minv = 32767;
        int16_t maxv = -32768;

        for (int j = 0; j < FRAME_SIZE; j++) {
          if (samples[j] < minv) minv = samples[j];
          if (samples[j] > maxv) maxv = samples[j];
        }

        if (millis() - last_dbg > 250) {
          Serial.printf("mic range: %d .. %d\n", minv, maxv);
          last_dbg = millis();
        }
        // END DEBUG
      }
    }

  for (int i = 0; i < FRAME_SIZE; i++) {
    packet[12 + i] = linear2ulaw(samples[i]);
  }

  rtp_hdr* hdr = (rtp_hdr*)packet;
  hdr->vpxcc = 0x80;
  hdr->mpt   = 0x00;
  hdr->seq   = htons(seq++);
  hdr->ts    = htonl(ts);
  hdr->ssrc  = htonl(0x12345678);

  udp.beginPacket(DEST_IP, UDP_PORT);
  udp.write(packet, sizeof(packet));
  udp.endPacket();

  ts += FRAME_SIZE;
  last_send = now;

  yield();
}

script2 - simple mic processing (ln160 ff)

#include <WiFi.h>
#include <WiFiUdp.h>
#include <math.h>
#include <driver/i2s.h>
#include <driver/touch_pad.h>

const char* ssid = "Fios-8EKF5";
const char* password = "hero816cars7050jon";
const char* DEST_IP = "192.168.1.190";
const int UDP_PORT = 5004;

const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate
const int MIC_RATE = 16000;   // capture rate inmp441
const int FRAME_SIZE  = 160;  // 20ms frames @ 8kHz
const float TONE_HZ   = 440.0;

const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13
const int TOUCH_THRESHOLD = 800; // adjust as needed

// inmp441 pins - change as needed
const int I2S_WS  = 25; // 
const int I2S_SCK = 26; // 
const int I2S_SD  = 33; // data from mic to esp32 

WiFiUDP udp;
uint16_t seq = 0;
uint32_t ts = 0;
bool tone_mode = true; // start with tone

struct rtp_hdr {
  uint8_t vpxcc;
  uint8_t mpt;
  uint16_t seq;
  uint32_t ts;
  uint32_t ssrc;
};

static const int16_t exp_lut[256] = {
  0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};

uint8_t linear2ulaw(int16_t pcm_val) {
  int sign = (pcm_val >> 8) & 0x80;
  if (sign) pcm_val = (short)-pcm_val;
  if (pcm_val > 32635) pcm_val = 32635;
  pcm_val = pcm_val + 0x84;
  int exponent = exp_lut[(pcm_val >> 7) & 0xFF];
  int mantissa = (pcm_val >> (exponent + 3)) & 0x0F;
  return ~(sign | (exponent << 4) | mantissa);
}

void setup_i2s_mic() {
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = MIC_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 8,
    .dma_buf_len = 256,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0
  };

  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_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
  i2s_zero_dma_buffer(I2S_NUM_0);
}

void setup() {
  Serial.begin(115200);
  
  // init touch
  touch_pad_init();
  touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
  touch_pad_config(TOUCH_PIN, 0);
  
  setup_i2s_mic();

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
  Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str());
  udp.begin(UDP_PORT);
  
  Serial.println("tap pin 13 to switch modes");
}

void loop() {
  static unsigned long last_send = 0;
  static unsigned long last_touch_check = 0;
  static bool last_touch_state = false;
  static const unsigned long FRAME_INTERVAL = 20; // 20ms
  static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms
  
  // check touch state periodically
  unsigned long now = millis();
  if (now - last_touch_check > TOUCH_CHECK_INTERVAL) {
    uint16_t touch_val;
    touch_pad_read(TOUCH_PIN, &touch_val);
    bool touched = touch_val < TOUCH_THRESHOLD;
    
    // detect touch press (not hold)
    if (touched && !last_touch_state) {
      tone_mode = !tone_mode;
      Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic");
      delay(300); // debounce
    }
    
    last_touch_state = touched;
    last_touch_check = now;
  }
  
  // only send if it's time
  if (now - last_send < FRAME_INTERVAL) {
    yield();
    return;
  }
  
  uint8_t packet[12 + FRAME_SIZE];
  int16_t samples[FRAME_SIZE];
  
  if (tone_mode) {
    // fixed tone generation with integer phase accumulator
    static uint32_t phase_acc = 0;
    const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE);
    
    for (int i = 0; i < FRAME_SIZE; i++) {
      float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0);
      samples[i] = (int16_t)(16000.0 * sinf(phase));
      phase_acc += phase_inc_int;
    }
    
  } else {

    // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz
    int32_t mic_buf[FRAME_SIZE * 2];
    size_t bytes_read = 0;
    i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY);

    int frames_read = bytes_read / sizeof(int32_t);
    if (frames_read < FRAME_SIZE * 2) {
      for (int i = 0; i < FRAME_SIZE; i++) samples[i] = 0;
    } else {
      static float dc = 0.0f;
      static float lpf = 0.0f;
      //
      int16_t minv = 32767;
      int16_t maxv = -32768;
      static unsigned long last_dbg = 0;

      for (int i = 0; i < FRAME_SIZE; i++) {
        int32_t raw = mic_buf[i * 2] >> 8;   // try 8 first, not 14
        if (raw > 32767) raw = 32767;
        if (raw < -32768) raw = -32768;
        samples[i] = (int16_t)raw;

        if (samples[i] < minv) minv = samples[i];
        if (samples[i] > maxv) maxv = samples[i];
      }

      if (millis() - last_dbg > 250) {
        Serial.printf("raw range: %d .. %d\n", minv, maxv);
        last_dbg = millis();
      }
    }
  }
  for (int i = 0; i < FRAME_SIZE; i++) {
    packet[12 + i] = linear2ulaw(samples[i]);
  }

  rtp_hdr* hdr = (rtp_hdr*)packet;
  hdr->vpxcc = 0x80;
  hdr->mpt   = 0x00;
  hdr->seq   = htons(seq++);
  hdr->ts    = htonl(ts);
  hdr->ssrc  = htonl(0x12345678);

  udp.beginPacket(DEST_IP, UDP_PORT);
  udp.write(packet, sizeof(packet));
  udp.endPacket();

  ts += FRAME_SIZE;
  last_send = now;

  yield();
}

script3 - hex dump version:

#include <WiFi.h>
#include <WiFiUdp.h>
#include <math.h>
#include <driver/i2s.h>
#include <driver/touch_pad.h>

const char* ssid = "Fios-8EKF5";
const char* password = "hero816cars7050jon";
const char* DEST_IP = "192.168.1.190";
const int UDP_PORT = 5004;

const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate
const int MIC_RATE = 16000;   // capture rate inmp441
const int FRAME_SIZE  = 160;  // 20ms frames @ 8kHz
const float TONE_HZ   = 440.0;

const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13
const int TOUCH_THRESHOLD = 800; // adjust as needed

// inmp441 pins - change as needed
const int I2S_WS  = 25; // 
const int I2S_SCK = 26; // 
const int I2S_SD  = 33; // data from mic to esp32 

WiFiUDP udp;
uint16_t seq = 0;
uint32_t ts = 0;
bool tone_mode = true; // start with tone

struct rtp_hdr {
  uint8_t vpxcc;
  uint8_t mpt;
  uint16_t seq;
  uint32_t ts;
  uint32_t ssrc;
};

static const int16_t exp_lut[256] = {
  0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};

uint8_t linear2ulaw(int16_t pcm_val) {
  int sign = (pcm_val >> 8) & 0x80;
  if (sign) pcm_val = (short)-pcm_val;
  if (pcm_val > 32635) pcm_val = 32635;
  pcm_val = pcm_val + 0x84;
  int exponent = exp_lut[(pcm_val >> 7) & 0xFF];
  int mantissa = (pcm_val >> (exponent + 3)) & 0x0F;
  return ~(sign | (exponent << 4) | mantissa);
}

void setup_i2s_mic() {
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = MIC_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 8,
    .dma_buf_len = 256,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0
  };

  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_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
  i2s_zero_dma_buffer(I2S_NUM_0);
}

void setup() {
  Serial.begin(115200);
  
  // init touch
  touch_pad_init();
  touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
  touch_pad_config(TOUCH_PIN, 0);
  
  setup_i2s_mic();

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
  Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str());
  udp.begin(UDP_PORT);
  
  Serial.println("tap pin 13 to switch modes");
}

void loop() {
  static unsigned long last_send = 0;
  static unsigned long last_touch_check = 0;
  static bool last_touch_state = false;
  static unsigned long last_dbg = 0;
  static const unsigned long FRAME_INTERVAL = 20; // 20ms
  static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms
  
  // check touch state periodically
  unsigned long now = millis();
  if (now - last_touch_check > TOUCH_CHECK_INTERVAL) {
    uint16_t touch_val;
    touch_pad_read(TOUCH_PIN, &touch_val);
    bool touched = touch_val < TOUCH_THRESHOLD;
    
    // detect touch press (not hold)
    if (touched && !last_touch_state) {
      tone_mode = !tone_mode;
      Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic");
      delay(300); // debounce
    }
    
    last_touch_state = touched;
    last_touch_check = now;
  }
  
  // only send if it's time
  if (now - last_send < FRAME_INTERVAL) {
    yield();
    return;
  }
  
  uint8_t packet[12 + FRAME_SIZE];
  int16_t samples[FRAME_SIZE];
  
  if (tone_mode) {
    // fixed tone generation with integer phase accumulator
    static uint32_t phase_acc = 0;
    const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE);
    
    for (int i = 0; i < FRAME_SIZE; i++) {
      float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0);
      samples[i] = (int16_t)(16000.0 * sinf(phase));
      phase_acc += phase_inc_int;
    }
    
  } else {

    // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz
    int32_t mic_buf[FRAME_SIZE * 2];

    size_t bytes_read = 0;
    i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY);
    for (int i = 0; i < FRAME_SIZE; i++) {
      samples[i] = 0;
    }

    if (bytes_read >= 16 * sizeof(int32_t) && millis() - last_dbg > 500) {
      Serial.println("first 16 raw words:");
      for (int i = 0; i < 16; i++) {
        Serial.printf("%2d: 0x%08lx\n", i, (uint32_t)mic_buf[i]);
      }
      last_dbg = millis();
    }
  }
  for (int i = 0; i < FRAME_SIZE; i++) {
    packet[12 + i] = linear2ulaw(samples[i]);
  }

  rtp_hdr* hdr = (rtp_hdr*)packet;
  hdr->vpxcc = 0x80;
  hdr->mpt   = 0x00;
  hdr->seq   = htons(seq++);
  hdr->ts    = htonl(ts);
  hdr->ssrc  = htonl(0x12345678);

  udp.beginPacket(DEST_IP, UDP_PORT);
  udp.write(packet, sizeof(packet));
  udp.endPacket();

  ts += FRAME_SIZE;
  last_send = now;

  yield();
}

issue

https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/

  • dump is overwhelmingly 0x00000000, 0x00000001, or 0xffffffff, with only very occasional nontrivial words like 0xffbffb41. that means the esp32 is clocking something, but it is mostly seeing a line that is effectively stuck low/high or only barely transitioning, not normal audio sample words.
  • in esp32 standard i2s mode, the bus is just bclk, ws, and data, and standard mode always has left/right slots. in master mode, the esp32 generates sck and ws; the mic only drives the data line.
  • standard-mode format differences on esp32 are basically philips vs msb, where philips has a one-bit shift relative to ws and msb does not. so “wrong format” can cause junk, but a stream dominated by exact 0/1/-1 patterns is more consistent with bad data capture than mere gain.

[2026-04-20 Mon]

very useful expl thanks, you're refreshign my memory on the rtp header work i did a few months ago. good insight on 440hz wandering - i didnt account for network instability inherent in the chipset, of course that makes sense.

heres the mic datasheet.

(WHT) LR GND (BLK) (YEL) WS VDD (RED) (WHT) SCK SD (BLUE)

gnd (WHT) LR GND (BLK) g25 (YEL) WS VDD (RED) g22 (WHT) SCK SD (BLUE) g21

mic outputs 24-bit signed sample, left-justified in 32-bit word [31……..8][7…..0] sample pad

successful hex word test of inmf441

#include <WiFi.h>
#include <WiFiUdp.h>
#include <math.h>
#include <driver/i2s.h>
#include <driver/touch_pad.h>

const char* ssid = "Fios-8EKF5";
const char* password = "hero816cars7050jon";
const char* DEST_IP = "192.168.1.190";
const int UDP_PORT = 5004;

const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate
const int MIC_RATE = 16000;   // capture rate inmp441
const int FRAME_SIZE  = 160;  // 20ms frames @ 8kHz
const float TONE_HZ   = 440.0;

const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13
const int TOUCH_THRESHOLD = 800; // adjust as needed

// inmp441 pins - change as needed
const int I2S_WS  = 25; // 
const int I2S_SCK = 22; // 
const int I2S_SD  = 21; // data from mic to esp32 

WiFiUDP udp;
uint16_t seq = 0;
uint32_t ts = 0;
bool tone_mode = true; // start with tone

struct rtp_hdr {
  uint8_t vpxcc;
  uint8_t mpt;
  uint16_t seq;
  uint32_t ts;
  uint32_t ssrc;
};

static const int16_t exp_lut[256] = {
  0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};

uint8_t linear2ulaw(int16_t pcm_val) {
  int sign = (pcm_val >> 8) & 0x80;
  if (sign) pcm_val = (short)-pcm_val;
  if (pcm_val > 32635) pcm_val = 32635;
  pcm_val = pcm_val + 0x84;
  int exponent = exp_lut[(pcm_val >> 7) & 0xFF];
  int mantissa = (pcm_val >> (exponent + 3)) & 0x0F;
  return ~(sign | (exponent << 4) | mantissa);
}

void setup_i2s_mic() {
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = MIC_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S,
    // .communication_format = I2S_COMM_FORMAT_I2S_MSB,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 8,
    .dma_buf_len = 256,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0
  };

  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_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
  i2s_zero_dma_buffer(I2S_NUM_0);
}

void setup() {
  Serial.begin(115200);
  
  touch_pad_init();
  touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
  touch_pad_config(TOUCH_PIN, 0);
  
  setup_i2s_mic();

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
  Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str());
  udp.begin(UDP_PORT);
  
  Serial.println("tap pin 13 to switch modes");
}

void loop() {
  static unsigned long last_send = 0; // timer
  static unsigned long last_touch_check = 0;  // timer
  static bool last_touch_state = false;
  static unsigned long last_dbg = 0; // timer
  static const unsigned long FRAME_INTERVAL = 20; // 20ms
  static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms
  
  // check touch state periodically
  unsigned long now = millis();
  if (now - last_touch_check > TOUCH_CHECK_INTERVAL) {
    uint16_t touch_val;
    touch_pad_read(TOUCH_PIN, &touch_val);
    bool touched = touch_val < TOUCH_THRESHOLD;
    
    // detect touch press (not hold)
    if (touched && !last_touch_state) {
      tone_mode = !tone_mode;
      Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic");
      delay(300); // debounce
    }
    
    last_touch_state = touched;
    last_touch_check = now;
  }
  
  // only send if it's time
  if (now - last_send < FRAME_INTERVAL) {
    yield();
    return;
  }
  
  uint8_t packet[12 + FRAME_SIZE];
  int16_t samples[FRAME_SIZE];
  
  if (tone_mode) {
    // fixed tone generation with integer phase accumulator
    static uint32_t phase_acc = 0;
    const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE);
    
    for (int i = 0; i < FRAME_SIZE; i++) {
      float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0);
      samples[i] = (int16_t)(16000.0 * sinf(phase));
      phase_acc += phase_inc_int;
    }
    
  } else {

    // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz
    int32_t mic_buf[FRAME_SIZE * 2];

    size_t bytes_read = 0;
    i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY);
    for (int i = 0; i < FRAME_SIZE; i++) {
      samples[i] = 0;
    }

    if (bytes_read >= 16 * sizeof(int32_t) && millis() - last_dbg > 500) {
      Serial.println("first 16 raw words:");
      for (int i = 0; i < 16; i++) {
        Serial.printf("%2d: 0x%08lx\n", i, (uint32_t)mic_buf[i]);
      }
      last_dbg = millis();
    }
  }
  for (int i = 0; i < FRAME_SIZE; i++) {
    packet[12 + i] = linear2ulaw(samples[i]);
  }

  rtp_hdr* hdr = (rtp_hdr*)packet;
  hdr->vpxcc = 0x80;
  hdr->mpt   = 0x00;
  hdr->seq   = htons(seq++);
  hdr->ts    = htonl(ts);
  hdr->ssrc  = htonl(0x12345678);

  udp.beginPacket(DEST_IP, UDP_PORT);
  udp.write(packet, sizeof(packet));
  udp.endPacket();

  ts += FRAME_SIZE;
  last_send = now;

  yield();
}

to add

dc gain dc = dc * 0.999f + x * 0.001f; x -= dc;

low pass filter lpf = lpf * 0.7f + x * 0.3f;

gain float y = x * 2.0f; before adding gains:

  #include <WiFi.h>
#include <WiFiUdp.h>
#include <math.h>
#include <driver/i2s.h>
#include <driver/touch_pad.h>

const char* ssid = "Fios-8EKF5";
const char* password = "hero816cars7050jon";
const char* DEST_IP = "192.168.1.190";
const int UDP_PORT = 5004;

const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate
const int MIC_RATE = 16000;   // capture rate inmp441
const int FRAME_SIZE  = 160;  // 20ms frames @ 8kHz
const float TONE_HZ   = 440.0;

const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13
const int TOUCH_THRESHOLD = 800; // adjust as needed

// inmp441 pins - change as needed
const int I2S_WS  = 25; // 
const int I2S_SCK = 22; // 
const int I2S_SD  = 21; // data from mic to esp32 

WiFiUDP udp;
uint16_t seq = 0;
uint32_t ts = 0;
bool tone_mode = true; // start with tone

struct rtp_hdr {
  uint8_t vpxcc;
  uint8_t mpt;
  uint16_t seq;
  uint32_t ts;
  uint32_t ssrc;
};

static const int16_t exp_lut[256] = {
  0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};

uint8_t linear2ulaw(int16_t pcm_val) {
  int sign = (pcm_val >> 8) & 0x80;
  if (sign) pcm_val = (short)-pcm_val;
  if (pcm_val > 32635) pcm_val = 32635;
  pcm_val = pcm_val + 0x84;
  int exponent = exp_lut[(pcm_val >> 7) & 0xFF];
  int mantissa = (pcm_val >> (exponent + 3)) & 0x0F;
  return ~(sign | (exponent << 4) | mantissa);
}

void setup_i2s_mic() {
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = MIC_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S,
    // .communication_format = I2S_COMM_FORMAT_I2S_MSB,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 8,
    .dma_buf_len = 256,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0
  };

  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_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
  i2s_zero_dma_buffer(I2S_NUM_0);
}

void setup() {
  Serial.begin(115200);
  
  touch_pad_init();
  touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
  touch_pad_config(TOUCH_PIN, 0);
  
  setup_i2s_mic();

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
  Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str());
  udp.begin(UDP_PORT);
  
  Serial.println("tap pin 13 to switch modes");
}

void loop() {
  static unsigned long last_send = 0; // timer
  static unsigned long last_touch_check = 0;  // timer
  static bool last_touch_state = false;
  static unsigned long last_dbg = 0; // timer
  static const unsigned long FRAME_INTERVAL = 20; // 20ms
  static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms
  
  // check touch state periodically
  unsigned long now = millis();
  if (now - last_touch_check > TOUCH_CHECK_INTERVAL) {
    uint16_t touch_val;
    touch_pad_read(TOUCH_PIN, &touch_val);
    bool touched = touch_val < TOUCH_THRESHOLD;
    
    // detect touch press (not hold)
    if (touched && !last_touch_state) {
      tone_mode = !tone_mode;
      Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic");
      delay(300); // debounce
    }
    
    last_touch_state = touched;
    last_touch_check = now;
  }
  
  // only send if it's time
  if (now - last_send < FRAME_INTERVAL) {
    yield();
    return;
  }
  
  uint8_t packet[12 + FRAME_SIZE];
  int16_t samples[FRAME_SIZE];
  
  if (tone_mode) {
    // fixed tone generation with integer phase accumulator
    static uint32_t phase_acc = 0;
    const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE);
    
    for (int i = 0; i < FRAME_SIZE; i++) {
      float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0);
      samples[i] = (int16_t)(16000.0 * sinf(phase));
      phase_acc += phase_inc_int;
    }
    
  } else {

    // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz
    int32_t mic_buf[FRAME_SIZE * 2];
    size_t bytes_read = 0;

    i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY);
    
    for (int i = 0; i < FRAME_SIZE; i++) {
    // decimate 16k → 8k
    int32_t raw = mic_buf[i * 2] >> 16;   // decimate 16k -> 8k by keeping every other sample
    if (raw > 32767) raw = 32767;
    if (raw < -32768) raw = -32768;
    samples[i] = (int16_t)raw;
    }
  }
  for (int i = 0; i < FRAME_SIZE; i++) {
    packet[12 + i] = linear2ulaw(samples[i]);
  }

  rtp_hdr* hdr = (rtp_hdr*)packet;
  hdr->vpxcc = 0x80;
  hdr->mpt   = 0x00;
  hdr->seq   = htons(seq++);
  hdr->ts    = htonl(ts);
  hdr->ssrc  = htonl(0x12345678);

  udp.beginPacket(DEST_IP, UDP_PORT);
  udp.write(packet, sizeof(packet));
  udp.endPacket();

  ts += FRAME_SIZE;
  last_send = now;

  yield();
}

after gains SUCCESS IWTH SOUND!

  #include <WiFi.h>
#include <WiFiUdp.h>
#include <math.h>
#include <driver/i2s.h>
#include <driver/touch_pad.h>

const char* ssid = "Fios-8EKF5";
const char* password = "hero816cars7050jon";
const char* DEST_IP = "192.168.1.190";
const int UDP_PORT = 5004;

const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate
const int MIC_RATE = 16000;   // capture rate inmp441
const int FRAME_SIZE  = 160;  // 20ms frames @ 8kHz
const float TONE_HZ   = 440.0;

const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13
const int TOUCH_THRESHOLD = 800; // adjust as needed

// inmp441 pins - change as needed
const int I2S_WS  = 25; // 
const int I2S_SCK = 22; // 
const int I2S_SD  = 21; // data from mic to esp32 

WiFiUDP udp;
uint16_t seq = 0;
uint32_t ts = 0;
bool tone_mode = true; // start with tone

struct rtp_hdr {
  uint8_t vpxcc;
  uint8_t mpt;
  uint16_t seq;
  uint32_t ts;
  uint32_t ssrc;
};

static const int16_t exp_lut[256] = {
  0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};

uint8_t linear2ulaw(int16_t pcm_val) {
  int sign = (pcm_val >> 8) & 0x80;
  if (sign) pcm_val = (short)-pcm_val;
  if (pcm_val > 32635) pcm_val = 32635;
  pcm_val = pcm_val + 0x84;
  int exponent = exp_lut[(pcm_val >> 7) & 0xFF];
  int mantissa = (pcm_val >> (exponent + 3)) & 0x0F;
  return ~(sign | (exponent << 4) | mantissa);
}

void setup_i2s_mic() {
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = MIC_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S,
    // .communication_format = I2S_COMM_FORMAT_I2S_MSB,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 8,
    .dma_buf_len = 256,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0
  };

  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_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
  i2s_zero_dma_buffer(I2S_NUM_0);
}

void setup() {
  Serial.begin(115200);
  
  touch_pad_init();
  touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
  touch_pad_config(TOUCH_PIN, 0);
  
  setup_i2s_mic();

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
  Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str());
  udp.begin(UDP_PORT);
  
  Serial.println("tap pin 13 to switch modes");
}

void loop() {
  static unsigned long last_send = 0; // timer
  static unsigned long last_touch_check = 0;  // timer
  static bool last_touch_state = false;
  static unsigned long last_dbg = 0; // timer
  static const unsigned long FRAME_INTERVAL = 20; // 20ms
  static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms
  
  // check touch state periodically
  unsigned long now = millis();
  if (now - last_touch_check > TOUCH_CHECK_INTERVAL) {
    uint16_t touch_val;
    touch_pad_read(TOUCH_PIN, &touch_val);
    bool touched = touch_val < TOUCH_THRESHOLD;
    
    // detect touch press (not hold)
    if (touched && !last_touch_state) {
      tone_mode = !tone_mode;
      Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic");
      delay(300); // debounce
    }
    
    last_touch_state = touched;
    last_touch_check = now;
  }
  
  // only send if it's time
  if (now - last_send < FRAME_INTERVAL) {
    yield();
    return;
  }
  
  uint8_t packet[12 + FRAME_SIZE];
  int16_t samples[FRAME_SIZE];
  
  if (tone_mode) {
    // fixed tone generation with integer phase accumulator
    static uint32_t phase_acc = 0;
    const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE);
    
    for (int i = 0; i < FRAME_SIZE; i++) {
      float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0);
      samples[i] = (int16_t)(16000.0 * sinf(phase));
      phase_acc += phase_inc_int;
    }
    
  } else {

    // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz
    int32_t mic_buf[FRAME_SIZE * 2];
    size_t bytes_read = 0;
    i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY);
    
    //debug
    if (millis() - last_dbg > 500) {
      for (int i = 0; i < 8; i++) {
      Serial.printf("%d: 0x%08lx\n", i, (uint32_t)mic_buf[i]);
    }
      last_dbg = millis();
    } 
    //end debug

    for (int i = 0; i < FRAME_SIZE; i++) {
    // decimate 16k → 8k
    int32_t raw = mic_buf[i] >> 16;   // full send 
    // int32_t raw = mic_buf[i*2] >> 16;   // drop every other frame to get to 8k
    samples[i] = (int16_t)raw;
    }

    int16_t minv = 32767;
    int16_t maxv = -32768;

    for (int j = 0; j < FRAME_SIZE; j++) {
      if (samples[j] < minv) minv = samples[j];
      if (samples[j] > maxv) maxv = samples[j];
    }
    //debug2
    if (millis() - last_dbg > 500) {
    Serial.printf("mic range: %d .. %d\n", minv, maxv);
    }
    //end debug2
  }
  for (int i = 0; i < FRAME_SIZE; i++) {
    packet[12 + i] = linear2ulaw(samples[i]);
  }

  rtp_hdr* hdr = (rtp_hdr*)packet;
  hdr->vpxcc = 0x80;
  hdr->mpt   = 0x00;
  hdr->seq   = htons(seq++);
  hdr->ts    = htonl(ts);
  hdr->ssrc  = htonl(0x12345678);

  udp.beginPacket(DEST_IP, UDP_PORT);
  udp.write(packet, sizeof(packet));
  udp.endPacket();

  ts += FRAME_SIZE;
  last_send = now;

  yield();
}

likely slow bc of full send line:

   int32_t raw = mic_buf[i] >> 16;   // full send

done

  #include <WiFi.h>
#include <WiFiUdp.h>
#include <math.h>
#include <driver/i2s.h>
#include <driver/touch_pad.h>

const char* ssid = "Fios-8EKF5";
const char* password = "hero816cars7050jon";
const char* DEST_IP = "192.168.1.190";
const int UDP_PORT = 5004;

const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate
const int MIC_RATE = 8000;   // capture rate inmp441
const int FRAME_SIZE  = 160;  // 20ms frames @ 8kHz
const float TONE_HZ   = 440.0;

const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13
const int TOUCH_THRESHOLD = 500;

const int I2S_WS  = 25; 
const int I2S_SCK = 22; 
const int I2S_SD  = 21; 

WiFiUDP udp;
uint16_t seq = 0;
uint32_t ts = 0;
bool tone_mode = true; // start with tone

struct rtp_hdr {
  uint8_t vpxcc;
  uint8_t mpt;
  uint16_t seq;
  uint32_t ts;
  uint32_t ssrc;
};

static const int16_t exp_lut[256] = {
  0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};

uint8_t linear2ulaw(int16_t pcm_val) {
  int sign = (pcm_val >> 8) & 0x80;
  if (sign) pcm_val = (short)-pcm_val;
  if (pcm_val > 32635) pcm_val = 32635;
  pcm_val = pcm_val + 0x84;
  int exponent = exp_lut[(pcm_val >> 7) & 0xFF];
  int mantissa = (pcm_val >> (exponent + 3)) & 0x0F;
  return ~(sign | (exponent << 4) | mantissa);
}

void setup_i2s_mic() {
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = MIC_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 8,
    .dma_buf_len = 256,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0
  };

  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_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
  i2s_zero_dma_buffer(I2S_NUM_0);
}

void setup() {
  Serial.begin(115200);
  
  touch_pad_init();
  touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
  touch_pad_config(TOUCH_PIN, 0);
  
  setup_i2s_mic();

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
  Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str());
  udp.begin(UDP_PORT);
  
  Serial.println("tap pin 13 to switch modes");
}

void loop() {
  static unsigned long last_send = 0; // timer
  static unsigned long last_touch_check = 0;  // timer
  static bool last_touch_state = false;
  static unsigned long last_dbg = 0; // timer
  static const unsigned long FRAME_INTERVAL = 20; // 20ms
  static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms
  
  // check touch state periodically
  unsigned long now = millis();
  if (now - last_touch_check > TOUCH_CHECK_INTERVAL) {
    uint16_t touch_val;
    touch_pad_read(TOUCH_PIN, &touch_val);
    bool touched = touch_val < TOUCH_THRESHOLD;
    
    // detect touch press (not hold)
    if (touched && !last_touch_state) {
      tone_mode = !tone_mode;
      Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic");
      delay(300); // debounce
    }
    
    last_touch_state = touched;
    last_touch_check = now;
  }
  
  // frame buffer
  if (now - last_send < FRAME_INTERVAL) {
    yield();
    return;
  }
  
  uint8_t packet[12 + FRAME_SIZE];
  int16_t samples[FRAME_SIZE];
  
  if (tone_mode) {
    // fixed tone generation with integer phase accumulator
    static uint32_t phase_acc = 0;
    const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE);
    
    for (int i = 0; i < FRAME_SIZE; i++) {
      float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0);
      samples[i] = (int16_t)(16000.0 * sinf(phase));
      phase_acc += phase_inc_int;
    }
    
  } else {
    int32_t mic_buf[FRAME_SIZE];
    size_t bytes_read = 0;
    i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY);

    for (int i = 0; i < FRAME_SIZE; i++) {
      float y = (mic_buf[i] >> 16) * 4.0f; //gain
      if (y > 32767.0f) y = 32767.0f;
      if (y < -32768.0f) y = -32768.0f;
      samples[i] = (int16_t)y;
    }

    int16_t minv = 32767;
    int16_t maxv = -32768;

    for (int j = 0; j < FRAME_SIZE; j++) {
      if (samples[j] < minv) minv = samples[j];
      if (samples[j] > maxv) maxv = samples[j];
    }
  }
  for (int i = 0; i < FRAME_SIZE; i++) {
    packet[12 + i] = linear2ulaw(samples[i]);
  }

  rtp_hdr* hdr = (rtp_hdr*)packet;
  hdr->vpxcc = 0x80;
  hdr->mpt   = 0x00;
  hdr->seq   = htons(seq++);
  hdr->ts    = htonl(ts);
  hdr->ssrc  = htonl(0x12345678);

  udp.beginPacket(DEST_IP, UDP_PORT);
  udp.write(packet, sizeof(packet));
  udp.endPacket();

  ts += FRAME_SIZE;
  last_send = now;

  yield();
}

Final Veersion mic.cpp

#include <WiFi.h>
#include <WiFiUdp.h>
#include <math.h>
#include <driver/i2s.h>
#include <driver/touch_pad.h>

const char* ssid = "Fios-8EKF5";
const char* password = "hero816cars7050jon";
const char* DEST_IP = "192.168.1.190";
const int UDP_PORT = 5004;

const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate
const int MIC_RATE = 8000;   // capture rate inmp441
const int FRAME_SIZE  = 160;  // 20ms frames @ 8kHz
const float TONE_HZ   = 440.0;
const float MIC_GAIN = 4.0f;

const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13
const int TOUCH_THRESHOLD = 500;

const int I2S_WS  = 25; 
const int I2S_SCK = 22; 
const int I2S_SD  = 21; 

WiFiUDP udp;
uint16_t seq = 0;
uint32_t ts = 0;
bool tone_mode = true; // start with tone

struct rtp_hdr {
  uint8_t vpxcc;
  uint8_t mpt;
  uint16_t seq;
  uint32_t ts;
  uint32_t ssrc;
};

static const int16_t exp_lut[256] = {
  0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};

uint8_t linear2ulaw(int16_t pcm_val) {
  int sign = (pcm_val >> 8) & 0x80;
  if (sign) pcm_val = (short)-pcm_val;
  if (pcm_val > 32635) pcm_val = 32635;
  pcm_val = pcm_val + 0x84;
  int exponent = exp_lut[(pcm_val >> 7) & 0xFF];
  int mantissa = (pcm_val >> (exponent + 3)) & 0x0F;
  return ~(sign | (exponent << 4) | mantissa);
}

void setup_i2s_mic() {
  i2s_config_t i2s_config = {
    .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = MIC_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = I2S_COMM_FORMAT_STAND_I2S,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 8,
    .dma_buf_len = 256,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0
  };

  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_NUM_0, &i2s_config, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pin_config);
  i2s_zero_dma_buffer(I2S_NUM_0);
}

void setup() {
  Serial.begin(115200);
  
  touch_pad_init();
  touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
  touch_pad_config(TOUCH_PIN, 0);
  
  setup_i2s_mic();

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
  Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str());
  udp.begin(UDP_PORT);
  
  Serial.println("tap pin 13 to switch modes");
}

void loop() {
  static unsigned long last_send = 0; // timer
  static unsigned long last_touch_check = 0;  // timer
  static bool last_touch_state = false;
  static const unsigned long FRAME_INTERVAL = 20; // 20ms
  static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms
  
  // check touch state periodically
  unsigned long now = millis();
  if (now - last_touch_check > TOUCH_CHECK_INTERVAL) {
    uint16_t touch_val;
    touch_pad_read(TOUCH_PIN, &touch_val);
    bool touched = touch_val < TOUCH_THRESHOLD;
    
    // detect touch press (not hold)
    if (touched && !last_touch_state) {
      tone_mode = !tone_mode;
      Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic");
      delay(300); // debounce
    }
    
    last_touch_state = touched;
    last_touch_check = now;
  }
  
  // frame buffer
  if (now - last_send < FRAME_INTERVAL) {
    yield();
    return;
  }
  
  uint8_t packet[12 + FRAME_SIZE];
  int16_t samples[FRAME_SIZE];
  
  if (tone_mode) {
    // fixed tone generation with integer phase accumulator
    static uint32_t phase_acc = 0;
    const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE);
    
    for (int i = 0; i < FRAME_SIZE; i++) {
      float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0);
      samples[i] = (int16_t)(16000.0 * sinf(phase));
      phase_acc += phase_inc_int;
    }
    
  } else {
    int32_t mic_buf[FRAME_SIZE];
    size_t bytes_read = 0;
    i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY);

    if (bytes_read != sizeof(mic_buf)) {
      memset(samples, 0, sizeof(samples));
    } else {
      for (int i = 0; i < FRAME_SIZE; i++) {
        float y = (mic_buf[i] >> 16) * MIC_GAIN; //gain
        if (y > 32767.0f) y = 32767.0f;
        if (y < -32768.0f) y = -32768.0f;
        samples[i] = (int16_t)y;
      }
    }
  }
  for (int i = 0; i < FRAME_SIZE; i++) {
    packet[12 + i] = linear2ulaw(samples[i]);
  }

  rtp_hdr* hdr = (rtp_hdr*)packet;
  hdr->vpxcc = 0x80;
  hdr->mpt   = 0x00;
  hdr->seq   = htons(seq++);
  hdr->ts    = htonl(ts);
  hdr->ssrc  = htonl(0x12345678);

  udp.beginPacket(DEST_IP, UDP_PORT);
  udp.write(packet, sizeof(packet));
  udp.endPacket();

  ts += FRAME_SIZE;
  last_send = now;

  yield();
}

optimize:

TODOs

  • add pot knob gain, middle at 4.0f
  • web server interface/config - need to load wifi creds etc

try hardcoded station connect if fail, start softap + web portal from portal, optionally save new ssid/pwd and switch to station mode

webserver

  #include <WiFi.h>
#include <WebServer.h>
#include <Preferences.h>
#include <driver/touch_pad.h>

Preferences prefs;
WebServer server(80);

// touch pad used as boot override / setup trigger
const touch_pad_t touch_pin = TOUCH_PAD_NUM4; // gpio13
const int touch_threshold = 500;

// softap fallback
const char* ap_ssid = "baby-monitor-setup";
const char* ap_password = "setup1234";

// saved / editable config
String wifi_ssid = "";
String wifi_password = "";
String dest_ip_str = "192.168.1.190";
uint16_t udp_port = 5004;

bool config_mode = false;
const unsigned long wifi_connect_timeout_ms = 15000;

String html_escape(const String& s) {
  String out = s;
  out.replace("&", "&amp;");
  out.replace("<", "&lt;");
  out.replace(">", "&gt;");
  out.replace("\"", "&quot;");
  return out;
}

void load_config() {
  prefs.begin("bmcfg", true);
  wifi_ssid = prefs.getString("ssid", "");
  wifi_password = prefs.getString("pwd", "");
  dest_ip_str = prefs.getString("destip", "192.168.1.190");
  udp_port = prefs.getUShort("port", 5004);
  prefs.end();
}

void save_config(const String& ssid, const String& pwd, const String& dest_ip, uint16_t port) {
  prefs.begin("bmcfg", false);
  prefs.putString("ssid", ssid);
  prefs.putString("pwd", pwd);
  prefs.putString("destip", dest_ip);
  prefs.putUShort("port", port);
  prefs.end();
}

void clear_config() {
  prefs.begin("bmcfg", false);
  prefs.clear();
  prefs.end();
}

bool force_setup_requested() {
  // give touch pad a moment to settle
  delay(100);

  uint16_t touch_val = 0;
  touch_pad_read(touch_pin, &touch_val);

  Serial.printf("touch boot check: %u\n", touch_val);
  return touch_val < touch_threshold;
}

void handle_root() {
  String page =
    "<!doctype html>"
    "<html><head>"
    "<meta name='viewport' content='width=device-width,initial-scale=1'>"
    "<title>baby monitor setup</title>"
    "<style>"
    "body{font-family:sans-serif;max-width:520px;margin:2rem auto;padding:0 1rem;}"
    "input{width:100%;padding:.6rem;margin:.2rem 0 1rem 0;box-sizing:border-box;}"
    "button{padding:.7rem 1rem;margin-right:.5rem;}"
    "code{background:#eee;padding:.1rem .3rem;}"
    "</style>"
    "</head><body>"
    "<h2>baby monitor setup</h2>"
    "<p>connect to ap <code>" + String(ap_ssid) + "</code> then browse to <code>192.168.4.1</code>.</p>"
    "<form method='post' action='/save'>"
    "<label>wifi ssid</label>"
    "<input name='ssid' value='" + html_escape(wifi_ssid) + "'>"
    "<label>wifi password</label>"
    "<input name='pwd' type='password' value='" + html_escape(wifi_password) + "'>"
    "<label>destination ip</label>"
    "<input name='destip' value='" + html_escape(dest_ip_str) + "'>"
    "<label>udp port</label>"
    "<input name='port' value='" + String(udp_port) + "'>"
    "<button type='submit'>save and reboot</button>"
    "</form>"
    "<form method='post' action='/clear' onsubmit='return confirm(\"clear saved config?\");'>"
    "<button type='submit'>clear saved config</button>"
    "</form>"
    "<p><a href='/status'>status json</a></p>"
    "</body></html>";

  server.send(200, "text/html", page);
}

void handle_status() {
  String json = "{";
  json += "\"config_mode\":" + String(config_mode ? "true" : "false") + ",";
  json += "\"ap_ssid\":\"" + String(ap_ssid) + "\",";
  json += "\"saved_ssid\":\"" + html_escape(wifi_ssid) + "\",";
  json += "\"dest_ip\":\"" + html_escape(dest_ip_str) + "\",";
  json += "\"udp_port\":" + String(udp_port);
  json += "}";

  server.send(200, "application/json", json);
}

bool valid_ipv4(const String& s) {
  IPAddress ip;
  return ip.fromString(s);
}

void handle_save() {
  String new_ssid = server.arg("ssid");
  String new_pwd = server.arg("pwd");
  String new_dest = server.arg("destip");
  uint16_t new_port = (uint16_t)server.arg("port").toInt();

  if (new_ssid.length() == 0) {
    server.send(400, "text/plain", "ssid required");
    return;
  }

  if (!valid_ipv4(new_dest)) {
    server.send(400, "text/plain", "invalid destination ip");
    return;
  }

  if (new_port == 0) {
    server.send(400, "text/plain", "invalid udp port");
    return;
  }

  save_config(new_ssid, new_pwd, new_dest, new_port);

  server.send(200, "text/html",
    "<html><body><h3>saved. rebooting...</h3></body></html>");
  delay(1000);
  esp_restart();
}

void handle_clear() {
  clear_config();
  server.send(200, "text/html",
    "<html><body><h3>config cleared. rebooting...</h3></body></html>");
  delay(1000);
  esp_restart();
}

void start_config_ap() {
  config_mode = true;

  WiFi.disconnect(true, true);
  delay(250);

  WiFi.mode(WIFI_AP);
  WiFi.softAP(ap_ssid, ap_password);

  IPAddress ip = WiFi.softAPIP();
  Serial.printf("config ap active\n");
  Serial.printf("  ssid: %s\n", ap_ssid);
  Serial.printf("  pass: %s\n", ap_password);
  Serial.printf("  ip:   %s\n", ip.toString().c_str());

  server.on("/", HTTP_GET, handle_root);
  server.on("/save", HTTP_POST, handle_save);
  server.on("/clear", HTTP_POST, handle_clear);
  server.on("/status", HTTP_GET, handle_status);
  server.begin();
}

bool try_connect_wifi() {
  if (wifi_ssid.length() == 0) {
    Serial.println("no saved wifi ssid");
    return false;
  }

  WiFi.disconnect(true, true);
  delay(250);

  WiFi.mode(WIFI_STA);
  WiFi.begin(wifi_ssid.c_str(), wifi_password.c_str());

  Serial.printf("connecting to wifi: %s\n", wifi_ssid.c_str());

  unsigned long start = millis();
  while (WiFi.status() != WL_CONNECTED &&
         millis() - start < wifi_connect_timeout_ms) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  if (WiFi.status() == WL_CONNECTED) {
    Serial.printf("connected\n");
    Serial.printf("  ip: %s\n", WiFi.localIP().toString().c_str());
    Serial.printf("  dest ip: %s\n", dest_ip_str.c_str());
    Serial.printf("  udp port: %u\n", udp_port);
    return true;
  }

  Serial.println("wifi connect failed");
  return false;
}

void setup() {
  Serial.begin(115200);
  delay(200);

  touch_pad_init();
  touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V);
  touch_pad_config(touch_pin, 0);

  load_config();

  if (force_setup_requested()) {
    Serial.println("force setup mode requested");
    start_config_ap();
    return;
  }

  if (!try_connect_wifi()) {
    start_config_ap();
  }
}

void loop() {
  if (config_mode) {
    server.handleClient();
    delay(2);
    return;
  }

  // placeholder for later normal-mode behavior
  static unsigned long last_print = 0;
  if (millis() - last_print > 5000) {
    Serial.printf("normal mode alive. wifi=%s ip=%s dest=%s:%u\n",
      wifi_ssid.c_str(),
      WiFi.localIP().toString().c_str(),
      dest_ip_str.c_str(),
      udp_port);
    last_print = millis();
  }

  delay(10);
}