
I2S MEMS MIC(ICS-43434) 테스트 코드를 이용해 마이크 음성 신호를 UDP로 방송할 수 있는 네트웍 마이크를 제작해 보자.
스위치1을 누르면 기존과 같이 보드의 스피커로 출력 스위치 2를 누르면 네트웍으로 전송하는 코드를 작성했다.
UDP 수신은 기존 네트웍 스피커 코드와 동일하고 마이크 음성 송신은 별도의 소켓을 생성해서 처리 하도록 했다.
이렇게 하면 수신하면서 송신이 가능한 구조가 될 수 있다.
void process_audio_tx() {
switch (getSn_SR(SOCK_UDP_TX)) {
case SOCK_UDP:
gpio_put(LED_PIN2, 1);
int buf_idx = 0;
for (uint i = 0; i < TX_SAMPLE_COUNT; i++) {
uint32_t packet = pio_sm_get_blocking(pio_rx, sm_rx);
int16_t left = (int16_t)(packet >> 16);
int16_t right = (int16_t)(packet & 0xFFFF);
tx_buf[buf_idx + 0] = left & 0xFF;
tx_buf[buf_idx + 1] = (left >> 8) & 0xFF;
tx_buf[buf_idx + 2] = right & 0xFF;
tx_buf[buf_idx + 3] = (right >> 8) & 0xFF;
buf_idx += 4;
}
int32_t len = sendto(SOCK_UDP_TX, tx_buf, TX_BUF_SIZE, target_ip, target_port);
if (len < 0) {
printf("⚠️ UDP send error: %d\n", len);
}
break;
case SOCK_CLOSED:
if (socket(SOCK_UDP_TX, Sn_MR_UDP, 0, 0x00) == SOCK_UDP_TX) {
printf("UDP TX (Broadcast) Socket Opened.\n");
}
break;
default:
break;
}
}
main 함수는 스위치 눌렀을때 I2S 마이크 신호를 전송하고 버튼을 누르지 않으면 기존 코드와 같이 수신 받은 음성을 스피커로 출력 하도록 했다.
while (true) {
// 버튼 2번이 눌려 있으면 방송(송신) 프로세스 작동
if (gpio_get(BUTTON_PIN2) == 0) {
// 내가 송신하는 도중에 수신 소켓에 쌓이는 패킷이 있다면
// 버튼을 뗐을 때 하울링이나 지연이 발생하므로 미리미리 비워줍니다.
if (getSn_RX_RSR(SOCK_UDP_RX) > 0) {
uint8_t dump_ip[4]; uint16_t dump_port;
recvfrom(SOCK_UDP_RX, rx_buf, RX_BUF_SIZE, dump_ip, &dump_port);
}
// 송신 함수 독립 호출
process_audio_tx();
// 방송 직후에는 수신 타임아웃을 초기화하여 매끄럽게 수신 전환 유도
last_recv_time = to_ms_since_boot(get_absolute_time());
}
// 버튼을 떼면 평소대로 수신 프로세스 작동
else {
// 수신 함수 독립 호출
process_audio_rx(producer_pool, volume);
}
}
return 0;
}
동작 테스트는 기존에 제작했던 네트웍 스피커를 이용하거나 PC에 간단히 파이썬 스크립터로 UDP로 수신한 음성을 출력 하도록 할 수 있다.
W55RP20 UDP 네트웍 마이크 테스트 동영상
스위치1을 누르면 자신의 스피커로 마이크 입력 신호를 출력하고 스위치 2를 누르면 PC 서버로 전송해서 녹음을 하며 녹음된 WAV파일을 다시 스피커로 출력하는 테스트
테스트용 PC프로그램
