diff options
author | Alexander Lantsev <aunsane@gmail.com> | 2015-04-14 17:55:10 +0000 |
---|---|---|
committer | Alexander Lantsev <aunsane@gmail.com> | 2015-04-14 17:55:10 +0000 |
commit | 5da95c8f396b7ac716f7ea61c9d8c5a0eee7e1ec (patch) | |
tree | 6e1417af1fd835fc5998b1558cf4c26d3c908285 /protocols/Tox/src/tox_multimedia.cpp | |
parent | a216cdaab245e00627e69726d1d65d06e91f03f9 (diff) |
Tox: first approach for audio support
git-svn-id: http://svn.miranda-ng.org/main/trunk@12824 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/Tox/src/tox_multimedia.cpp')
-rw-r--r-- | protocols/Tox/src/tox_multimedia.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/protocols/Tox/src/tox_multimedia.cpp b/protocols/Tox/src/tox_multimedia.cpp new file mode 100644 index 0000000000..214f35f8d0 --- /dev/null +++ b/protocols/Tox/src/tox_multimedia.cpp @@ -0,0 +1,92 @@ +#include "common.h"
+
+void CToxProto::OnAvInvite(void*, int32_t callId, void *arg) { }
+void CToxProto::OnAvRinging(void*, int32_t callId, void *arg) { }
+void CToxProto::OnAvStart(void*, int32_t callId, void *arg) { }
+void CToxProto::OnAvEnd(void*, int32_t callId, void *arg) { }
+void CToxProto::OnAvReject(void*, int32_t callId, void *arg) { }
+void CToxProto::OnAvCancel(void*, int32_t callId, void *arg) { }
+void CToxProto::OnAvCsChange(void*, int32_t callId, void *arg) { }
+void CToxProto::OnAvRequestTimeout(void*, int32_t callId, void *arg) { }
+void CToxProto::OnAvPeerTimeout(void*, int32_t callId, void *arg) { }
+
+void CToxProto::OnFriendAudio(void*, int32_t callId, const int16_t *PCM, uint16_t size, void *arg)
+{
+ CToxProto *proto = (CToxProto*)arg;
+
+ ToxAvCSettings dest;
+ if (toxav_get_peer_csettings(proto->toxAv, callId, 0, &dest) != av_ErrorNone)
+ {
+ proto->debugLogA(__FUNCTION__": failed to get codec settings");
+ toxav_stop_call(proto->toxAv, callId);
+ return;
+ }
+
+ if (dest.call_type != av_TypeAudio)
+ {
+ proto->debugLogA(__FUNCTION__": failed to play video");
+ toxav_stop_call(proto->toxAv, callId);
+ return;
+ }
+
+ WAVEFORMATEX wfx = { 0 };
+ wfx.wFormatTag = WAVE_FORMAT_PCM;
+ wfx.nChannels = dest.audio_channels;
+ wfx.wBitsPerSample = dest.audio_bitrate;
+ wfx.nSamplesPerSec = dest.audio_sample_rate;
+ wfx.nBlockAlign = (wfx.nChannels * wfx.wBitsPerSample) / 8;
+ wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
+
+ DWORD deviceId = proto->getDword("AudioOutputDeviceID", -1);
+ if (deviceId != av_ErrorNone)
+ {
+ proto->debugLogA(__FUNCTION__": failed to get device id");
+ toxav_stop_call(proto->toxAv, callId);
+ return;
+ }
+
+ HWAVEOUT hDevice;
+ MMRESULT result = waveOutOpen(&hDevice, deviceId, &wfx, 0, 0, CALLBACK_NULL | WAVE_FORMAT_DIRECT);
+ if (result != MMSYSERR_NOERROR)
+ {
+ proto->debugLogA(__FUNCTION__": failed to open audio device");
+ toxav_stop_call(proto->toxAv, callId);
+ return;
+ }
+
+ WAVEHDR header;// = { 0 };
+ ZeroMemory(&header, sizeof(WAVEHDR));
+ header.lpData = (LPSTR)PCM;
+ header.dwBufferLength = size;
+
+ result = waveOutPrepareHeader(hDevice, &header, sizeof(WAVEHDR));
+ if (result != MMSYSERR_NOERROR)
+ {
+ proto->debugLogA(__FUNCTION__": failed to prepare audio device header");
+ toxav_stop_call(proto->toxAv, callId);
+ return;
+ }
+
+ result = waveOutWrite(hDevice, &header, sizeof(WAVEHDR));
+ if (result != MMSYSERR_NOERROR)
+ {
+ proto->debugLogA(__FUNCTION__": failed to write to audio device");
+ toxav_stop_call(proto->toxAv, callId);
+ return;
+ }
+
+ do
+ {
+ Sleep(100);
+ result = waveOutUnprepareHeader(hDevice, &header, sizeof(WAVEHDR));
+ } while (result == WAVERR_STILLPLAYING);
+
+ if (result != MMSYSERR_NOERROR)
+ {
+ proto->debugLogA(__FUNCTION__": failed to unprepare audio device header");
+ toxav_stop_call(proto->toxAv, callId);
+ return;
+ }
+
+ waveOutClose(hDevice);
+}
\ No newline at end of file |