From 59a975bf66c19ebddd8c82d9d501fddc02584d7c Mon Sep 17 00:00:00 2001 From: Grishka Date: Mon, 31 Dec 2018 04:05:58 +0300 Subject: [PATCH] Fixes --- EchoCanceller.h | 2 +- OpusEncoder.cpp | 1 + os/linux/AudioInputPulse.cpp | 52 ++++++++++++++++++++------------ os/linux/AudioInputPulse.h | 1 + os/linux/AudioOutputPulse.cpp | 41 ++++++++++++++----------- os/linux/AudioOutputPulse.h | 1 + os/windows/AudioInputWASAPI.cpp | 8 +++-- os/windows/AudioInputWASAPI.h | 4 +-- os/windows/AudioOutputWASAPI.cpp | 8 +++-- os/windows/AudioOutputWASAPI.h | 4 +-- 10 files changed, 76 insertions(+), 46 deletions(-) diff --git a/EchoCanceller.h b/EchoCanceller.h index e684ba051b..5f26e1aeb9 100755 --- a/EchoCanceller.h +++ b/EchoCanceller.h @@ -59,7 +59,7 @@ public: virtual void Process(int16_t* inOut, size_t numSamples)=0; virtual void SetPassThrough(bool passThrough); protected: - bool passThrough; + bool passThrough=false; }; class Volume : public AudioEffect{ diff --git a/OpusEncoder.cpp b/OpusEncoder.cpp index 0eb50b61bd..cf665900d2 100755 --- a/OpusEncoder.cpp +++ b/OpusEncoder.cpp @@ -6,6 +6,7 @@ #include "OpusEncoder.h" #include +#include #include "logging.h" #include "VoIPServerConfig.h" #ifdef HAVE_CONFIG_H diff --git a/os/linux/AudioInputPulse.cpp b/os/linux/AudioInputPulse.cpp index e9b7a4f688..be7366b260 100644 --- a/os/linux/AudioInputPulse.cpp +++ b/os/linux/AudioInputPulse.cpp @@ -33,25 +33,13 @@ AudioInputPulse::AudioInputPulse(pa_context* context, pa_threaded_mainloop* main remainingDataSize=0; pa_threaded_mainloop_lock(mainloop); - pa_sample_spec sample_specifications{ - .format=PA_SAMPLE_S16LE, - .rate=48000, - .channels=1 - }; - pa_proplist* proplist=pa_proplist_new(); - pa_proplist_sets(proplist, PA_PROP_FILTER_APPLY, ""); // according to PA sources, this disables any possible filters - stream=pa_stream_new_with_proplist(context, "libtgvoip capture", &sample_specifications, NULL, proplist); - pa_proplist_free(proplist); - if(!stream){ - LOGE("Error initializing PulseAudio (pa_stream_new)"); - failed=true; - return; - } - pa_stream_set_state_callback(stream, AudioInputPulse::StreamStateCallback, this); - pa_stream_set_read_callback(stream, AudioInputPulse::StreamReadCallback, this); + stream=CreateAndInitStream(); pa_threaded_mainloop_unlock(mainloop); isLocked=false; + if(!stream){ + return; + } SetCurrentDevice(devID); } @@ -63,6 +51,26 @@ AudioInputPulse::~AudioInputPulse(){ } } +pa_stream* AudioInputPulse::CreateAndInitStream(){ + pa_sample_spec sampleSpec{ + .format=PA_SAMPLE_S16LE, + .rate=48000, + .channels=1 + }; + pa_proplist* proplist=pa_proplist_new(); + pa_proplist_sets(proplist, PA_PROP_FILTER_APPLY, ""); // according to PA sources, this disables any possible filters + pa_stream* stream=pa_stream_new_with_proplist(context, "libtgvoip capture", &sampleSpec, NULL, proplist); + pa_proplist_free(proplist); + if(!stream){ + LOGE("Error initializing PulseAudio (pa_stream_new)"); + failed=true; + return NULL; + } + pa_stream_set_state_callback(stream, AudioInputPulse::StreamStateCallback, this); + pa_stream_set_read_callback(stream, AudioInputPulse::StreamReadCallback, this); + return stream; +} + void AudioInputPulse::Start(){ if(failed || isRecording) return; @@ -92,7 +100,9 @@ void AudioInputPulse::SetCurrentDevice(std::string devID){ currentDevice=devID; if(isRecording && isConnected){ pa_stream_disconnect(stream); + pa_stream_unref(stream); isConnected=false; + stream=CreateAndInitStream(); } pa_buffer_attr bufferAttr={ @@ -105,9 +115,12 @@ void AudioInputPulse::SetCurrentDevice(std::string devID){ int streamFlags=PA_STREAM_START_CORKED | PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_ADJUST_LATENCY; int err=pa_stream_connect_record(stream, devID=="default" ? NULL : devID.c_str(), &bufferAttr, (pa_stream_flags_t)streamFlags); - if(err!=0 && devID!="default"){ - SetCurrentDevice("default"); - return; + if(err!=0){ + pa_threaded_mainloop_unlock(mainloop); + /*if(devID!="default"){ + SetCurrentDevice("default"); + return; + }*/ } CHECK_ERROR(err, "pa_stream_connect_record"); @@ -115,6 +128,7 @@ void AudioInputPulse::SetCurrentDevice(std::string devID){ pa_stream_state_t streamState=pa_stream_get_state(stream); if(!PA_STREAM_IS_GOOD(streamState)){ LOGE("Error connecting to audio device '%s'", devID.c_str()); + pa_threaded_mainloop_unlock(mainloop); failed=true; return; } diff --git a/os/linux/AudioInputPulse.h b/os/linux/AudioInputPulse.h index a1e748d714..e1d29948b3 100644 --- a/os/linux/AudioInputPulse.h +++ b/os/linux/AudioInputPulse.h @@ -30,6 +30,7 @@ private: static void StreamStateCallback(pa_stream* s, void* arg); static void StreamReadCallback(pa_stream* stream, size_t requested_bytes, void* userdata); void StreamReadCallback(pa_stream* stream, size_t requestedBytes); + pa_stream* CreateAndInitStream(); pa_threaded_mainloop* mainloop; pa_context* context; diff --git a/os/linux/AudioOutputPulse.cpp b/os/linux/AudioOutputPulse.cpp index 6086731d6d..bcdacb7050 100644 --- a/os/linux/AudioOutputPulse.cpp +++ b/os/linux/AudioOutputPulse.cpp @@ -34,25 +34,8 @@ AudioOutputPulse::AudioOutputPulse(pa_context* context, pa_threaded_mainloop* ma stream=NULL; remainingDataSize=0; - pa_sample_spec sample_specifications{ - .format=PA_SAMPLE_S16LE, - .rate=48000, - .channels=1 - }; - pa_threaded_mainloop_lock(mainloop); - pa_proplist* proplist=pa_proplist_new(); - pa_proplist_sets(proplist, PA_PROP_FILTER_APPLY, ""); // according to PA sources, this disables any possible filters - stream=pa_stream_new_with_proplist(context, "libtgvoip playback", &sample_specifications, NULL, proplist); - pa_proplist_free(proplist); - if(!stream){ - LOGE("Error initializing PulseAudio (pa_stream_new)"); - pa_threaded_mainloop_unlock(mainloop); - failed=true; - return; - } - pa_stream_set_state_callback(stream, AudioOutputPulse::StreamStateCallback, this); - pa_stream_set_write_callback(stream, AudioOutputPulse::StreamWriteCallback, this); + stream=CreateAndInitStream(); pa_threaded_mainloop_unlock(mainloop); SetCurrentDevice(devID); @@ -65,6 +48,26 @@ AudioOutputPulse::~AudioOutputPulse(){ } } +pa_stream* AudioOutputPulse::CreateAndInitStream(){ + pa_sample_spec sampleSpec{ + .format=PA_SAMPLE_S16LE, + .rate=48000, + .channels=1 + }; + pa_proplist* proplist=pa_proplist_new(); + pa_proplist_sets(proplist, PA_PROP_FILTER_APPLY, ""); // according to PA sources, this disables any possible filters + pa_stream* stream=pa_stream_new_with_proplist(context, "libtgvoip playback", &sampleSpec, NULL, proplist); + pa_proplist_free(proplist); + if(!stream){ + LOGE("Error initializing PulseAudio (pa_stream_new)"); + failed=true; + return NULL; + } + pa_stream_set_state_callback(stream, AudioOutputPulse::StreamStateCallback, this); + pa_stream_set_write_callback(stream, AudioOutputPulse::StreamWriteCallback, this); + return stream; +} + void AudioOutputPulse::Start(){ if(failed || isPlaying) return; @@ -94,7 +97,9 @@ void AudioOutputPulse::SetCurrentDevice(std::string devID){ currentDevice=devID; if(isPlaying && isConnected){ pa_stream_disconnect(stream); + pa_stream_unref(stream); isConnected=false; + stream=CreateAndInitStream(); } pa_buffer_attr bufferAttr={ diff --git a/os/linux/AudioOutputPulse.h b/os/linux/AudioOutputPulse.h index 0d93edc974..496cf85f51 100644 --- a/os/linux/AudioOutputPulse.h +++ b/os/linux/AudioOutputPulse.h @@ -28,6 +28,7 @@ private: static void StreamStateCallback(pa_stream* s, void* arg); static void StreamWriteCallback(pa_stream* stream, size_t requested_bytes, void* userdata); void StreamWriteCallback(pa_stream* stream, size_t requestedBytes); + pa_stream* CreateAndInitStream(); pa_threaded_mainloop* mainloop; pa_context* context; diff --git a/os/windows/AudioInputWASAPI.cpp b/os/windows/AudioInputWASAPI.cpp index ee0547749b..eaae3937b0 100755 --- a/os/windows/AudioInputWASAPI.cpp +++ b/os/windows/AudioInputWASAPI.cpp @@ -31,7 +31,9 @@ AudioInputWASAPI::AudioInputWASAPI(std::string deviceID){ refCount=1; HRESULT res; res=CoInitializeEx(NULL, COINIT_MULTITHREADED); - CHECK_RES(res, "CoInitializeEx"); + if(FAILED(res) && res!=RPC_E_CHANGED_MODE){ + CHECK_RES(res, "CoInitializeEx"); + } #ifdef TGVOIP_WINXP_COMPAT HANDLE (WINAPI *__CreateEventExA)(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCSTR lpName, DWORD dwFlags, DWORD dwDesiredAccess); __CreateEventExA=(HANDLE (WINAPI *)(LPSECURITY_ATTRIBUTES, LPCSTR, DWORD, DWORD))GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateEventExA"); @@ -124,7 +126,9 @@ void AudioInputWASAPI::EnumerateDevices(std::vector& d #ifdef TGVOIP_WINDOWS_DESKTOP HRESULT res; res=CoInitializeEx(NULL, COINIT_MULTITHREADED); - SCHECK_RES(res, "CoInitializeEx"); + if(FAILED(res) && res!=RPC_E_CHANGED_MODE){ + SCHECK_RES(res, "CoInitializeEx"); + } IMMDeviceEnumerator *deviceEnumerator = NULL; IMMDeviceCollection *deviceCollection = NULL; diff --git a/os/windows/AudioInputWASAPI.h b/os/windows/AudioInputWASAPI.h index 899c98bc50..b92ef25ed2 100755 --- a/os/windows/AudioInputWASAPI.h +++ b/os/windows/AudioInputWASAPI.h @@ -64,8 +64,8 @@ private: HANDLE audioSamplesReadyEvent; HANDLE streamSwitchEvent; HANDLE thread; - IAudioClient* audioClient; - IAudioCaptureClient* captureClient; + IAudioClient* audioClient=NULL; + IAudioCaptureClient* captureClient=NULL; #ifdef TGVOIP_WINDOWS_DESKTOP IMMDeviceEnumerator* enumerator; IAudioSessionControl* audioSessionControl; diff --git a/os/windows/AudioOutputWASAPI.cpp b/os/windows/AudioOutputWASAPI.cpp index f4e624ca45..81734e4835 100755 --- a/os/windows/AudioOutputWASAPI.cpp +++ b/os/windows/AudioOutputWASAPI.cpp @@ -35,7 +35,9 @@ AudioOutputWASAPI::AudioOutputWASAPI(std::string deviceID){ refCount=1; HRESULT res; res=CoInitializeEx(NULL, COINIT_MULTITHREADED); - CHECK_RES(res, "CoInitializeEx"); + if(FAILED(res) && res!=RPC_E_CHANGED_MODE){ + CHECK_RES(res, "CoInitializeEx"); + } #ifdef TGVOIP_WINXP_COMPAT HANDLE (WINAPI *__CreateEventExA)(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCSTR lpName, DWORD dwFlags, DWORD dwDesiredAccess); __CreateEventExA=(HANDLE (WINAPI *)(LPSECURITY_ATTRIBUTES, LPCSTR, DWORD, DWORD))GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateEventExA"); @@ -120,7 +122,9 @@ void AudioOutputWASAPI::EnumerateDevices(std::vector& #ifdef TGVOIP_WINDOWS_DESKTOP HRESULT res; res=CoInitializeEx(NULL, COINIT_MULTITHREADED); - SCHECK_RES(res, "CoInitializeEx"); + if(FAILED(res) && res!=RPC_E_CHANGED_MODE){ + SCHECK_RES(res, "CoInitializeEx"); + } IMMDeviceEnumerator *deviceEnumerator = NULL; IMMDeviceCollection *deviceCollection = NULL; diff --git a/os/windows/AudioOutputWASAPI.h b/os/windows/AudioOutputWASAPI.h index 81236d11a7..f3b9d559d4 100755 --- a/os/windows/AudioOutputWASAPI.h +++ b/os/windows/AudioOutputWASAPI.h @@ -63,8 +63,8 @@ private: HANDLE audioSamplesReadyEvent; HANDLE streamSwitchEvent; HANDLE thread; - IAudioClient* audioClient; - IAudioRenderClient* renderClient; + IAudioClient* audioClient=NULL; + IAudioRenderClient* renderClient=NULL; #ifdef TGVOIP_WINDOWS_DESKTOP IMMDeviceEnumerator* enumerator; IAudioSessionControl* audioSessionControl;