pjaudio and spdlog support
This commit is contained in:
parent
58fa05e5a8
commit
f9315603b6
|
@ -0,0 +1,205 @@
|
|||
cmake_minimum_required(VERSION 3.9)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(OPUS opus REQUIRED)
|
||||
pkg_check_modules(OPENSSL openssl REQUIRED)
|
||||
pkg_check_modules(PJSIP libpjproject>=2.8 REQUIRED)
|
||||
find_package(spdlog 0.17)
|
||||
|
||||
add_library(libtgvoip STATIC
|
||||
BlockingQueue.cpp
|
||||
BlockingQueue.h
|
||||
Buffers.cpp
|
||||
Buffers.h
|
||||
CongestionControl.cpp
|
||||
CongestionControl.h
|
||||
EchoCanceller.cpp
|
||||
EchoCanceller.h
|
||||
JitterBuffer.cpp
|
||||
JitterBuffer.h
|
||||
logging.cpp
|
||||
logging.h
|
||||
MediaStreamItf.cpp
|
||||
MediaStreamItf.h
|
||||
OpusDecoder.cpp
|
||||
OpusDecoder.h
|
||||
OpusEncoder.cpp
|
||||
OpusEncoder.h
|
||||
threading.h
|
||||
VoIPController.cpp
|
||||
VoIPGroupController.cpp
|
||||
VoIPController.h
|
||||
PrivateDefines.h
|
||||
VoIPServerConfig.cpp
|
||||
VoIPServerConfig.h
|
||||
audio/AudioInput.cpp
|
||||
audio/AudioInput.h
|
||||
audio/AudioOutput.cpp
|
||||
audio/AudioOutput.h
|
||||
audio/Resampler.cpp
|
||||
audio/Resampler.h
|
||||
NetworkSocket.cpp
|
||||
NetworkSocket.h
|
||||
PacketReassembler.cpp
|
||||
PacketReassembler.h
|
||||
MessageThread.cpp
|
||||
MessageThread.h
|
||||
audio/AudioIO.cpp
|
||||
audio/AudioIO.h
|
||||
|
||||
# POSIX
|
||||
os/posix/NetworkSocketPosix.cpp
|
||||
os/posix/NetworkSocketPosix.h
|
||||
|
||||
webrtc_dsp/webrtc/base/array_view.h
|
||||
webrtc_dsp/webrtc/base/atomicops.h
|
||||
webrtc_dsp/webrtc/base/basictypes.h
|
||||
webrtc_dsp/webrtc/base/checks.cc
|
||||
webrtc_dsp/webrtc/base/checks.h
|
||||
webrtc_dsp/webrtc/base/constructormagic.h
|
||||
webrtc_dsp/webrtc/base/safe_compare.h
|
||||
webrtc_dsp/webrtc/base/safe_conversions.h
|
||||
webrtc_dsp/webrtc/base/safe_conversions_impl.h
|
||||
webrtc_dsp/webrtc/base/sanitizer.h
|
||||
webrtc_dsp/webrtc/base/stringutils.cc
|
||||
webrtc_dsp/webrtc/base/stringutils.h
|
||||
webrtc_dsp/webrtc/base/type_traits.h
|
||||
webrtc_dsp/webrtc/common_audio/audio_util.cc
|
||||
webrtc_dsp/webrtc/common_audio/channel_buffer.cc
|
||||
webrtc_dsp/webrtc/common_audio/channel_buffer.h
|
||||
webrtc_dsp/webrtc/common_audio/fft4g.c
|
||||
webrtc_dsp/webrtc/common_audio/fft4g.h
|
||||
webrtc_dsp/webrtc/common_audio/include/audio_util.h
|
||||
webrtc_dsp/webrtc/common_audio/ring_buffer.c
|
||||
webrtc_dsp/webrtc/common_audio/ring_buffer.h
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/auto_corr_to_refl_coef.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/auto_correlation.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/complex_bit_reverse.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/complex_fft.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/complex_fft_tables.h
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/copy_set_operations.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/cross_correlation.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/division_operations.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/dot_product_with_scale.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/downsample_fast.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/energy.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/filter_ar.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/filter_ar_fast_q12.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/filter_ma_fast_q12.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/get_hanning_window.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/get_scaling_square.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/ilbc_specific_functions.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/include/real_fft.h
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/include/signal_processing_library.h
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/include/spl_inl.h
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/include/spl_inl_mips.h
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/levinson_durbin.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/lpc_to_refl_coef.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/min_max_operations.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/randomization_functions.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/real_fft.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/refl_coef_to_lpc.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/resample.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/resample_48khz.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/resample_by_2.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/resample_by_2_internal.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/resample_by_2_internal.h
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/resample_fractional.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/spl_init.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/spl_inl.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/spl_sqrt.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/spl_sqrt_floor.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/splitting_filter_impl.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/sqrt_of_one_minus_x_squared.c
|
||||
webrtc_dsp/webrtc/common_audio/signal_processing/vector_scaling_operations.c
|
||||
webrtc_dsp/webrtc/common_audio/sparse_fir_filter.cc
|
||||
webrtc_dsp/webrtc/common_audio/sparse_fir_filter.h
|
||||
webrtc_dsp/webrtc/common_audio/wav_file.cc
|
||||
webrtc_dsp/webrtc/common_audio/wav_file.h
|
||||
webrtc_dsp/webrtc/common_audio/wav_header.cc
|
||||
webrtc_dsp/webrtc/common_audio/wav_header.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_common.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_core.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_core.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_core_optimized_methods.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_core_sse2.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_resampler.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_resampler.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aec/echo_cancellation.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aec/echo_cancellation.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aecm/aecm_core.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aecm/aecm_core.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aecm/aecm_core_c.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aecm/aecm_defines.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aecm/echo_control_mobile.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/aecm/echo_control_mobile.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/agc/legacy/analog_agc.c
|
||||
webrtc_dsp/webrtc/modules/audio_processing/agc/legacy/analog_agc.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/agc/legacy/digital_agc.c
|
||||
webrtc_dsp/webrtc/modules/audio_processing/agc/legacy/digital_agc.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/agc/legacy/gain_control.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/logging/apm_data_dumper.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/logging/apm_data_dumper.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/ns/defines.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/ns/noise_suppression.c
|
||||
webrtc_dsp/webrtc/modules/audio_processing/ns/noise_suppression.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/ns/noise_suppression_x.c
|
||||
webrtc_dsp/webrtc/modules/audio_processing/ns/noise_suppression_x.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/ns/ns_core.c
|
||||
webrtc_dsp/webrtc/modules/audio_processing/ns/ns_core.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/ns/nsx_core.c
|
||||
webrtc_dsp/webrtc/modules/audio_processing/ns/nsx_core.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/ns/nsx_core_c.c
|
||||
webrtc_dsp/webrtc/modules/audio_processing/ns/nsx_defines.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/ns/windows_private.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/splitting_filter.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/splitting_filter.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/three_band_filter_bank.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/three_band_filter_bank.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/utility/block_mean_calculator.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/utility/block_mean_calculator.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/utility/delay_estimator.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/utility/delay_estimator.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/utility/delay_estimator_internal.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/utility/ooura_fft.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/utility/ooura_fft.h
|
||||
webrtc_dsp/webrtc/modules/audio_processing/utility/ooura_fft_sse2.cc
|
||||
webrtc_dsp/webrtc/modules/audio_processing/utility/ooura_fft_tables_common.h
|
||||
webrtc_dsp/webrtc/system_wrappers/include/asm_defines.h
|
||||
webrtc_dsp/webrtc/system_wrappers/include/compile_assert_c.h
|
||||
webrtc_dsp/webrtc/system_wrappers/include/cpu_features_wrapper.h
|
||||
webrtc_dsp/webrtc/system_wrappers/include/metrics.h
|
||||
webrtc_dsp/webrtc/system_wrappers/source/cpu_features.cc
|
||||
webrtc_dsp/webrtc/typedefs.h
|
||||
|
||||
#SOFTWARE AUDIO
|
||||
audio/SoftwareAudioInput.h
|
||||
audio/SoftwareAudioInput.cpp
|
||||
audio/SoftwareAudioOutput.h
|
||||
audio/SoftwareAudioOutput.cpp)
|
||||
|
||||
set_property(TARGET libtgvoip PROPERTY CXX_STANDARD 11)
|
||||
|
||||
target_include_directories(libtgvoip PRIVATE
|
||||
webrtc_dsp
|
||||
${OPUS_INCLUDE_DIRS}
|
||||
${OPENSSL_INCLUDE_DIRS}
|
||||
${PJSIP_INCLUDE_DIRS})
|
||||
|
||||
target_compile_definitions(libtgvoip PRIVATE
|
||||
WEBRTC_APM_DEBUG_DUMP=0
|
||||
WEBRTC_POSIX
|
||||
DEFAULT_THREAD_PRIORITY)
|
||||
|
||||
target_compile_definitions(libtgvoip PUBLIC
|
||||
TGVOIP_USE_DESKTOP_DSP
|
||||
TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
|
||||
if (${spdlog_FOUND})
|
||||
target_compile_definitions(libtgvoip PUBLIC
|
||||
TGVOIP_USE_SPDLOG)
|
||||
else ()
|
||||
message(STATUS "Could NOT find spdlog")
|
||||
endif ()
|
|
@ -123,6 +123,9 @@ CryptoFunctions VoIPController::crypto; // set it yourself upon initialization
|
|||
|
||||
|
||||
extern FILE* tgvoipLogFile;
|
||||
#ifdef TGVOIP_USE_SPDLOG
|
||||
extern std::shared_ptr<spdlog::logger> _voip_logger;
|
||||
#endif
|
||||
|
||||
VoIPController::VoIPController() : activeNetItfName(""),
|
||||
currentAudioInput("default"),
|
||||
|
@ -130,7 +133,10 @@ VoIPController::VoIPController() : activeNetItfName(""),
|
|||
proxyAddress(""),
|
||||
proxyUsername(""),
|
||||
proxyPassword(""){
|
||||
seq=1;
|
||||
#ifdef TGVOIP_USE_SPDLOG
|
||||
_voip_logger = spdlog::get("tgvoip");
|
||||
#endif
|
||||
seq=1;
|
||||
lastRemoteSeq=0;
|
||||
state=STATE_WAIT_INIT;
|
||||
audioInput=NULL;
|
||||
|
@ -245,10 +251,42 @@ VoIPController::VoIPController() : activeNetItfName(""),
|
|||
vstm.codec=CODEC_AVC;
|
||||
vstm.enabled=1;
|
||||
outgoingStreams.push_back(vstm);*/
|
||||
|
||||
#if defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
pj_thread_t *tmp_thread = nullptr;
|
||||
pj_thread_desc tmp_thread_desc;
|
||||
if (!pj_thread_is_registered()) {
|
||||
pj_bzero(&tmp_thread_desc, sizeof(tmp_thread_desc));
|
||||
pj_status_t status;
|
||||
status = pj_thread_register("tmp", tmp_thread_desc, &tmp_thread);
|
||||
if (status != PJ_SUCCESS) {
|
||||
LOGE("Temp constructor thread PJ register failed");
|
||||
}
|
||||
}
|
||||
|
||||
softwareMediaInput = new tgvoip::audio::SoftwareAudioInput();
|
||||
softwareMediaOutput = new tgvoip::audio::SoftwareAudioOutput();
|
||||
|
||||
if (tmp_thread) {
|
||||
pj_thread_destroy(tmp_thread);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
VoIPController::~VoIPController(){
|
||||
LOGD("Entered VoIPController::~VoIPController");
|
||||
#if defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
pj_thread_t *tmp_thread = nullptr;
|
||||
pj_thread_desc tmp_thread_desc;
|
||||
if (!pj_thread_is_registered()) {
|
||||
pj_bzero(&tmp_thread_desc, sizeof(tmp_thread_desc));
|
||||
pj_status_t status;
|
||||
status = pj_thread_register("tmp", tmp_thread_desc, &tmp_thread);
|
||||
if (status != PJ_SUCCESS) {
|
||||
LOGE("Temp destructor thread PJ register failed");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(!stopping){
|
||||
LOGE("!!!!!!!!!!!!!!!!!!!! CALL controller->Stop() BEFORE DELETING THE CONTROLLER OBJECT !!!!!!!!!!!!!!!!!!!!!!!1");
|
||||
abort();
|
||||
|
@ -289,6 +327,14 @@ VoIPController::~VoIPController(){
|
|||
delete (*stm)->decoder;
|
||||
}
|
||||
}*/
|
||||
#if defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
delete softwareMediaInput;
|
||||
delete softwareMediaOutput;
|
||||
|
||||
if(tmp_thread) {
|
||||
pj_thread_destroy(tmp_thread);
|
||||
}
|
||||
#endif
|
||||
LOGD("before delete echo canceller");
|
||||
if(echoCanceller){
|
||||
echoCanceller->Stop();
|
||||
|
@ -1346,45 +1392,45 @@ simpleAudioBlock random_id:long random_bytes:string raw_data:string = DecryptedA
|
|||
peerCapabilities|=TGVOIP_PEER_CAP_GROUP_CALLS;
|
||||
}
|
||||
|
||||
unsigned int i;
|
||||
unsigned int numSupportedAudioCodecs=in.ReadByte();
|
||||
for(i=0; i<numSupportedAudioCodecs; i++){
|
||||
if(peerVersion<5)
|
||||
in.ReadByte(); // ignore for now
|
||||
else
|
||||
in.ReadInt32();
|
||||
}
|
||||
unsigned int numSupportedVideoCodecs=in.ReadByte();
|
||||
for(i=0; i<numSupportedVideoCodecs; i++){
|
||||
if(peerVersion<5)
|
||||
in.ReadByte(); // ignore for now
|
||||
else
|
||||
in.ReadInt32();
|
||||
}
|
||||
unsigned int i;
|
||||
unsigned int numSupportedAudioCodecs=in.ReadByte();
|
||||
for(i=0; i<numSupportedAudioCodecs; i++){
|
||||
if(peerVersion<5)
|
||||
in.ReadByte(); // ignore for now
|
||||
else
|
||||
in.ReadInt32();
|
||||
}
|
||||
unsigned int numSupportedVideoCodecs=in.ReadByte();
|
||||
for(i=0; i<numSupportedVideoCodecs; i++){
|
||||
if(peerVersion<5)
|
||||
in.ReadByte(); // ignore for now
|
||||
else
|
||||
in.ReadInt32();
|
||||
}
|
||||
|
||||
BufferOutputStream out(1024);
|
||||
BufferOutputStream out(1024);
|
||||
|
||||
out.WriteInt32(PROTOCOL_VERSION);
|
||||
out.WriteInt32(MIN_PROTOCOL_VERSION);
|
||||
out.WriteInt32(PROTOCOL_VERSION);
|
||||
out.WriteInt32(MIN_PROTOCOL_VERSION);
|
||||
|
||||
out.WriteByte((unsigned char) outgoingStreams.size());
|
||||
for(vector<shared_ptr<Stream>>::iterator s=outgoingStreams.begin(); s!=outgoingStreams.end(); ++s){
|
||||
out.WriteByte((*s)->id);
|
||||
out.WriteByte((*s)->type);
|
||||
if(peerVersion<5)
|
||||
out.WriteByte((unsigned char) ((*s)->codec==CODEC_OPUS ? CODEC_OPUS_OLD : 0));
|
||||
else
|
||||
out.WriteInt32((*s)->codec);
|
||||
out.WriteInt16((*s)->frameDuration);
|
||||
out.WriteByte((unsigned char) ((*s)->enabled ? 1 : 0));
|
||||
}
|
||||
sendQueue->Put(PendingOutgoingPacket{
|
||||
/*.seq=*/GenerateOutSeq(),
|
||||
/*.type=*/PKT_INIT_ACK,
|
||||
/*.len=*/out.GetLength(),
|
||||
/*.data=*/Buffer(move(out)),
|
||||
/*.endpoint=*/0
|
||||
});
|
||||
out.WriteByte((unsigned char) outgoingStreams.size());
|
||||
for(vector<shared_ptr<Stream>>::iterator s=outgoingStreams.begin(); s!=outgoingStreams.end(); ++s){
|
||||
out.WriteByte((*s)->id);
|
||||
out.WriteByte((*s)->type);
|
||||
if(peerVersion<5)
|
||||
out.WriteByte((unsigned char) ((*s)->codec==CODEC_OPUS ? CODEC_OPUS_OLD : 0));
|
||||
else
|
||||
out.WriteInt32((*s)->codec);
|
||||
out.WriteInt16((*s)->frameDuration);
|
||||
out.WriteByte((unsigned char) ((*s)->enabled ? 1 : 0));
|
||||
}
|
||||
sendQueue->Put(PendingOutgoingPacket{
|
||||
/*.seq=*/GenerateOutSeq(),
|
||||
/*.type=*/PKT_INIT_ACK,
|
||||
/*.len=*/out.GetLength(),
|
||||
/*.data=*/Buffer(move(out)),
|
||||
/*.endpoint=*/0
|
||||
});
|
||||
}
|
||||
}
|
||||
if(type==PKT_INIT_ACK){
|
||||
|
@ -2648,9 +2694,14 @@ void VoIPController::SendUdpPing(shared_ptr<Endpoint> endpoint){
|
|||
void VoIPController::StartAudio(){
|
||||
shared_ptr<Stream>& outgoingAudioStream=outgoingStreams[0];
|
||||
LOGI("before create audio io");
|
||||
#if defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
audioInput = softwareMediaInput;
|
||||
audioOutput = softwareMediaOutput;
|
||||
#else
|
||||
audioIO=audio::AudioIO::Create();
|
||||
audioInput=audioIO->GetInput();
|
||||
audioOutput=audioIO->GetOutput();
|
||||
#endif
|
||||
LOGI("AEC: %d NS: %d AGC: %d", config.enableAEC, config.enableNS, config.enableAGC);
|
||||
echoCanceller=new EchoCanceller(config.enableAEC, config.enableNS, config.enableAGC);
|
||||
encoder=new OpusEncoder(audioInput, peerVersion>=6);
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
#if defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
#include <pjsua2.hpp>
|
||||
#include "audio/SoftwareAudioInput.h"
|
||||
#include "audio/SoftwareAudioOutput.h"
|
||||
#endif
|
||||
#include "audio/AudioInput.h"
|
||||
#include "BlockingQueue.h"
|
||||
#include "audio/AudioOutput.h"
|
||||
|
@ -381,6 +386,11 @@ namespace tgvoip{
|
|||
return 0.0f;
|
||||
};
|
||||
|
||||
#if defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
pj::AudioMedia * AudioMediaInput() {return softwareMediaInput;};
|
||||
pj::AudioMedia * AudioMediaOutput() {return softwareMediaOutput;};
|
||||
#endif
|
||||
|
||||
private:
|
||||
struct Stream;
|
||||
struct UnacknowledgedExtraData;
|
||||
|
@ -631,6 +641,10 @@ namespace tgvoip{
|
|||
double p2pToRelaySwitchThreshold;
|
||||
double relayToP2pSwitchThreshold;
|
||||
double reconnectingTimeout;
|
||||
#if defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
tgvoip::audio::SoftwareAudioInput* softwareMediaInput;
|
||||
tgvoip::audio::SoftwareAudioOutput* softwareMediaOutput;
|
||||
#endif
|
||||
|
||||
public:
|
||||
#ifdef __APPLE__
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if !defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
|
||||
#include "AudioIOCallback.h"
|
||||
#elif defined(__ANDROID__)
|
||||
|
@ -42,12 +43,14 @@
|
|||
#else
|
||||
#error "Unsupported operating system"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace tgvoip;
|
||||
using namespace tgvoip::audio;
|
||||
using namespace std;
|
||||
|
||||
shared_ptr<AudioIO> AudioIO::Create(){
|
||||
#if !defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
std::string inputDevice="default", outputDevice="default";
|
||||
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
|
||||
return std::make_shared<AudioIOCallback>();
|
||||
|
@ -81,6 +84,7 @@ shared_ptr<AudioIO> AudioIO::Create(){
|
|||
return std::make_shared<AudioPulse>(inputDevice, outputDevice);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
bool AudioIO::Failed(){
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if !defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
|
||||
// nothing
|
||||
#elif defined(__ANDROID__)
|
||||
|
@ -36,6 +37,7 @@
|
|||
#else
|
||||
#error "Unsupported operating system"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace tgvoip;
|
||||
using namespace tgvoip::audio;
|
||||
|
@ -60,6 +62,7 @@ bool AudioInput::IsInitialized(){
|
|||
}
|
||||
|
||||
void AudioInput::EnumerateDevices(std::vector<AudioInputDevice>& devs){
|
||||
#if !defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
|
||||
// not supported
|
||||
#elif defined(__APPLE__) && TARGET_OS_OSX
|
||||
|
@ -82,6 +85,7 @@ void AudioInput::EnumerateDevices(std::vector<AudioInputDevice>& devs){
|
|||
AudioInputPulse::EnumerateDevices(devs)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string AudioInput::GetCurrentDevice(){
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if !defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
|
||||
// nothing
|
||||
#elif defined(__ANDROID__)
|
||||
|
@ -40,6 +41,7 @@
|
|||
#else
|
||||
#error "Unsupported operating system"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace tgvoip;
|
||||
using namespace tgvoip::audio;
|
||||
|
@ -71,6 +73,7 @@ int32_t AudioOutput::GetEstimatedDelay(){
|
|||
|
||||
|
||||
void AudioOutput::EnumerateDevices(std::vector<AudioOutputDevice>& devs){
|
||||
#if !defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
|
||||
// not supported
|
||||
#elif defined(__APPLE__) && TARGET_OS_OSX
|
||||
|
@ -93,6 +96,7 @@ void AudioOutput::EnumerateDevices(std::vector<AudioOutputDevice>& devs){
|
|||
AudioOutputPulse::EnumerateDevices(devs)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
#include <cassert>
|
||||
#include "SoftwareAudioInput.h"
|
||||
|
||||
using namespace tgvoip::audio;
|
||||
|
||||
SoftwareAudioInput::SoftwareAudioInput() {
|
||||
isActive = false;
|
||||
|
||||
pj_pool = pjsua_pool_create("input%p", 2048, 512);
|
||||
media_port = PJ_POOL_ZALLOC_T(pj_pool, pjmedia_port);
|
||||
|
||||
pj_status_t status;
|
||||
pj_str_t name = pj_str((char *) "input");
|
||||
|
||||
status = pjmedia_port_info_init(&media_port->info,
|
||||
&name,
|
||||
PJMEDIA_SIG_CLASS_PORT_AUD('S', 'I'), // Software Input SIG
|
||||
48000, 1, 16, 960);
|
||||
assert(status == PJ_SUCCESS);
|
||||
|
||||
media_port->port_data.pdata = this;
|
||||
media_port->put_frame = &PutFrameCallback;
|
||||
media_port->get_frame = &GetFrameCallback;
|
||||
|
||||
registerMediaPort(media_port);
|
||||
}
|
||||
|
||||
SoftwareAudioInput::~SoftwareAudioInput() {
|
||||
unregisterMediaPort();
|
||||
pjmedia_port_destroy(media_port);
|
||||
pj_pool_release(pj_pool);
|
||||
}
|
||||
|
||||
void SoftwareAudioInput::Start() {
|
||||
isActive = true;
|
||||
}
|
||||
|
||||
void SoftwareAudioInput::Stop() {
|
||||
isActive = false;
|
||||
}
|
||||
|
||||
pj_status_t SoftwareAudioInput::PutFrameCallback(pjmedia_port *port, pjmedia_frame *frame) {
|
||||
|
||||
// skip heartbeat frame
|
||||
if (frame->type != PJMEDIA_FRAME_TYPE_AUDIO) {
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
assert(frame->size == 960 * 2);
|
||||
|
||||
auto input = (SoftwareAudioInput *) port->port_data.pdata;
|
||||
|
||||
if (!input->isActive) {
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
input->InvokeCallback((unsigned char *) frame->buf, frame->size);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
pj_status_t SoftwareAudioInput::GetFrameCallback(pjmedia_port *port, pjmedia_frame *frame) {
|
||||
frame->size = 0;
|
||||
frame->type = PJMEDIA_FRAME_TYPE_NONE;
|
||||
return PJ_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef TG2SIP_SOFTWAREAUDIOINPUT_H
|
||||
#define TG2SIP_SOFTWAREAUDIOINPUT_H
|
||||
|
||||
#include <pjsua2.hpp>
|
||||
#include "AudioInput.h"
|
||||
#include "../threading.h"
|
||||
|
||||
namespace tgvoip {
|
||||
namespace audio {
|
||||
class SoftwareAudioInput : public AudioInput, public pj::AudioMedia {
|
||||
public:
|
||||
explicit SoftwareAudioInput();
|
||||
|
||||
virtual ~SoftwareAudioInput();
|
||||
|
||||
void Start() override;
|
||||
|
||||
void Stop() override;
|
||||
|
||||
private:
|
||||
static pj_status_t PutFrameCallback(pjmedia_port *port, pjmedia_frame *frame);
|
||||
|
||||
static pj_status_t GetFrameCallback(pjmedia_port *port, pjmedia_frame *frame);
|
||||
|
||||
bool isActive;
|
||||
|
||||
pj_pool_t *pj_pool;
|
||||
pjmedia_port *media_port;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //TG2SIP_SOFTWAREAUDIOINPUT_H
|
|
@ -0,0 +1,81 @@
|
|||
#include <cassert>
|
||||
#include "SoftwareAudioOutput.h"
|
||||
|
||||
using namespace tgvoip::audio;
|
||||
|
||||
SoftwareAudioOutput::SoftwareAudioOutput() {
|
||||
isActive = false;
|
||||
|
||||
pj_pool = pjsua_pool_create("output%p", 2048, 512);
|
||||
media_port = PJ_POOL_ZALLOC_T(pj_pool, pjmedia_port);
|
||||
|
||||
pj_status_t status;
|
||||
pj_str_t name = pj_str((char *) "output");
|
||||
|
||||
// ptime = 10ms -> 480 samples per frame
|
||||
status = pjmedia_port_info_init(&media_port->info,
|
||||
&name,
|
||||
PJMEDIA_SIG_CLASS_PORT_AUD('S', 'O'), // Software Output SIG
|
||||
48000, 1, 16, 480);
|
||||
assert(status == PJ_SUCCESS);
|
||||
|
||||
media_port->port_data.pdata = this;
|
||||
media_port->put_frame = &PutFrameCallback;
|
||||
media_port->get_frame = &GetFrameCallback;
|
||||
|
||||
registerMediaPort(media_port);
|
||||
|
||||
// 48kHz * 20 ms * 16 bits per sample
|
||||
buffer = new unsigned char[1920];
|
||||
}
|
||||
|
||||
SoftwareAudioOutput::~SoftwareAudioOutput() {
|
||||
unregisterMediaPort();
|
||||
pjmedia_port_destroy(media_port);
|
||||
pj_pool_release(pj_pool);
|
||||
if (buffer) {
|
||||
delete buffer;
|
||||
}
|
||||
}
|
||||
|
||||
void SoftwareAudioOutput::Start() {
|
||||
isActive = true;
|
||||
}
|
||||
|
||||
void SoftwareAudioOutput::Stop() {
|
||||
isActive = false;
|
||||
}
|
||||
|
||||
bool SoftwareAudioOutput::IsPlaying() {
|
||||
return isActive;
|
||||
}
|
||||
|
||||
pj_status_t SoftwareAudioOutput::PutFrameCallback(pjmedia_port *port, pjmedia_frame *frame) {
|
||||
|
||||
frame->size = 0;
|
||||
frame->type = PJMEDIA_FRAME_TYPE_NONE;
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
pj_status_t SoftwareAudioOutput::GetFrameCallback(pjmedia_port *port, pjmedia_frame *frame) {
|
||||
|
||||
auto output = (SoftwareAudioOutput *) port->port_data.pdata;
|
||||
|
||||
if (!output->isActive) {
|
||||
frame->type = PJMEDIA_FRAME_TYPE_NONE;
|
||||
frame->size = 0;
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
// libtgvoip ptime = 20ms
|
||||
if (output->read_buffer) {
|
||||
output->InvokeCallback(output->buffer, 1920);
|
||||
memcpy(frame->buf, output->buffer, 960);
|
||||
} else {
|
||||
memcpy(frame->buf, output->buffer + 960, 960);
|
||||
}
|
||||
|
||||
output->read_buffer = !output->read_buffer;
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef TG2SIP_SOFTWAREAUDIOOUTPUT_H
|
||||
#define TG2SIP_SOFTWAREAUDIOOUTPUT_H
|
||||
|
||||
#include <pjsua2.hpp>
|
||||
#include "AudioOutput.h"
|
||||
#include "../threading.h"
|
||||
|
||||
namespace tgvoip {
|
||||
namespace audio {
|
||||
class SoftwareAudioOutput : public AudioOutput, public pj::AudioMedia {
|
||||
public:
|
||||
explicit SoftwareAudioOutput();
|
||||
|
||||
virtual ~SoftwareAudioOutput();
|
||||
|
||||
void Start() override;
|
||||
|
||||
void Stop() override;
|
||||
|
||||
virtual bool IsPlaying();
|
||||
|
||||
private:
|
||||
static pj_status_t PutFrameCallback(pjmedia_port *port, pjmedia_frame *frame);
|
||||
|
||||
static pj_status_t GetFrameCallback(pjmedia_port *port, pjmedia_frame *frame);
|
||||
|
||||
bool isActive;
|
||||
|
||||
pj_pool_t *pj_pool;
|
||||
pjmedia_port *media_port;
|
||||
|
||||
bool read_buffer{true};
|
||||
unsigned char *buffer;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //TG2SIP_SOFTWAREAUDIOOUTPUT_H
|
|
@ -22,7 +22,48 @@
|
|||
#include "os/darwin/DarwinSpecific.h"
|
||||
#endif
|
||||
|
||||
#ifdef TGVOIP_USE_SPDLOG
|
||||
#include <memory>
|
||||
#include "spdlog/spdlog.h"
|
||||
#endif
|
||||
|
||||
FILE* tgvoipLogFile=NULL;
|
||||
#ifdef TGVOIP_USE_SPDLOG
|
||||
std::shared_ptr<spdlog::logger> _voip_logger;
|
||||
|
||||
void tgvoip_log_spdlog(char level, const char* msg, ...) {
|
||||
if (_voip_logger) {
|
||||
spdlog::level::level_enum lvl;
|
||||
switch (level) {
|
||||
case 'V':
|
||||
lvl = spdlog::level::level_enum::trace;
|
||||
break;
|
||||
case 'D':
|
||||
lvl = spdlog::level::level_enum::debug;
|
||||
break;
|
||||
case 'I':
|
||||
lvl = spdlog::level::level_enum::info;
|
||||
break;
|
||||
case 'W':
|
||||
lvl = spdlog::level::level_enum::warn;
|
||||
break;
|
||||
case 'E':
|
||||
lvl = spdlog::level::level_enum::err;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, msg);
|
||||
|
||||
char buf[1024];
|
||||
vsprintf(buf, msg, argptr);
|
||||
_voip_logger->log(lvl, buf);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void tgvoip_log_file_printf(char level, const char* msg, ...){
|
||||
if(tgvoipLogFile){
|
||||
|
|
|
@ -13,11 +13,19 @@
|
|||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
#ifdef TGVOIP_USE_SPDLOG
|
||||
#include "spdlog/spdlog.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void tgvoip_log_file_printf(char level, const char* msg, ...);
|
||||
void tgvoip_log_file_write_header(FILE* file);
|
||||
|
||||
#ifdef TGVOIP_USE_SPDLOG
|
||||
void tgvoip_log_spdlog(char level, const char* msg, ...);
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
#include <android/log.h>
|
||||
|
@ -58,7 +66,11 @@ void tgvoip_log_file_write_header(FILE* file);
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef TGVOIP_USE_SPDLOG
|
||||
#define _TGVOIP_LOG_PRINT(verb, msg, ...) {tgvoip_log_spdlog(verb, msg, ##__VA_ARGS__);}
|
||||
#else
|
||||
#define _TGVOIP_LOG_PRINT(verb, msg, ...) {printf("%c/tgvoip: " msg "\n", verb, ##__VA_ARGS__); tgvoip_log_file_printf(verb, msg, ##__VA_ARGS__);}
|
||||
#endif
|
||||
|
||||
#define LOGV(msg, ...) _TGVOIP_LOG_PRINT('V', msg, ##__VA_ARGS__)
|
||||
#define LOGD(msg, ...) _TGVOIP_LOG_PRINT('D', msg, ##__VA_ARGS__)
|
||||
|
|
|
@ -26,6 +26,11 @@ extern jclass jniUtilitiesClass;
|
|||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
// fix of undef in pjsip
|
||||
#if defined(TGVOIP_USE_SOFTWARE_AUDIO)
|
||||
#define s6_addr __in6_u.__u6_addr8
|
||||
#endif
|
||||
|
||||
using namespace tgvoip;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue