mirror of
https://github.com/danog/libtgvoip.git
synced 2024-12-02 09:37:52 +01:00
Fixes
This commit is contained in:
parent
8fd89fc173
commit
59a975bf66
@ -59,7 +59,7 @@ public:
|
|||||||
virtual void Process(int16_t* inOut, size_t numSamples)=0;
|
virtual void Process(int16_t* inOut, size_t numSamples)=0;
|
||||||
virtual void SetPassThrough(bool passThrough);
|
virtual void SetPassThrough(bool passThrough);
|
||||||
protected:
|
protected:
|
||||||
bool passThrough;
|
bool passThrough=false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Volume : public AudioEffect{
|
class Volume : public AudioEffect{
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "OpusEncoder.h"
|
#include "OpusEncoder.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <algorithm>
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "VoIPServerConfig.h"
|
#include "VoIPServerConfig.h"
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
|
@ -33,25 +33,13 @@ AudioInputPulse::AudioInputPulse(pa_context* context, pa_threaded_mainloop* main
|
|||||||
remainingDataSize=0;
|
remainingDataSize=0;
|
||||||
|
|
||||||
pa_threaded_mainloop_lock(mainloop);
|
pa_threaded_mainloop_lock(mainloop);
|
||||||
pa_sample_spec sample_specifications{
|
|
||||||
.format=PA_SAMPLE_S16LE,
|
|
||||||
.rate=48000,
|
|
||||||
.channels=1
|
|
||||||
};
|
|
||||||
|
|
||||||
pa_proplist* proplist=pa_proplist_new();
|
stream=CreateAndInitStream();
|
||||||
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);
|
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
isLocked=false;
|
isLocked=false;
|
||||||
|
if(!stream){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SetCurrentDevice(devID);
|
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(){
|
void AudioInputPulse::Start(){
|
||||||
if(failed || isRecording)
|
if(failed || isRecording)
|
||||||
return;
|
return;
|
||||||
@ -92,7 +100,9 @@ void AudioInputPulse::SetCurrentDevice(std::string devID){
|
|||||||
currentDevice=devID;
|
currentDevice=devID;
|
||||||
if(isRecording && isConnected){
|
if(isRecording && isConnected){
|
||||||
pa_stream_disconnect(stream);
|
pa_stream_disconnect(stream);
|
||||||
|
pa_stream_unref(stream);
|
||||||
isConnected=false;
|
isConnected=false;
|
||||||
|
stream=CreateAndInitStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_buffer_attr bufferAttr={
|
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 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);
|
int err=pa_stream_connect_record(stream, devID=="default" ? NULL : devID.c_str(), &bufferAttr, (pa_stream_flags_t)streamFlags);
|
||||||
if(err!=0 && devID!="default"){
|
if(err!=0){
|
||||||
SetCurrentDevice("default");
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
return;
|
/*if(devID!="default"){
|
||||||
|
SetCurrentDevice("default");
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
CHECK_ERROR(err, "pa_stream_connect_record");
|
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);
|
pa_stream_state_t streamState=pa_stream_get_state(stream);
|
||||||
if(!PA_STREAM_IS_GOOD(streamState)){
|
if(!PA_STREAM_IS_GOOD(streamState)){
|
||||||
LOGE("Error connecting to audio device '%s'", devID.c_str());
|
LOGE("Error connecting to audio device '%s'", devID.c_str());
|
||||||
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
failed=true;
|
failed=true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ private:
|
|||||||
static void StreamStateCallback(pa_stream* s, void* arg);
|
static void StreamStateCallback(pa_stream* s, void* arg);
|
||||||
static void StreamReadCallback(pa_stream* stream, size_t requested_bytes, void* userdata);
|
static void StreamReadCallback(pa_stream* stream, size_t requested_bytes, void* userdata);
|
||||||
void StreamReadCallback(pa_stream* stream, size_t requestedBytes);
|
void StreamReadCallback(pa_stream* stream, size_t requestedBytes);
|
||||||
|
pa_stream* CreateAndInitStream();
|
||||||
|
|
||||||
pa_threaded_mainloop* mainloop;
|
pa_threaded_mainloop* mainloop;
|
||||||
pa_context* context;
|
pa_context* context;
|
||||||
|
@ -34,25 +34,8 @@ AudioOutputPulse::AudioOutputPulse(pa_context* context, pa_threaded_mainloop* ma
|
|||||||
stream=NULL;
|
stream=NULL;
|
||||||
remainingDataSize=0;
|
remainingDataSize=0;
|
||||||
|
|
||||||
pa_sample_spec sample_specifications{
|
|
||||||
.format=PA_SAMPLE_S16LE,
|
|
||||||
.rate=48000,
|
|
||||||
.channels=1
|
|
||||||
};
|
|
||||||
|
|
||||||
pa_threaded_mainloop_lock(mainloop);
|
pa_threaded_mainloop_lock(mainloop);
|
||||||
pa_proplist* proplist=pa_proplist_new();
|
stream=CreateAndInitStream();
|
||||||
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);
|
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
|
|
||||||
SetCurrentDevice(devID);
|
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(){
|
void AudioOutputPulse::Start(){
|
||||||
if(failed || isPlaying)
|
if(failed || isPlaying)
|
||||||
return;
|
return;
|
||||||
@ -94,7 +97,9 @@ void AudioOutputPulse::SetCurrentDevice(std::string devID){
|
|||||||
currentDevice=devID;
|
currentDevice=devID;
|
||||||
if(isPlaying && isConnected){
|
if(isPlaying && isConnected){
|
||||||
pa_stream_disconnect(stream);
|
pa_stream_disconnect(stream);
|
||||||
|
pa_stream_unref(stream);
|
||||||
isConnected=false;
|
isConnected=false;
|
||||||
|
stream=CreateAndInitStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_buffer_attr bufferAttr={
|
pa_buffer_attr bufferAttr={
|
||||||
|
@ -28,6 +28,7 @@ private:
|
|||||||
static void StreamStateCallback(pa_stream* s, void* arg);
|
static void StreamStateCallback(pa_stream* s, void* arg);
|
||||||
static void StreamWriteCallback(pa_stream* stream, size_t requested_bytes, void* userdata);
|
static void StreamWriteCallback(pa_stream* stream, size_t requested_bytes, void* userdata);
|
||||||
void StreamWriteCallback(pa_stream* stream, size_t requestedBytes);
|
void StreamWriteCallback(pa_stream* stream, size_t requestedBytes);
|
||||||
|
pa_stream* CreateAndInitStream();
|
||||||
|
|
||||||
pa_threaded_mainloop* mainloop;
|
pa_threaded_mainloop* mainloop;
|
||||||
pa_context* context;
|
pa_context* context;
|
||||||
|
@ -31,7 +31,9 @@ AudioInputWASAPI::AudioInputWASAPI(std::string deviceID){
|
|||||||
refCount=1;
|
refCount=1;
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
res=CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
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
|
#ifdef TGVOIP_WINXP_COMPAT
|
||||||
HANDLE (WINAPI *__CreateEventExA)(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCSTR lpName, DWORD dwFlags, DWORD dwDesiredAccess);
|
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");
|
__CreateEventExA=(HANDLE (WINAPI *)(LPSECURITY_ATTRIBUTES, LPCSTR, DWORD, DWORD))GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateEventExA");
|
||||||
@ -124,7 +126,9 @@ void AudioInputWASAPI::EnumerateDevices(std::vector<tgvoip::AudioInputDevice>& d
|
|||||||
#ifdef TGVOIP_WINDOWS_DESKTOP
|
#ifdef TGVOIP_WINDOWS_DESKTOP
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
res=CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
res=CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||||
SCHECK_RES(res, "CoInitializeEx");
|
if(FAILED(res) && res!=RPC_E_CHANGED_MODE){
|
||||||
|
SCHECK_RES(res, "CoInitializeEx");
|
||||||
|
}
|
||||||
|
|
||||||
IMMDeviceEnumerator *deviceEnumerator = NULL;
|
IMMDeviceEnumerator *deviceEnumerator = NULL;
|
||||||
IMMDeviceCollection *deviceCollection = NULL;
|
IMMDeviceCollection *deviceCollection = NULL;
|
||||||
|
@ -64,8 +64,8 @@ private:
|
|||||||
HANDLE audioSamplesReadyEvent;
|
HANDLE audioSamplesReadyEvent;
|
||||||
HANDLE streamSwitchEvent;
|
HANDLE streamSwitchEvent;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
IAudioClient* audioClient;
|
IAudioClient* audioClient=NULL;
|
||||||
IAudioCaptureClient* captureClient;
|
IAudioCaptureClient* captureClient=NULL;
|
||||||
#ifdef TGVOIP_WINDOWS_DESKTOP
|
#ifdef TGVOIP_WINDOWS_DESKTOP
|
||||||
IMMDeviceEnumerator* enumerator;
|
IMMDeviceEnumerator* enumerator;
|
||||||
IAudioSessionControl* audioSessionControl;
|
IAudioSessionControl* audioSessionControl;
|
||||||
|
@ -35,7 +35,9 @@ AudioOutputWASAPI::AudioOutputWASAPI(std::string deviceID){
|
|||||||
refCount=1;
|
refCount=1;
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
res=CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
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
|
#ifdef TGVOIP_WINXP_COMPAT
|
||||||
HANDLE (WINAPI *__CreateEventExA)(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCSTR lpName, DWORD dwFlags, DWORD dwDesiredAccess);
|
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");
|
__CreateEventExA=(HANDLE (WINAPI *)(LPSECURITY_ATTRIBUTES, LPCSTR, DWORD, DWORD))GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateEventExA");
|
||||||
@ -120,7 +122,9 @@ void AudioOutputWASAPI::EnumerateDevices(std::vector<tgvoip::AudioOutputDevice>&
|
|||||||
#ifdef TGVOIP_WINDOWS_DESKTOP
|
#ifdef TGVOIP_WINDOWS_DESKTOP
|
||||||
HRESULT res;
|
HRESULT res;
|
||||||
res=CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
res=CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||||
SCHECK_RES(res, "CoInitializeEx");
|
if(FAILED(res) && res!=RPC_E_CHANGED_MODE){
|
||||||
|
SCHECK_RES(res, "CoInitializeEx");
|
||||||
|
}
|
||||||
|
|
||||||
IMMDeviceEnumerator *deviceEnumerator = NULL;
|
IMMDeviceEnumerator *deviceEnumerator = NULL;
|
||||||
IMMDeviceCollection *deviceCollection = NULL;
|
IMMDeviceCollection *deviceCollection = NULL;
|
||||||
|
@ -63,8 +63,8 @@ private:
|
|||||||
HANDLE audioSamplesReadyEvent;
|
HANDLE audioSamplesReadyEvent;
|
||||||
HANDLE streamSwitchEvent;
|
HANDLE streamSwitchEvent;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
IAudioClient* audioClient;
|
IAudioClient* audioClient=NULL;
|
||||||
IAudioRenderClient* renderClient;
|
IAudioRenderClient* renderClient=NULL;
|
||||||
#ifdef TGVOIP_WINDOWS_DESKTOP
|
#ifdef TGVOIP_WINDOWS_DESKTOP
|
||||||
IMMDeviceEnumerator* enumerator;
|
IMMDeviceEnumerator* enumerator;
|
||||||
IAudioSessionControl* audioSessionControl;
|
IAudioSessionControl* audioSessionControl;
|
||||||
|
Loading…
Reference in New Issue
Block a user