From 930fa5e62b924b66bee881070fd9619994da202d Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Fri, 24 Apr 2015 06:41:32 +0000 Subject: Tox: work commit git-svn-id: http://svn.miranda-ng.org/main/trunk@13061 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Tox/src/common.h | 3 + protocols/Tox/src/tox_icons.cpp | 11 ++- protocols/Tox/src/tox_menus.cpp | 3 +- protocols/Tox/src/tox_multimedia.cpp | 159 +++++++++++++++++++---------------- protocols/Tox/src/tox_proto.h | 4 + 5 files changed, 105 insertions(+), 75 deletions(-) (limited to 'protocols/Tox/src') diff --git a/protocols/Tox/src/common.h b/protocols/Tox/src/common.h index 75c1e48f58..a470d0ae10 100644 --- a/protocols/Tox/src/common.h +++ b/protocols/Tox/src/common.h @@ -6,9 +6,12 @@ #include #include +#include + #include #include #include +#include #include #include diff --git a/protocols/Tox/src/tox_icons.cpp b/protocols/Tox/src/tox_icons.cpp index 5600283ae0..e01c39ff97 100644 --- a/protocols/Tox/src/tox_icons.cpp +++ b/protocols/Tox/src/tox_icons.cpp @@ -34,13 +34,22 @@ void CToxProto::InitIcons() } } +HICON CToxProto::GetIcon(const char *name, int size) +{ + for (size_t i = 0; i < SIZEOF(Icons); i++) + if (mir_strcmpi(Icons[i].Name, name) == 0) + return Skin_GetIconByHandle(Icons[i].Handle, size); + + return NULL; +} + HANDLE CToxProto::GetIconHandle(const char *name) { for (size_t i = 0; i < SIZEOF(Icons); i++) if (mir_strcmpi(Icons[i].Name, name) == 0) return Icons[i].Handle; - return 0; + return NULL; } HANDLE CToxProto::GetSkinIconHandle(const char *name) diff --git a/protocols/Tox/src/tox_menus.cpp b/protocols/Tox/src/tox_menus.cpp index 4820a2acd3..aec9a4b1eb 100644 --- a/protocols/Tox/src/tox_menus.cpp +++ b/protocols/Tox/src/tox_menus.cpp @@ -23,7 +23,8 @@ int CToxProto::OnPrebuildContactMenu(WPARAM hContact, LPARAM) Menu_ShowItem(ContactMenuItems[CMI_AUTH_REQUEST], isCtrlPressed || isAuthNeed); Menu_ShowItem(ContactMenuItems[CMI_AUTH_GRANT], isCtrlPressed || isGrantNeed); - Menu_ShowItem(ContactMenuItems[CMI_AUDIO_CALL], TRUE); + bool isContactOnline = GetContactStatus(hContact) > ID_STATUS_OFFLINE; + Menu_ShowItem(ContactMenuItems[CMI_AUDIO_CALL], isContactOnline); return 0; } diff --git a/protocols/Tox/src/tox_multimedia.cpp b/protocols/Tox/src/tox_multimedia.cpp index 1833a3c953..729a75f17f 100644 --- a/protocols/Tox/src/tox_multimedia.cpp +++ b/protocols/Tox/src/tox_multimedia.cpp @@ -3,9 +3,9 @@ /* AUDIO RECEIVING */ CToxAudioCall::CToxAudioCall(CToxProto *proto, MCONTACT hContact) : - CToxDlgBase(proto, IDD_AUDIO, false), - hContact(hContact), isCallStarted(false), - ok(this, IDOK), cancel(this, IDCANCEL) +CToxDlgBase(proto, IDD_AUDIO, false), +hContact(hContact), isCallStarted(false), +ok(this, IDOK), cancel(this, IDCANCEL) { m_autoClose = CLOSE_ON_CANCEL; ok.OnClick = Callback(this, &CToxAudioCall::OnOk); @@ -73,46 +73,46 @@ ToxAvCSettings* CToxProto::GetAudioCSettings() } cSettings->audio_channels = wic.wChannels; - if ((wic.dwFormats & WAVE_FORMAT_96S16) || (wic.dwFormats & WAVE_FORMAT_96M16)) + if ((wic.dwFormats & WAVE_FORMAT_48S16) || (wic.dwFormats & WAVE_FORMAT_48M16)) { cSettings->audio_bitrate = 16 * 1000; cSettings->audio_sample_rate = 48000; } - else if ((wic.dwFormats & WAVE_FORMAT_96S08) || (wic.dwFormats & WAVE_FORMAT_96M08)) + else if ((wic.dwFormats & WAVE_FORMAT_48S08) || (wic.dwFormats & WAVE_FORMAT_48M08)) { cSettings->audio_bitrate = 8 * 1000; cSettings->audio_sample_rate = 48000; } - else if ((wic.dwFormats & WAVE_FORMAT_4S16) || (wic.dwFormats & WAVE_FORMAT_4M16)) + /*else if ((wic.dwFormats & WAVE_FORMAT_4S16) || (wic.dwFormats & WAVE_FORMAT_4M16)) { - cSettings->audio_bitrate = 16 * 1000; - cSettings->audio_sample_rate = 24000; + cSettings->audio_bitrate = 16 * 1000; + cSettings->audio_sample_rate = 24000; } else if ((wic.dwFormats & WAVE_FORMAT_4S08) || (wic.dwFormats & WAVE_FORMAT_4S08)) { - cSettings->audio_bitrate = 8 * 1000; - cSettings->audio_sample_rate = 24000; + cSettings->audio_bitrate = 8 * 1000; + cSettings->audio_sample_rate = 24000; } else if ((wic.dwFormats & WAVE_FORMAT_2M16) || (wic.dwFormats & WAVE_FORMAT_2S16)) { - cSettings->audio_bitrate = 16 * 1000; - cSettings->audio_sample_rate = 16000; + cSettings->audio_bitrate = 16 * 1000; + cSettings->audio_sample_rate = 16000; } else if ((wic.dwFormats & WAVE_FORMAT_2M08) || (wic.dwFormats & WAVE_FORMAT_2S08)) { - cSettings->audio_bitrate = 8 * 1000; - cSettings->audio_sample_rate = 16000; + cSettings->audio_bitrate = 8 * 1000; + cSettings->audio_sample_rate = 16000; } else if ((wic.dwFormats & WAVE_FORMAT_1M16) || (wic.dwFormats & WAVE_FORMAT_1S16)) { - cSettings->audio_bitrate = 16 * 1000; - cSettings->audio_sample_rate = 8000; + cSettings->audio_bitrate = 16 * 1000; + cSettings->audio_sample_rate = 8000; } else if ((wic.dwFormats & WAVE_FORMAT_1M08) || (wic.dwFormats & WAVE_FORMAT_1S08)) { - cSettings->audio_bitrate = 8 * 1000; - cSettings->audio_sample_rate = 8000; - } + cSettings->audio_bitrate = 8 * 1000; + cSettings->audio_sample_rate = 8000; + }*/ else { debugLogA(__FUNCTION__": failed to parse input device caps"); @@ -126,7 +126,7 @@ ToxAvCSettings* CToxProto::GetAudioCSettings() // incoming call flow CToxIncomingAudioCall::CToxIncomingAudioCall(CToxProto *proto, MCONTACT hContact) : - CToxAudioCall(proto, hContact) +CToxAudioCall(proto, hContact) { } @@ -293,7 +293,7 @@ void CToxProto::OnAvCancel(void*, int32_t callId, void *arg) // outcoming audio flow CToxOutgoingAudioCall::CToxOutgoingAudioCall(CToxProto *proto, MCONTACT hContact) : - CToxAudioCall(proto, hContact) +CToxAudioCall(proto, hContact) { } @@ -431,6 +431,46 @@ void CToxProto::OnAvStart(void*, int32_t callId, void *arg) { CToxProto *proto = (CToxProto*)arg; + ToxAvCSettings cSettings; + int cSettingsError = toxav_get_peer_csettings(proto->toxAv, callId, 0, &cSettings); + if (cSettingsError != av_ErrorNone) + { + proto->debugLogA(__FUNCTION__": failed to get codec settings (%d)", cSettingsError); + toxav_hangup(proto->toxAv, callId); + return; + } + + if (cSettings.call_type != av_TypeAudio) + { + proto->debugLogA(__FUNCTION__": video call is unsupported"); + toxav_hangup(proto->toxAv, callId); + return; + } + + WAVEFORMATEX wfx = { 0 }; + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.nChannels = cSettings.audio_channels; + wfx.wBitsPerSample = cSettings.audio_bitrate / 1000; + wfx.nSamplesPerSec = cSettings.audio_sample_rate; + wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + + DWORD deviceId = proto->getDword("AudioOutputDeviceID", WAVE_MAPPER); + MMRESULT error = waveOutOpen(&proto->hOutDevice, deviceId, &wfx, (DWORD_PTR)&CToxProto::WaveOutCallback, (DWORD_PTR)proto, CALLBACK_FUNCTION); + if (error != MMSYSERR_NOERROR) + { + proto->debugLogA(__FUNCTION__": failed to open audio device (%d)", error); + toxav_hangup(proto->toxAv, callId); + + TCHAR errorMessage[MAX_PATH]; + waveInGetErrorText(error, errorMessage, SIZEOF(errorMessage)); + CToxProto::ShowNotification( + TranslateT("Unable to find output audio device"), + errorMessage); + + return; + } + int friendNumber = toxav_get_peer_id(proto->toxAv, callId, 0); if (friendNumber == TOX_ERROR) { @@ -447,9 +487,9 @@ void CToxProto::OnAvStart(void*, int32_t callId, void *arg) return; } - HWND hwnd = WindowList_Find(proto->hAudioDialogs, hContact); - CToxAudioCall *audioCall = (CToxAudioCall*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - audioCall->OnStartCall(); + //HWND hwnd = WindowList_Find(proto->hAudioDialogs, hContact); + //CToxAudioCall *audioCall = (CToxAudioCall*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + //audioCall->OnStartCall(); char *message = mir_utf8encodeT(TranslateT("Call started")); @@ -474,6 +514,7 @@ void CToxProto::OnAvEnd(void*, int32_t callId, void *arg) { CToxProto *proto = (CToxProto*)arg; + waveOutClose(proto->hOutDevice); toxav_kill_transmission(proto->toxAv, callId); int friendNumber = toxav_get_peer_id(proto->toxAv, callId, 0); @@ -489,7 +530,7 @@ void CToxProto::OnAvEnd(void*, int32_t callId, void *arg) proto->debugLogA(__FUNCTION__": failed to find contact"); return; } - + char *message = mir_utf8encodeT(TranslateT("Call ended")); DBEVENTINFO dbei = { sizeof(dbei) }; @@ -546,71 +587,43 @@ 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) +void CToxProto::WaveOutCallback(HWAVEOUT m_hWO, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { - CToxProto *proto = (CToxProto*)arg; - - ToxAvCSettings cSettings; - int cSettingsError = toxav_get_peer_csettings(proto->toxAv, callId, 0, &cSettings); - if (cSettingsError != av_ErrorNone) + CToxProto *proto = (CToxProto*)dwInstance; + switch (uMsg) { - proto->debugLogA(__FUNCTION__": failed to get codec settings (%d)", cSettingsError); - return; - } - - if (cSettings.call_type != av_TypeAudio) + case WOM_DONE: { - proto->debugLogA(__FUNCTION__": video call is unsupported"); - return; + WAVEHDR *header = (WAVEHDR*)dwParam1; + if (header->dwFlags & WHDR_PREPARED) + waveOutUnprepareHeader(proto->hOutDevice, header, sizeof(WAVEHDR)); + mir_free(header->lpData); + mir_free(header); } - - WAVEFORMATEX wfx = { 0 }; - wfx.wFormatTag = WAVE_FORMAT_PCM; - wfx.nChannels = cSettings.audio_channels; - wfx.wBitsPerSample = cSettings.audio_bitrate / 1000; - wfx.nSamplesPerSec = cSettings.audio_sample_rate; - wfx.nBlockAlign = (wfx.nChannels * wfx.wBitsPerSample) / 8; - wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; - - DWORD deviceId = proto->getDword("AudioOutputDeviceID", WAVE_MAPPER); - - HWAVEOUT hDevice; - MMRESULT error = waveOutOpen(&hDevice, deviceId, &wfx, 0, 0, CALLBACK_NULL); - if (error != MMSYSERR_NOERROR) - { - proto->debugLogA(__FUNCTION__": failed to open audio device (%d)", error); - - TCHAR errorMessage[MAX_PATH]; - waveInGetErrorText(error, errorMessage, SIZEOF(errorMessage)); - CToxProto::ShowNotification( - TranslateT("Unable to find output audio device"), - errorMessage); - - return; + break; } +} - WAVEHDR header = { 0 }; - header.lpData = (LPSTR)PCM; - header.dwBufferLength = size * wfx.nChannels * sizeof(int16_t); +void CToxProto::OnFriendAudio(void*, int32_t callId, const int16_t *PCM, uint16_t size, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; - waveOutSetVolume(hDevice, 0xFFFF); + WAVEHDR *header = (WAVEHDR*)mir_calloc(sizeof(WAVEHDR)); + header->dwBufferLength = size * sizeof(int16_t); + header->lpData = (LPSTR)mir_alloc(header->dwBufferLength); + memcpy(header->lpData, (PBYTE)PCM, header->dwBufferLength); - error = waveOutPrepareHeader(hDevice, &header, sizeof(WAVEHDR)); + MMRESULT error = waveOutPrepareHeader(proto->hOutDevice, header, sizeof(WAVEHDR)); if (error != MMSYSERR_NOERROR) { proto->debugLogA(__FUNCTION__": failed to prepare audio buffer (%d)", error); return; } - error = waveOutWrite(hDevice, &header, sizeof(WAVEHDR)); + error = waveOutWrite(proto->hOutDevice, header, sizeof(WAVEHDR)); if (error != MMSYSERR_NOERROR) { proto->debugLogA(__FUNCTION__": failed to play audio samples (%d)", error); return; } - - while (waveOutUnprepareHeader(hDevice, &header, sizeof(WAVEHDR)) == WAVERR_STILLPLAYING) - Sleep(10); - - waveOutClose(hDevice); } \ No newline at end of file diff --git a/protocols/Tox/src/tox_proto.h b/protocols/Tox/src/tox_proto.h index a806555cb8..2f15e16477 100644 --- a/protocols/Tox/src/tox_proto.h +++ b/protocols/Tox/src/tox_proto.h @@ -122,6 +122,7 @@ private: // icons static IconInfo Icons[]; + static HICON GetIcon(const char *name, int size = 0); static HANDLE GetIconHandle(const char *name); static HANDLE GetSkinIconHandle(const char *name); @@ -243,8 +244,11 @@ private: // multimedia HANDLE hAudioDialogs; + HWAVEOUT hOutDevice; std::map calls; + static void CALLBACK WaveOutCallback(HWAVEOUT m_hWO, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); + ToxAvCSettings* GetAudioCSettings(); static void OnFriendAudio(void *agent, int32_t callId, const int16_t *PCM, uint16_t size, void *arg); -- cgit v1.2.3