112 lines
4.4 KiB
Markdown
112 lines
4.4 KiB
Markdown
# 서버
|
|
|
|
이 폴더는 macOS, Ubuntu, Rocky Linux 9, Windows WSL2에서 실행할 수신기/믹서 서버 소프트웨어를 둘 위치입니다.
|
|
|
|
현재 서버는 Homebrew로 준비한 CMake와 miniaudio를 기준으로 구현합니다.
|
|
|
|
## 초기 목표
|
|
|
|
첫 서버의 목표는 Orange Pi Zero 2W 클라이언트가 보낸 UDP 오디오 패킷을 서버 실행 장비에서 받아 실제 소리로 재생하는 것입니다.
|
|
|
|
초기 성공 기준은 다음과 같습니다.
|
|
|
|
- 지원 OS에서 지정된 UDP 포트를 엽니다.
|
|
- 단일 Orange Pi 클라이언트의 오디오 패킷을 받습니다.
|
|
- 수신 패킷의 sequence와 payload 크기를 확인합니다.
|
|
- PCM 16-bit mono 오디오를 실행 OS의 기본 출력 장치로 재생합니다.
|
|
- 패킷 손실, 순서 역전, 끊김 여부를 로그로 관찰합니다.
|
|
- 송신기별 음량 조절은 초기 범위에서 제외합니다.
|
|
|
|
## 초기 후보
|
|
|
|
```text
|
|
listen_port = 4860
|
|
sample_rate = 48000
|
|
sample_format = signed 16-bit little endian
|
|
channels = 1
|
|
frame_ms = 10
|
|
```
|
|
|
|
초기 프레임 길이는 10 ms를 우선합니다. `48 kHz / 16-bit / mono / 10 ms` 기준 payload는 960바이트라 일반적인 MTU 안에 들어가기 쉽습니다.
|
|
|
|
## 포트 운영 방향
|
|
|
|
초기 서버는 UDP 수신 포트 하나만 사용합니다.
|
|
|
|
마이크가 여러 대가 되더라도 기본 방향은 포트를 마이크 수만큼 나누지 않고, 하나의 포트에서 받은 패킷을 송신기 식별자와 sequence, timestamp로 구분하는 것입니다.
|
|
|
|
마이크별 포트 분리는 별도 서버 프로세스로 디버깅하거나 트래픽을 강하게 분리해야 할 때만 후보로 둡니다.
|
|
|
|
## 오디오 출력 라이브러리 후보
|
|
|
|
- miniaudio
|
|
- Core Audio
|
|
- PortAudio
|
|
- RtAudio
|
|
|
|
현재 우선 후보는 `miniaudio`입니다. macOS와 Linux 계열 환경에서 Homebrew로 설치할 수 있고 초기 재생 경로를 단순하게 만들 수 있기 때문입니다.
|
|
|
|
Homebrew를 개발/실행 준비 기준으로 둡니다. Windows는 네이티브 Windows가 아니라 WSL2 Linux 환경을 사용합니다.
|
|
|
|
## 빌드 준비 후보
|
|
|
|
```bash
|
|
brew install cmake miniaudio
|
|
```
|
|
|
|
WSL2 Ubuntu에서 Homebrew를 처음 설치하는 경우, Homebrew 공식 문서의 Linux/WSL2 안내를 따릅니다. Homebrew 설치 전 기본 개발 도구가 필요할 수 있습니다.
|
|
|
|
## 빌드
|
|
|
|
```bash
|
|
cd server
|
|
cmake -S . -B build -DCMAKE_PREFIX_PATH="$(brew --prefix)"
|
|
cmake --build build
|
|
```
|
|
|
|
## 실행
|
|
|
|
```bash
|
|
./build/mic_server server.conf.example
|
|
```
|
|
|
|
서버는 UDP `4860`을 열고 첫 번째 유효한 `sender_id`를 활성 송신기로 선택합니다. `sender_id`를 고정하고 싶으면 `server.conf.example`의 `sender_id` 값을 1 이상의 값으로 지정합니다.
|
|
|
|
현재 구현은 단일 송신기의 `PCM_S16LE / mono / 48 kHz / 10 ms` payload를 기본 오디오 출력 장치로 재생합니다. 여러 송신기 동시 믹싱과 송신기별 음량 조절은 아직 구현하지 않습니다.
|
|
|
|
Windows에서는 네이티브 Windows 실행이 아니라 WSL2에서 실행합니다. WSL2에서 실제 소리를 들으려면 WSLg 또는 Linux 오디오 출력 경로가 동작해야 합니다.
|
|
|
|
## 패킷 헤더 v1
|
|
|
|
서버가 기대하는 UDP 패킷은 56바이트 헤더와 PCM payload로 구성됩니다. 헤더 정수 필드는 네트워크 바이트 오더를 사용하고, PCM payload는 little endian입니다.
|
|
|
|
```text
|
|
magic u32 "MIC1"
|
|
version u8 1
|
|
header_len u8 56
|
|
packet_type u8 1 = audio
|
|
flags u8 reserved
|
|
sender_id u16 0 reserved, 1..65535
|
|
stream_id u16 initial 0
|
|
session_id u32 random value after sender restart
|
|
sequence u32 increments per sender/session
|
|
capture_sample_index u64 first sample index in this packet
|
|
sender_monotonic_us u64 sender monotonic timestamp
|
|
sample_rate u32 initial 48000
|
|
frame_samples u16 initial 480
|
|
payload_bytes u16 initial 960
|
|
codec_id u8 1 = PCM_S16LE
|
|
sample_format u8 1 = S16LE
|
|
channels u8 initial 1
|
|
channel_layout u8 0 = mono/default
|
|
header_crc32 u32 0 allowed in initial implementation
|
|
reserved u32 future use
|
|
```
|
|
|
|
## 관련 문서
|
|
|
|
- `../docs/03-server-direction.md`: 서버 수신/믹서 초기 방향성
|
|
- `../docs/02-client-direction.md`: Orange Pi 클라이언트 초기 방향성
|
|
- https://docs.brew.sh/Homebrew-on-Linux
|
|
- https://formulae.brew.sh/formula/miniaudio
|