118 lines
3.2 KiB
Markdown
118 lines
3.2 KiB
Markdown
# 클라이언트
|
|
|
|
Orange Pi Zero 2W에서 실행할 USB 마이크 송신기입니다.
|
|
|
|
초기 목표는 USB 마이크 입력을 ALSA로 캡처하고, Mac 수신기로 UDP 패킷을 보내 실제 소리가 나오는지 확인하는 것입니다.
|
|
|
|
## 현재 범위
|
|
|
|
- C++17
|
|
- ALSA 기반 캡처
|
|
- UDP 송신
|
|
- 로컬 WAV 백업 녹음
|
|
- 단일 송신기
|
|
- 무압축 signed 16-bit little endian PCM
|
|
- 설정 파일 기반 Mac 수신기 주소 지정
|
|
|
|
자동 검색, 압축, 다중 송신기, 동기화, 지연 시간 최적화는 이후 단계에서 다룹니다.
|
|
|
|
## 필요 패키지
|
|
|
|
Orange Pi 공식 Debian 12 Bookworm Server 기준으로 다음 패키지가 필요합니다.
|
|
|
|
```bash
|
|
sudo apt update
|
|
sudo apt install build-essential cmake libasound2-dev
|
|
```
|
|
|
|
## 빌드
|
|
|
|
```bash
|
|
cd client
|
|
cmake -S . -B build
|
|
cmake --build build
|
|
```
|
|
|
|
## 설정
|
|
|
|
예시 설정 파일을 복사해서 사용합니다.
|
|
|
|
```bash
|
|
cp client.conf.example client.conf
|
|
```
|
|
|
|
주요 값:
|
|
|
|
```text
|
|
server_host = 192.168.0.10
|
|
server_port = 4860
|
|
alsa_device = default
|
|
sample_rate = 48000
|
|
channels = 1
|
|
frame_ms = 20
|
|
record_enabled = true
|
|
record_dir = recordings
|
|
```
|
|
|
|
`server_host`는 Mac 수신기의 IP 주소로 바꿉니다.
|
|
|
|
초기 버전은 단일 포트 `4860`을 사용합니다. 이후 여러 포트가 필요해지면 `4800-5000` 범위 안에서 배정하는 방향으로 둡니다.
|
|
|
|
`record_enabled`의 기본값은 `true`입니다. 저장 위치는 실행 위치 기준 `recordings/`이며, 클라이언트가 실행될 때마다 새 WAV 파일을 만듭니다.
|
|
|
|
## 실행
|
|
|
|
```bash
|
|
./build/mic-client --config client.conf
|
|
```
|
|
|
|
종료는 `Ctrl+C`로 합니다.
|
|
|
|
## 로컬 녹음
|
|
|
|
클라이언트는 Wi-Fi UDP 송신과 동시에 로컬 WAV 파일을 저장합니다.
|
|
|
|
파일명은 녹음 시작 일자와 실행 시각을 기준으로 자동 생성됩니다.
|
|
|
|
```text
|
|
recordings/mic-client-20260602-165000.wav
|
|
```
|
|
|
|
파일 분할은 하지 않습니다. 클라이언트가 재부팅되거나 재실행되면 새 파일을 만듭니다.
|
|
|
|
녹음 파일 생성, 디렉터리 생성, 파일 쓰기, 종료 시 WAV 헤더 갱신에 실패해도 클라이언트는 종료되지 않습니다. 이 경우 경고를 출력하고 로컬 저장 없이 Wi-Fi 송신을 계속합니다.
|
|
|
|
저장 용량은 `48 kHz / 16-bit / mono` 기준으로 1시간에 약 330 MB입니다.
|
|
|
|
## 마이크 확인
|
|
|
|
Orange Pi에서 USB 마이크 인식 여부를 먼저 확인합니다.
|
|
|
|
```bash
|
|
arecord -l
|
|
arecord -L
|
|
```
|
|
|
|
마이크가 `default`로 바로 잡히지 않으면 `client.conf`의 `alsa_device` 값을 `plughw:CARD,DEV` 또는 `hw:CARD,DEV` 형태로 지정합니다.
|
|
|
|
## 패킷 형식
|
|
|
|
현재 클라이언트는 각 UDP 패킷 앞에 40바이트 헤더를 붙이고, 그 뒤에 PCM payload를 붙입니다.
|
|
|
|
헤더 숫자 값은 network byte order로 전송합니다. PCM payload는 signed 16-bit little endian입니다.
|
|
|
|
```text
|
|
magic 4 bytes "MIC1"
|
|
version u16
|
|
header_size u16
|
|
sequence u64
|
|
timestamp_frames u64
|
|
sample_rate u32
|
|
channels u16
|
|
bits_per_sample u16
|
|
frame_count u32
|
|
payload_bytes u32
|
|
```
|
|
|
|
서버 구현은 이 형식에 맞춰 UDP 패킷을 수신하고 PCM payload를 재생하거나 저장하면 됩니다.
|