본문 바로가기
programing/C++

음성 채팅 구현

by RedWiz 2017. 1. 20.

1. 마이크를 사용하여 녹음

- mmsystem.h 에 녹음 및 사운드 출력 이용

- directx sound를 사용해도 무방


- portaudio를 이용하면 편하다.


2. 음성 압축 코덱으로 인코딩

- 대충 찾아보니

> G.723.1, G.729.A, GSM610, True Speech, PCM (LAN or High speed network area)

> 유료 코덱을 쓰기엔...

> PCM은 일반적으로 로컬에서 많이 사용되기 때문에 음질을 고수준으로 올릴 필요 있음


- speex

> http://www.speex.org/ : BSD 라이센스


- Opus

> speex 보다 좋다고 한다.


cf. 음성데이터를 인코딩, 디코딩 하기 위해선 어느정도 음성 데이터 지식이 필요


- 음성 데이터 추출시

데이터 = 채널수 * 버퍼당 프레임수, 왼쪽 오른쪽 교차로 순차 기록


- PCM(Pulse Code Modulation) : 펄스 코드 변조
- Frame      : Sample로 그려진 소스
- Sample      : 표본
- Sampling     : 표본 추출
- SamplingRate    : 표본 추출의 밀도


3. RTP / RTCP 프로토콜 전송

- Real-time_Transport_Protocol

- 다른 APP 과 호환성에 중점을 두지 않은 다면 UDP

- RTP/RTCP는 음질개선 측면 보다는 안정성이 강조 되어 트래픽을 증가함

> G.723.1, G.729A 코덱의 경우 30ms, 20ms의 패킷을 날리므로 패킷의 오버헤드가 커짐 -_-)

> SIP, H.323등과 같은 Internet Telephony에 사용되는 프로토콜에서 RTP/RTCP를 사용시 Bandwidth가 원하는 크기만큼 보장되지 않으면 UDP에 비하여 RTP/RTCP의 음질이 더 떨어짐

- RTP/RTCP를 사용하는 이유

> 통화중에라도 코덱을 변경할 수 있도록 지원 가능

> Proxy등을 이용하여 전송 경로를 임의로 변경하여 media convert server를 거치도록 할 수 있음


4. 버퍼링

- 음성 재생시 끊어지는 문제는 버퍼링과 재생 딜레이에 관한 부분

- 인터넷을 날아다니는 패킷이 항상 같은 경로로 가는 것이 아니기 때문에 복잡하게 딜레이 발생

- 지터 : 딜레이와 딜레이 사이의 차이값, 지터가 일정하지 못하면 안정적이지 못한 네트워크

- 버퍼링은 가능하면 딜레이가 200ms - 500ms 안쪽으로 잡는 것이 좋음

- 500ms가 넘어가면 대화가 힘들어짐

- RTP/RTCP는 버퍼링을 유동적으로 변경 가능

> 네트워크 속도가 빠르면 버퍼링을 줄이고, 네트워크 속도가 느리면 버퍼링을 좀 늘리고

- 코덱에서 지원하는 프레임을 몇 ms로 지원하는 지 중요한데 MFC는 18ms 이하로 정확히 타이머 처리가 되지 않음

- 그래서 MFC에서 제공하는 멀티미디어 타이머를 사용하는 것이 더 정확한 시간 처리해서 좋음

- 윈도우 스레드에 밀리면 타이머도 같이 밀리기 때문에 이벤트가 죽는 수가 있어서 스레드 순위를 올리는 것이 좋음 (스레드 순위가 높다고 해서 마냥 높은 것은 아님)

- 그래서 다른 상용화 프로토콜들은 RTP/RTCP를 디바이스로 만들어 Ring 0에 올리는 경우가 종종 있음


5. 음성 압축 코덱 디코딩


6. 사운드 출력


cf. 걍 속편하게 음성 채팅 서버 + 클라 해보고 싶으면

- mumble

- asterisk + freepbx (리눅스...)


참고 : http://cluster1.cafe.daum.net/_c21_/bbs_search_read?grpid=zn2v&fldid=3NjT&datanum=5&openArticle=true&docid=zn2v3NjT520050629163511