# 서버 이 폴더는 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