1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-11-26 20:24:38 +01:00
This commit is contained in:
Grishka 2018-12-31 04:05:58 +03:00
parent 8fd89fc173
commit 59a975bf66
10 changed files with 76 additions and 46 deletions

View File

@ -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{

View File

@ -6,6 +6,7 @@
#include "OpusEncoder.h"
#include <assert.h>
#include <algorithm>
#include "logging.h"
#include "VoIPServerConfig.h"
#ifdef HAVE_CONFIG_H

View File

@ -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;
}

View File

@ -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;

View File

@ -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={

View File

@ -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;

View File

@ -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<tgvoip::AudioInputDevice>& 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;

View File

@ -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;

View File

@ -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<tgvoip::AudioOutputDevice>&
#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;

View File

@ -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;