5.4 KiB
서버
이 폴더는 macOS, Ubuntu, Rocky Linux 9, Windows WSL2에서 실행할 수신기/믹서 서버 소프트웨어를 둘 위치입니다.
현재 서버는 Homebrew로 준비한 CMake와 miniaudio를 기준으로 구현합니다.
초기 목표
첫 서버의 목표는 Orange Pi Zero 2W 클라이언트가 보낸 UDP 오디오 패킷을 서버 실행 장비에서 받아 실제 소리로 재생하는 것입니다. 첫 bring-up은 송신기 1대로 진행하지만, 실제 목표 규모는 최소 2대에서 최대 16대입니다.
초기 성공 기준은 다음과 같습니다.
- 지원 OS에서 지정된 UDP 포트를 엽니다.
- 단일 Orange Pi 클라이언트의 오디오 패킷을 먼저 받습니다.
- 수신 패킷의 sequence와 payload 크기를 확인합니다.
- PCM 16-bit mono 오디오를 실행 OS의 기본 출력 장치로 재생합니다.
- 패킷 손실, 순서 역전, 끊김 여부를 로그로 관찰합니다.
- 이후 2대, 4대, 8대, 16대 순서로 송신기 수를 늘려 동시 수신과 믹싱을 검증합니다.
- 송신기별 음량 조절은 초기 범위에서 제외합니다.
초기 후보
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로 구분하는 것입니다.
마이크별 포트 분리는 별도 서버 프로세스로 디버깅하거나 트래픽을 강하게 분리해야 할 때만 후보로 둡니다.
목표 송신기 규모
현재 목표는 최소 2대, 최대 16대 송신기입니다.
초기 무압축 포맷인 48 kHz / 16-bit / mono / 10 ms 기준으로 송신기 1대는 UDP/IP 포함 대략 0.8 Mbps 이상을 사용합니다. 16대는 단순 계산으로 13 Mbps 이상입니다. 권장 네트워크는 2.4 GHz Wi-Fi이며, 실제 환경에서는 MAC 오버헤드, 주변 간섭, 재전송, airtime 경쟁 때문에 단순 대역폭 계산보다 보수적으로 검증해야 합니다.
따라서 다중 송신기 검증은 2.4 GHz Wi-Fi 기준으로 진행하고, 2대, 4대, 8대, 16대 순서로 패킷 손실, 순서 역전, 지터 버퍼 underflow와 overflow를 확인합니다.
오디오 출력 라이브러리 후보
- miniaudio
- Core Audio
- PortAudio
- RtAudio
현재 우선 후보는 miniaudio입니다. macOS와 Linux 계열 환경에서 Homebrew로 설치할 수 있고 초기 재생 경로를 단순하게 만들 수 있기 때문입니다.
Homebrew를 개발/실행 준비 기준으로 둡니다. Windows는 네이티브 Windows가 아니라 WSL2 Linux 환경을 사용합니다.
빌드 준비 후보
brew install cmake miniaudio
WSL2 Ubuntu에서 Homebrew를 처음 설치하는 경우, Homebrew 공식 문서의 Linux/WSL2 안내를 따릅니다. Homebrew 설치 전 기본 개발 도구가 필요할 수 있습니다.
빌드
cd server
cmake -S . -B build -DCMAKE_PREFIX_PATH="$(brew --prefix)"
cmake --build build
실행
./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를 기본 오디오 출력 장치로 재생합니다. 목표 규모는 2대에서 16대이지만, 여러 송신기 동시 믹싱과 송신기별 음량 조절은 아직 구현하지 않습니다.
Windows에서는 네이티브 Windows 실행이 아니라 WSL2에서 실행합니다. WSL2에서 실제 소리를 들으려면 WSLg 또는 Linux 오디오 출력 경로가 동작해야 합니다.
패킷 헤더 v1
서버가 기대하는 UDP 패킷은 56바이트 헤더와 PCM payload로 구성됩니다. 헤더 정수 필드는 네트워크 바이트 오더를 사용하고, PCM payload는 little endian입니다.
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