mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-07 23:03:35 +00:00
2.2
- Refactored audio I/O to allow sharing a common context between input and output, for those OSes that require this - Rewritten periodic operation handling to use a "run loop" thingy instead of an ugly loop formerly known as tick thread - Fixed a bunch of compiler warnings (closes #13) - Added automake so you no longer need to use the GYP file for standalone builds (closes #43)
This commit is contained in:
parent
dacde29548
commit
5380aaba0d
81
Buffers.h
81
Buffers.h
@ -11,7 +11,11 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <array>
|
||||||
|
#include <limits>
|
||||||
|
#include <stddef.h>
|
||||||
#include "threading.h"
|
#include "threading.h"
|
||||||
|
|
||||||
namespace tgvoip{
|
namespace tgvoip{
|
||||||
@ -157,6 +161,83 @@ namespace tgvoip{
|
|||||||
unsigned char* data;
|
unsigned char* data;
|
||||||
size_t length;
|
size_t length;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, size_t size, typename AVG_T=T> class HistoricBuffer{
|
||||||
|
public:
|
||||||
|
HistoricBuffer(){
|
||||||
|
std::fill(data.begin(), data.end(), (T)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
AVG_T Average(){
|
||||||
|
AVG_T avg=(AVG_T)0;
|
||||||
|
for(T& i:data){
|
||||||
|
avg+=i;
|
||||||
|
}
|
||||||
|
return avg/(AVG_T)size;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVG_T Average(size_t firstN){
|
||||||
|
AVG_T avg=(AVG_T)0;
|
||||||
|
for(size_t i=0;i<firstN;i++){
|
||||||
|
avg+=(*this)[i];
|
||||||
|
}
|
||||||
|
return avg/(AVG_T)firstN;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVG_T NonZeroAverage(){
|
||||||
|
AVG_T avg=(AVG_T)0;
|
||||||
|
int nonZeroCount=0;
|
||||||
|
for(T& i:data){
|
||||||
|
if(i!=0){
|
||||||
|
nonZeroCount++;
|
||||||
|
avg+=i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(nonZeroCount==0)
|
||||||
|
return (AVG_T)0;
|
||||||
|
return avg/(AVG_T)nonZeroCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add(T el){
|
||||||
|
data[offset]=el;
|
||||||
|
offset=(offset+1)%size;
|
||||||
|
}
|
||||||
|
|
||||||
|
T Min(){
|
||||||
|
T min=std::numeric_limits<T>::max();
|
||||||
|
for(T& i:data){
|
||||||
|
if(i<min)
|
||||||
|
min=i;
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
T Max(){
|
||||||
|
T max=std::numeric_limits<T>::min();
|
||||||
|
for(T& i:data){
|
||||||
|
if(i>max)
|
||||||
|
max=i;
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset(){
|
||||||
|
std::fill(data.begin(), data.end(), (T)0);
|
||||||
|
offset=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator[](size_t i){
|
||||||
|
assert(i<size);
|
||||||
|
// [0] should return the most recent entry, [1] the one before it, and so on
|
||||||
|
ptrdiff_t _i=offset-i-1;
|
||||||
|
if(_i<0)
|
||||||
|
_i=size+_i;
|
||||||
|
return data[_i];
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::array<T, size> data;
|
||||||
|
ptrdiff_t offset=0;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //LIBTGVOIP_BUFFERINPUTSTREAM_H
|
#endif //LIBTGVOIP_BUFFERINPUTSTREAM_H
|
||||||
|
|||||||
@ -15,16 +15,10 @@
|
|||||||
using namespace tgvoip;
|
using namespace tgvoip;
|
||||||
|
|
||||||
CongestionControl::CongestionControl(){
|
CongestionControl::CongestionControl(){
|
||||||
memset(rttHistory, 0, sizeof(rttHistory));
|
|
||||||
memset(inflightPackets, 0, sizeof(inflightPackets));
|
memset(inflightPackets, 0, sizeof(inflightPackets));
|
||||||
memset(inflightHistory, 0, sizeof(inflightHistory));
|
|
||||||
tmpRtt=0;
|
tmpRtt=0;
|
||||||
tmpRttCount=0;
|
tmpRttCount=0;
|
||||||
rttHistorySize=0;
|
|
||||||
rttHistoryTop=0;
|
|
||||||
lastSentSeq=0;
|
lastSentSeq=0;
|
||||||
inflightHistoryTop=0;
|
|
||||||
state=TGVOIP_CONCTL_STARTUP;
|
|
||||||
lastActionTime=0;
|
lastActionTime=0;
|
||||||
lastActionRtt=0;
|
lastActionRtt=0;
|
||||||
stateTransitionTime=0;
|
stateTransitionTime=0;
|
||||||
@ -41,25 +35,11 @@ size_t CongestionControl::GetAcknowledgedDataSize(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
double CongestionControl::GetAverageRTT(){
|
double CongestionControl::GetAverageRTT(){
|
||||||
if(rttHistorySize==0)
|
return rttHistory.NonZeroAverage();
|
||||||
return 0;
|
|
||||||
double avg=0;
|
|
||||||
int i;
|
|
||||||
for(i=0;i<30 && i<rttHistorySize;i++){
|
|
||||||
int x=(rttHistoryTop-i-1)%100;
|
|
||||||
avg+=rttHistory[x>=0 ? x : (100+x)];
|
|
||||||
//LOGV("adding [%d] %f", x>=0 ? x : (100+x), rttHistory[x>=0 ? x : (100+x)]);
|
|
||||||
}
|
|
||||||
return avg/i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CongestionControl::GetInflightDataSize(){
|
size_t CongestionControl::GetInflightDataSize(){
|
||||||
size_t avg=0;
|
return inflightHistory.Average();
|
||||||
int i;
|
|
||||||
for(i=0;i<30;i++){
|
|
||||||
avg+=inflightHistory[i];
|
|
||||||
}
|
|
||||||
return avg/30;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -68,13 +48,7 @@ size_t CongestionControl::GetCongestionWindow(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
double CongestionControl::GetMinimumRTT(){
|
double CongestionControl::GetMinimumRTT(){
|
||||||
int i;
|
return rttHistory.Min();
|
||||||
double min=INFINITY;
|
|
||||||
for(i=0;i<100;i++){
|
|
||||||
if(rttHistory[i]>0 && rttHistory[i]<min)
|
|
||||||
min=rttHistory[i];
|
|
||||||
}
|
|
||||||
return min;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CongestionControl::PacketAcknowledged(uint32_t seq){
|
void CongestionControl::PacketAcknowledged(uint32_t seq){
|
||||||
@ -128,10 +102,7 @@ void CongestionControl::Tick(){
|
|||||||
tickCount++;
|
tickCount++;
|
||||||
MutexGuard sync(mutex);
|
MutexGuard sync(mutex);
|
||||||
if(tmpRttCount>0){
|
if(tmpRttCount>0){
|
||||||
rttHistory[rttHistoryTop]=tmpRtt/tmpRttCount;
|
rttHistory.Add(tmpRtt/tmpRttCount);
|
||||||
rttHistoryTop=(rttHistoryTop+1)%100;
|
|
||||||
if(rttHistorySize<100)
|
|
||||||
rttHistorySize++;
|
|
||||||
tmpRtt=0;
|
tmpRtt=0;
|
||||||
tmpRttCount=0;
|
tmpRttCount=0;
|
||||||
}
|
}
|
||||||
@ -144,8 +115,7 @@ void CongestionControl::Tick(){
|
|||||||
LOGD("Packet with seq %u was not acknowledged", inflightPackets[i].seq);
|
LOGD("Packet with seq %u was not acknowledged", inflightPackets[i].seq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inflightHistory[inflightHistoryTop]=inflightDataSize;
|
inflightHistory.Add(inflightDataSize);
|
||||||
inflightHistoryTop=(inflightHistoryTop+1)%30;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -10,11 +10,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "threading.h"
|
#include "threading.h"
|
||||||
|
#include "Buffers.h"
|
||||||
#define TGVOIP_CONCTL_STARTUP 0
|
|
||||||
#define TGVOIP_CONCTL_DRAIN 1
|
|
||||||
#define TGVOIP_CONCTL_PROBE_BW 2
|
|
||||||
#define TGVOIP_CONCTL_PROBE_RTT 3
|
|
||||||
|
|
||||||
#define TGVOIP_CONCTL_ACT_INCREASE 1
|
#define TGVOIP_CONCTL_ACT_INCREASE 1
|
||||||
#define TGVOIP_CONCTL_ACT_DECREASE 2
|
#define TGVOIP_CONCTL_ACT_DECREASE 2
|
||||||
@ -47,19 +43,15 @@ public:
|
|||||||
uint32_t GetSendLossCount();
|
uint32_t GetSendLossCount();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double rttHistory[100];
|
HistoricBuffer<double, 100> rttHistory;
|
||||||
|
HistoricBuffer<size_t, 30> inflightHistory;
|
||||||
tgvoip_congestionctl_packet_t inflightPackets[100];
|
tgvoip_congestionctl_packet_t inflightPackets[100];
|
||||||
size_t inflightHistory[30];
|
|
||||||
int state;
|
|
||||||
uint32_t lossCount;
|
uint32_t lossCount;
|
||||||
double tmpRtt;
|
double tmpRtt;
|
||||||
double lastActionTime;
|
double lastActionTime;
|
||||||
double lastActionRtt;
|
double lastActionRtt;
|
||||||
double stateTransitionTime;
|
double stateTransitionTime;
|
||||||
int tmpRttCount;
|
int tmpRttCount;
|
||||||
char rttHistorySize;
|
|
||||||
unsigned int rttHistoryTop;
|
|
||||||
unsigned int inflightHistoryTop;
|
|
||||||
uint32_t lastSentSeq;
|
uint32_t lastSentSeq;
|
||||||
uint32_t tickCount;
|
uint32_t tickCount;
|
||||||
size_t inflightDataSize;
|
size_t inflightDataSize;
|
||||||
|
|||||||
@ -40,13 +40,12 @@ namespace webrtc{
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
EchoCanceller::EchoCanceller(bool enableAEC, bool enableNS, bool enableAGC){
|
EchoCanceller::EchoCanceller(bool enableAEC, bool enableNS, bool enableAGC){
|
||||||
|
#ifndef TGVOIP_NO_DSP
|
||||||
this->enableAEC=enableAEC;
|
this->enableAEC=enableAEC;
|
||||||
this->enableAGC=enableAGC;
|
this->enableAGC=enableAGC;
|
||||||
this->enableNS=enableNS;
|
this->enableNS=enableNS;
|
||||||
isOn=true;
|
isOn=true;
|
||||||
|
|
||||||
#ifndef TGVOIP_NO_DSP
|
|
||||||
|
|
||||||
splittingFilter=new webrtc::SplittingFilter(1, 3, 960);
|
splittingFilter=new webrtc::SplittingFilter(1, 3, 960);
|
||||||
splittingFilterFarend=new webrtc::SplittingFilter(1, 3, 960);
|
splittingFilterFarend=new webrtc::SplittingFilter(1, 3, 960);
|
||||||
|
|
||||||
@ -111,10 +110,14 @@ EchoCanceller::EchoCanceller(bool enableAEC, bool enableNS, bool enableAGC){
|
|||||||
}else{
|
}else{
|
||||||
agc=NULL;
|
agc=NULL;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
this->enableAEC=this->enableAGC=enableAGC=this->enableNS=enableNS=false;
|
||||||
|
isOn=true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
EchoCanceller::~EchoCanceller(){
|
EchoCanceller::~EchoCanceller(){
|
||||||
|
#ifndef TGVOIP_NO_DSP
|
||||||
if(enableAEC){
|
if(enableAEC){
|
||||||
running=false;
|
running=false;
|
||||||
farendQueue->Put(NULL);
|
farendQueue->Put(NULL);
|
||||||
@ -147,6 +150,7 @@ EchoCanceller::~EchoCanceller(){
|
|||||||
delete (webrtc::IFChannelBuffer*)splittingFilterOut;
|
delete (webrtc::IFChannelBuffer*)splittingFilterOut;
|
||||||
delete (webrtc::IFChannelBuffer*)splittingFilterFarendIn;
|
delete (webrtc::IFChannelBuffer*)splittingFilterFarendIn;
|
||||||
delete (webrtc::IFChannelBuffer*)splittingFilterFarendOut;
|
delete (webrtc::IFChannelBuffer*)splittingFilterFarendOut;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void EchoCanceller::Start(){
|
void EchoCanceller::Start(){
|
||||||
@ -166,13 +170,16 @@ void EchoCanceller::SpeakerOutCallback(unsigned char* data, size_t len){
|
|||||||
WebRtcAecm_BufferFarend(state, (int16_t*)(data+offset), AEC_FRAME_SIZE);
|
WebRtcAecm_BufferFarend(state, (int16_t*)(data+offset), AEC_FRAME_SIZE);
|
||||||
offset+=OFFSET_STEP;
|
offset+=OFFSET_STEP;
|
||||||
}*/
|
}*/
|
||||||
|
#ifndef TGVOIP_NO_DSP
|
||||||
int16_t* buf=(int16_t*)farendBufferPool->Get();
|
int16_t* buf=(int16_t*)farendBufferPool->Get();
|
||||||
if(buf){
|
if(buf){
|
||||||
memcpy(buf, data, 960*2);
|
memcpy(buf, data, 960*2);
|
||||||
farendQueue->Put(buf);
|
farendQueue->Put(buf);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TGVOIP_NO_DSP
|
||||||
void EchoCanceller::RunBufferFarendThread(void* arg){
|
void EchoCanceller::RunBufferFarendThread(void* arg){
|
||||||
while(running){
|
while(running){
|
||||||
int16_t* samplesIn=farendQueue->GetBlocking();
|
int16_t* samplesIn=farendQueue->GetBlocking();
|
||||||
@ -197,6 +204,7 @@ void EchoCanceller::RunBufferFarendThread(void* arg){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void EchoCanceller::Enable(bool enabled){
|
void EchoCanceller::Enable(bool enabled){
|
||||||
isOn=enabled;
|
isOn=enabled;
|
||||||
@ -208,6 +216,7 @@ void EchoCanceller::ProcessInput(unsigned char* data, unsigned char* out, size_t
|
|||||||
memcpy(out, data, len);
|
memcpy(out, data, len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifndef TGVOIP_NO_DSP
|
||||||
int16_t* samplesIn=(int16_t*)data;
|
int16_t* samplesIn=(int16_t*)data;
|
||||||
int16_t* samplesOut=(int16_t*)out;
|
int16_t* samplesOut=(int16_t*)out;
|
||||||
|
|
||||||
@ -355,9 +364,11 @@ void EchoCanceller::ProcessInput(unsigned char* data, unsigned char* out, size_t
|
|||||||
((webrtc::SplittingFilter*)splittingFilter)->Synthesis(bufOut, bufIn);
|
((webrtc::SplittingFilter*)splittingFilter)->Synthesis(bufOut, bufIn);
|
||||||
|
|
||||||
memcpy(samplesOut, bufIn->ibuf_const()->bands(0)[0], 960*2);
|
memcpy(samplesOut, bufIn->ibuf_const()->bands(0)[0], 960*2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void EchoCanceller::SetAECStrength(int strength){
|
void EchoCanceller::SetAECStrength(int strength){
|
||||||
|
#ifndef TGVOIP_NO_DSP
|
||||||
if(aec){
|
if(aec){
|
||||||
#ifndef TGVOIP_USE_DESKTOP_DSP
|
#ifndef TGVOIP_USE_DESKTOP_DSP
|
||||||
AecmConfig cfg;
|
AecmConfig cfg;
|
||||||
@ -366,6 +377,7 @@ void EchoCanceller::SetAECStrength(int strength){
|
|||||||
WebRtcAecm_set_config(aec, cfg);
|
WebRtcAecm_set_config(aec, cfg);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioEffect::~AudioEffect(){
|
AudioEffect::~AudioEffect(){
|
||||||
@ -377,6 +389,7 @@ void AudioEffect::SetPassThrough(bool passThrough){
|
|||||||
}
|
}
|
||||||
|
|
||||||
AutomaticGainControl::AutomaticGainControl(){
|
AutomaticGainControl::AutomaticGainControl(){
|
||||||
|
#ifndef TGVOIP_NO_DSP
|
||||||
splittingFilter=new webrtc::SplittingFilter(1, 3, 960);
|
splittingFilter=new webrtc::SplittingFilter(1, 3, 960);
|
||||||
splittingFilterIn=new webrtc::IFChannelBuffer(960, 1, 1);
|
splittingFilterIn=new webrtc::IFChannelBuffer(960, 1, 1);
|
||||||
splittingFilterOut=new webrtc::IFChannelBuffer(960, 1, 3);
|
splittingFilterOut=new webrtc::IFChannelBuffer(960, 1, 3);
|
||||||
@ -389,16 +402,20 @@ AutomaticGainControl::AutomaticGainControl(){
|
|||||||
WebRtcAgc_Init(agc, 0, 255, kAgcModeAdaptiveDigital, 48000);
|
WebRtcAgc_Init(agc, 0, 255, kAgcModeAdaptiveDigital, 48000);
|
||||||
WebRtcAgc_set_config(agc, agcConfig);
|
WebRtcAgc_set_config(agc, agcConfig);
|
||||||
agcMicLevel=0;
|
agcMicLevel=0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
AutomaticGainControl::~AutomaticGainControl(){
|
AutomaticGainControl::~AutomaticGainControl(){
|
||||||
|
#ifndef TGVOIP_NO_DSP
|
||||||
delete (webrtc::SplittingFilter*)splittingFilter;
|
delete (webrtc::SplittingFilter*)splittingFilter;
|
||||||
delete (webrtc::IFChannelBuffer*)splittingFilterIn;
|
delete (webrtc::IFChannelBuffer*)splittingFilterIn;
|
||||||
delete (webrtc::IFChannelBuffer*)splittingFilterOut;
|
delete (webrtc::IFChannelBuffer*)splittingFilterOut;
|
||||||
WebRtcAgc_Free(agc);
|
WebRtcAgc_Free(agc);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutomaticGainControl::Process(int16_t *inOut, size_t numSamples){
|
void AutomaticGainControl::Process(int16_t *inOut, size_t numSamples){
|
||||||
|
#ifndef TGVOIP_NO_DSP
|
||||||
if(passThrough)
|
if(passThrough)
|
||||||
return;
|
return;
|
||||||
if(numSamples!=960){
|
if(numSamples!=960){
|
||||||
@ -438,5 +455,6 @@ void AutomaticGainControl::Process(int16_t *inOut, size_t numSamples){
|
|||||||
((webrtc::SplittingFilter*)splittingFilter)->Synthesis(bufOut, bufIn);
|
((webrtc::SplittingFilter*)splittingFilter)->Synthesis(bufOut, bufIn);
|
||||||
|
|
||||||
memcpy(inOut, bufIn->ibuf_const()->bands(0)[0], 960*2);
|
memcpy(inOut, bufIn->ibuf_const()->bands(0)[0], 960*2);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,14 +17,6 @@ JitterBuffer::JitterBuffer(MediaStreamItf *out, uint32_t step):bufferPool(JITTER
|
|||||||
out->SetCallback(JitterBuffer::CallbackOut, this);
|
out->SetCallback(JitterBuffer::CallbackOut, this);
|
||||||
this->step=step;
|
this->step=step;
|
||||||
memset(slots, 0, sizeof(jitter_packet_t)*JITTER_SLOT_COUNT);
|
memset(slots, 0, sizeof(jitter_packet_t)*JITTER_SLOT_COUNT);
|
||||||
minDelay=6;
|
|
||||||
lostCount=0;
|
|
||||||
needBuffering=true;
|
|
||||||
tickCount=0;
|
|
||||||
dontIncMinDelay=0;
|
|
||||||
dontDecMinDelay=0;
|
|
||||||
lostPackets=0;
|
|
||||||
outstandingDelayChange=0;
|
|
||||||
if(step<30){
|
if(step<30){
|
||||||
minMinDelay=(uint32_t) ServerConfig::GetSharedInstance()->GetInt("jitter_min_delay_20", 6);
|
minMinDelay=(uint32_t) ServerConfig::GetSharedInstance()->GetInt("jitter_min_delay_20", 6);
|
||||||
maxMinDelay=(uint32_t) ServerConfig::GetSharedInstance()->GetInt("jitter_max_delay_20", 25);
|
maxMinDelay=(uint32_t) ServerConfig::GetSharedInstance()->GetInt("jitter_max_delay_20", 25);
|
||||||
@ -101,14 +93,13 @@ void JitterBuffer::Reset(){
|
|||||||
slots[i].buffer=NULL;
|
slots[i].buffer=NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memset(delayHistory, 0, sizeof(delayHistory));
|
delayHistory.Reset();
|
||||||
memset(lateHistory, 0, sizeof(lateHistory));
|
lateHistory.Reset();
|
||||||
adjustingDelay=false;
|
adjustingDelay=false;
|
||||||
lostSinceReset=0;
|
lostSinceReset=0;
|
||||||
gotSinceReset=0;
|
gotSinceReset=0;
|
||||||
expectNextAtTime=0;
|
expectNextAtTime=0;
|
||||||
memset(deviationHistory, 0, sizeof(deviationHistory));
|
deviationHistory.Reset();
|
||||||
deviationPtr=0;
|
|
||||||
outstandingDelayChange=0;
|
outstandingDelayChange=0;
|
||||||
dontChangeDelay=0;
|
dontChangeDelay=0;
|
||||||
}
|
}
|
||||||
@ -124,15 +115,6 @@ size_t JitterBuffer::HandleOutput(unsigned char *buffer, size_t len, int offsetI
|
|||||||
if(outstandingDelayChange<0){
|
if(outstandingDelayChange<0){
|
||||||
playbackScaledDuration=40;
|
playbackScaledDuration=40;
|
||||||
outstandingDelayChange+=20;
|
outstandingDelayChange+=20;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
playbackScaledDuration=80;
|
playbackScaledDuration=80;
|
||||||
outstandingDelayChange-=20;
|
outstandingDelayChange-=20;
|
||||||
@ -265,8 +247,7 @@ void JitterBuffer::PutInternal(jitter_packet_t* pkt, bool overwriteExisting){
|
|||||||
if(expectNextAtTime!=0){
|
if(expectNextAtTime!=0){
|
||||||
double dev=expectNextAtTime-time;
|
double dev=expectNextAtTime-time;
|
||||||
//LOGV("packet dev %f", dev);
|
//LOGV("packet dev %f", dev);
|
||||||
deviationHistory[deviationPtr]=dev;
|
deviationHistory.Add(dev);
|
||||||
deviationPtr=(deviationPtr+1)%64;
|
|
||||||
expectNextAtTime+=step/1000.0;
|
expectNextAtTime+=step/1000.0;
|
||||||
}else{
|
}else{
|
||||||
expectNextAtTime=time+step/1000.0;
|
expectNextAtTime=time+step/1000.0;
|
||||||
@ -338,27 +319,14 @@ void JitterBuffer::Tick(){
|
|||||||
MutexGuard m(mutex);
|
MutexGuard m(mutex);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memmove(&lateHistory[1], lateHistory, 63*sizeof(int));
|
lateHistory.Add(latePacketCount);
|
||||||
lateHistory[0]=latePacketCount;
|
|
||||||
latePacketCount=0;
|
latePacketCount=0;
|
||||||
bool absolutelyNoLatePackets=true;
|
bool absolutelyNoLatePackets=lateHistory.Max()==0;
|
||||||
|
|
||||||
double avgLate64=0, avgLate32=0, avgLate16=0;
|
double avgLate16=lateHistory.Average(16);
|
||||||
for(i=0;i<64;i++){
|
|
||||||
avgLate64+=lateHistory[i];
|
|
||||||
if(i<32)
|
|
||||||
avgLate32+=lateHistory[i];
|
|
||||||
if(i<16){
|
|
||||||
avgLate16+=lateHistory[i];
|
|
||||||
}
|
|
||||||
if(lateHistory[i]>0)
|
|
||||||
absolutelyNoLatePackets=false;
|
|
||||||
}
|
|
||||||
avgLate64/=64;
|
|
||||||
avgLate32/=32;
|
|
||||||
avgLate16/=16;
|
|
||||||
//LOGV("jitter: avg late=%.1f, %.1f, %.1f", avgLate16, avgLate32, avgLate64);
|
//LOGV("jitter: avg late=%.1f, %.1f, %.1f", avgLate16, avgLate32, avgLate64);
|
||||||
if(avgLate16>=resyncThreshold){
|
if(avgLate16>=resyncThreshold){
|
||||||
|
LOGV("resyncing: avgLate16=%f, resyncThreshold=%f", avgLate16, resyncThreshold);
|
||||||
wasReset=true;
|
wasReset=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,24 +335,11 @@ void JitterBuffer::Tick(){
|
|||||||
dontDecMinDelay--;
|
dontDecMinDelay--;
|
||||||
}
|
}
|
||||||
|
|
||||||
memmove(&delayHistory[1], delayHistory, 63*sizeof(int));
|
delayHistory.Add(GetCurrentDelay());
|
||||||
delayHistory[0]=GetCurrentDelay();
|
avgDelay=delayHistory.Average(32);
|
||||||
|
|
||||||
avgDelay=0;
|
|
||||||
int min=100;
|
|
||||||
for(i=0;i<32;i++){
|
|
||||||
avgDelay+=delayHistory[i];
|
|
||||||
if(delayHistory[i]<min)
|
|
||||||
min=delayHistory[i];
|
|
||||||
}
|
|
||||||
avgDelay/=32;
|
|
||||||
|
|
||||||
double stddev=0;
|
double stddev=0;
|
||||||
double avgdev=0;
|
double avgdev=deviationHistory.Average();
|
||||||
for(i=0;i<64;i++){
|
|
||||||
avgdev+=deviationHistory[i];
|
|
||||||
}
|
|
||||||
avgdev/=64;
|
|
||||||
for(i=0;i<64;i++){
|
for(i=0;i<64;i++){
|
||||||
double d=(deviationHistory[i]-avgdev);
|
double d=(deviationHistory[i]-avgdev);
|
||||||
stddev+=(d*d);
|
stddev+=(d*d);
|
||||||
@ -409,7 +364,7 @@ void JitterBuffer::Tick(){
|
|||||||
minDelay+=diff;
|
minDelay+=diff;
|
||||||
outstandingDelayChange+=diff*60;
|
outstandingDelayChange+=diff*60;
|
||||||
dontChangeDelay+=32;
|
dontChangeDelay+=32;
|
||||||
LOGD("new delay from stddev %f", minDelay);
|
//LOGD("new delay from stddev %f", minDelay);
|
||||||
if(diff<0){
|
if(diff<0){
|
||||||
dontDecMinDelay+=25;
|
dontDecMinDelay+=25;
|
||||||
}
|
}
|
||||||
@ -460,18 +415,7 @@ void JitterBuffer::Tick(){
|
|||||||
|
|
||||||
|
|
||||||
void JitterBuffer::GetAverageLateCount(double *out){
|
void JitterBuffer::GetAverageLateCount(double *out){
|
||||||
double avgLate64=0, avgLate32=0, avgLate16=0;
|
double avgLate64=lateHistory.Average(), avgLate32=lateHistory.Average(32), avgLate16=lateHistory.Average(16);
|
||||||
int i;
|
|
||||||
for(i=0;i<64;i++){
|
|
||||||
avgLate64+=lateHistory[i];
|
|
||||||
if(i<32)
|
|
||||||
avgLate32+=lateHistory[i];
|
|
||||||
if(i<16)
|
|
||||||
avgLate16+=lateHistory[i];
|
|
||||||
}
|
|
||||||
avgLate64/=64;
|
|
||||||
avgLate32/=32;
|
|
||||||
avgLate16/=16;
|
|
||||||
out[0]=avgLate16;
|
out[0]=avgLate16;
|
||||||
out[1]=avgLate32;
|
out[1]=avgLate32;
|
||||||
out[2]=avgLate64;
|
out[2]=avgLate64;
|
||||||
|
|||||||
@ -57,37 +57,36 @@ private:
|
|||||||
BufferPool bufferPool;
|
BufferPool bufferPool;
|
||||||
Mutex mutex;
|
Mutex mutex;
|
||||||
jitter_packet_t slots[JITTER_SLOT_COUNT];
|
jitter_packet_t slots[JITTER_SLOT_COUNT];
|
||||||
int64_t nextTimestamp;
|
int64_t nextTimestamp=0;
|
||||||
uint32_t step;
|
uint32_t step;
|
||||||
double minDelay;
|
double minDelay=6;
|
||||||
uint32_t minMinDelay;
|
uint32_t minMinDelay;
|
||||||
uint32_t maxMinDelay;
|
uint32_t maxMinDelay;
|
||||||
uint32_t maxUsedSlots;
|
uint32_t maxUsedSlots;
|
||||||
uint32_t lastPutTimestamp;
|
uint32_t lastPutTimestamp;
|
||||||
uint32_t lossesToReset;
|
uint32_t lossesToReset;
|
||||||
double resyncThreshold;
|
double resyncThreshold;
|
||||||
unsigned int lostCount;
|
unsigned int lostCount=0;
|
||||||
unsigned int lostSinceReset;
|
unsigned int lostSinceReset=0;
|
||||||
unsigned int gotSinceReset;
|
unsigned int gotSinceReset=0;
|
||||||
bool wasReset;
|
bool wasReset=true;
|
||||||
bool needBuffering;
|
bool needBuffering=true;
|
||||||
int delayHistory[64];
|
HistoricBuffer<int, 64, double> delayHistory;
|
||||||
int lateHistory[64];
|
HistoricBuffer<int, 64, double> lateHistory;
|
||||||
bool adjustingDelay;
|
bool adjustingDelay=false;
|
||||||
unsigned int tickCount;
|
unsigned int tickCount=0;
|
||||||
unsigned int latePacketCount;
|
unsigned int latePacketCount=0;
|
||||||
unsigned int dontIncMinDelay;
|
unsigned int dontIncMinDelay=0;
|
||||||
unsigned int dontDecMinDelay;
|
unsigned int dontDecMinDelay=0;
|
||||||
int lostPackets;
|
int lostPackets=0;
|
||||||
double prevRecvTime;
|
double prevRecvTime=0;
|
||||||
double expectNextAtTime;
|
double expectNextAtTime=0;
|
||||||
double deviationHistory[64];
|
HistoricBuffer<double, 64> deviationHistory;
|
||||||
int deviationPtr;
|
double lastMeasuredJitter=0;
|
||||||
double lastMeasuredJitter;
|
double lastMeasuredDelay=0;
|
||||||
double lastMeasuredDelay;
|
int outstandingDelayChange=0;
|
||||||
int outstandingDelayChange;
|
unsigned int dontChangeDelay=0;
|
||||||
unsigned int dontChangeDelay;
|
double avgDelay=0;
|
||||||
double avgDelay;
|
|
||||||
#ifdef TGVOIP_DUMP_JITTER_STATS
|
#ifdef TGVOIP_DUMP_JITTER_STATS
|
||||||
FILE* dump;
|
FILE* dump;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
268
Makefile.am
Normal file
268
Makefile.am
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
|
||||||
|
CFLAGS = -Wall -DHAVE_CONFIG_H -Wno-unknown-pragmas
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libtgvoip.la
|
||||||
|
|
||||||
|
SRC = VoIPController.cpp \
|
||||||
|
Buffers.cpp \
|
||||||
|
CongestionControl.cpp \
|
||||||
|
EchoCanceller.cpp \
|
||||||
|
JitterBuffer.cpp \
|
||||||
|
logging.cpp \
|
||||||
|
MediaStreamItf.cpp \
|
||||||
|
MessageThread.cpp \
|
||||||
|
NetworkSocket.cpp \
|
||||||
|
OpusDecoder.cpp \
|
||||||
|
OpusEncoder.cpp \
|
||||||
|
PacketReassembler.cpp \
|
||||||
|
VoIPGroupController.cpp \
|
||||||
|
VoIPServerConfig.cpp \
|
||||||
|
audio/AudioIO.cpp \
|
||||||
|
audio/AudioInput.cpp \
|
||||||
|
audio/AudioOutput.cpp \
|
||||||
|
audio/Resampler.cpp \
|
||||||
|
os/posix/NetworkSocketPosix.cpp
|
||||||
|
|
||||||
|
TGVOIP_HDRS = \
|
||||||
|
VoIPController.h \
|
||||||
|
Buffers.h \
|
||||||
|
BlockingQueue.h \
|
||||||
|
PrivateDefines.h \
|
||||||
|
CongestionControl.h \
|
||||||
|
EchoCanceller.h \
|
||||||
|
JitterBuffer.h \
|
||||||
|
logging.h \
|
||||||
|
threading.h \
|
||||||
|
MediaStreamItf.h \
|
||||||
|
MessageThread.h \
|
||||||
|
NetworkSocket.h \
|
||||||
|
OpusDecoder.h \
|
||||||
|
OpusEncoder.h \
|
||||||
|
PacketReassembler.h \
|
||||||
|
VoIPServerConfig.h \
|
||||||
|
audio/AudioIO.h \
|
||||||
|
audio/AudioInput.h \
|
||||||
|
audio/AudioOutput.h \
|
||||||
|
audio/Resampler.h \
|
||||||
|
os/posix/NetworkSocketPosix.h
|
||||||
|
|
||||||
|
if TARGET_OS_OSX
|
||||||
|
|
||||||
|
SRC += \
|
||||||
|
os/darwin/AudioInputAudioUnit.cpp \
|
||||||
|
os/darwin/AudioOutputAudioUnit.cpp \
|
||||||
|
os/darwin/AudioUnitIO.cpp \
|
||||||
|
os/darwin/AudioInputAudioUnitOSX.cpp \
|
||||||
|
os/darwin/AudioOutputAudioUnitOSX.cpp \
|
||||||
|
os/darwin/DarwinSpecific.mm
|
||||||
|
|
||||||
|
TGVOIP_HDRS += \
|
||||||
|
os/darwin/AudioInputAudioUnit.h \
|
||||||
|
os/darwin/AudioOutputAudioUnit.h \
|
||||||
|
os/darwin/AudioUnitIO.h \
|
||||||
|
os/darwin/AudioInputAudioUnitOSX.h \
|
||||||
|
os/darwin/AudioOutputAudioUnitOSX.h \
|
||||||
|
os/darwin/DarwinSpecific.h
|
||||||
|
|
||||||
|
LDFLAGS += -framework Foundation -framework CoreFoundation -framework CoreAudio -framework AudioToolbox
|
||||||
|
|
||||||
|
else
|
||||||
|
# Linux-specific
|
||||||
|
if WITH_ALSA
|
||||||
|
SRC += \
|
||||||
|
os/linux/AudioInputALSA.cpp \
|
||||||
|
os/linux/AudioOutputALSA.cpp
|
||||||
|
TGVOIP_HDRS += \
|
||||||
|
os/linux/AudioInputALSA.h \
|
||||||
|
os/linux/AudioOutputALSA.h
|
||||||
|
endif
|
||||||
|
|
||||||
|
if WITH_PULSE
|
||||||
|
SRC += \
|
||||||
|
os/linux/AudioOutputPulse.cpp \
|
||||||
|
os/linux/AudioInputPulse.cpp \
|
||||||
|
os/linux/AudioPulse.cpp
|
||||||
|
TGVOIP_HDRS += \
|
||||||
|
os/linux/AudioOutputPulse.h \
|
||||||
|
os/linux/AudioInputPulse.h \
|
||||||
|
os/linux/AudioPulse.h \
|
||||||
|
os/linux/PulseFunctions.h
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
if ENABLE_DSP
|
||||||
|
CFLAGS += -DWEBRTC_POSIX -DWEBRTC_APM_DEBUG_DUMP=0 -I$(top_srcdir)/webrtc_dsp
|
||||||
|
CCASFLAGS += -I$(top_srcdir)/webrtc_dsp
|
||||||
|
|
||||||
|
SRC += \
|
||||||
|
webrtc_dsp/webrtc/common_audio/ring_buffer.c \
|
||||||
|
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_fft.c \
|
||||||
|
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/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_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/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
|
||||||
|
|
||||||
|
SRC += \
|
||||||
|
webrtc_dsp/webrtc/base/checks.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aecm/aecm_core.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aecm/aecm_core_c.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aecm/echo_control_mobile.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/utility/delay_estimator.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/utility/delay_estimator_wrapper.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/three_band_filter_bank.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/splitting_filter.cc \
|
||||||
|
webrtc_dsp/webrtc/system_wrappers/source/cpu_features.cc \
|
||||||
|
webrtc_dsp/webrtc/common_audio/sparse_fir_filter.cc \
|
||||||
|
webrtc_dsp/webrtc/common_audio/channel_buffer.cc \
|
||||||
|
webrtc_dsp/webrtc/common_audio/audio_util.cc
|
||||||
|
|
||||||
|
SRC += \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/utility/block_mean_calculator.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/utility/ooura_fft.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/logging/apm_data_dumper.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_core.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_resampler.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aec/echo_cancellation.cc \
|
||||||
|
webrtc_dsp/webrtc/common_audio/wav_header.cc \
|
||||||
|
webrtc_dsp/webrtc/common_audio/wav_file.cc \
|
||||||
|
webrtc_dsp/webrtc/base/stringutils.cc
|
||||||
|
|
||||||
|
if TARGET_CPU_X86
|
||||||
|
SRC += \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_core_sse2.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/utility/ooura_fft_sse2.cc
|
||||||
|
endif
|
||||||
|
|
||||||
|
if TARGET_CPU_ARM
|
||||||
|
SRC += \
|
||||||
|
webrtc_dsp/webrtc/common_audio/signal_processing/complex_bit_reverse_arm.S \
|
||||||
|
webrtc_dsp/webrtc/common_audio/signal_processing/spl_sqrt_floor_arm.S
|
||||||
|
if TARGET_CPU_ARMV7
|
||||||
|
CFLAGS += -mfpu=neon -mfloat-abi=hard
|
||||||
|
CCASFLAGS += -mfpu=neon -mfloat-abi=hard
|
||||||
|
SRC += \
|
||||||
|
webrtc_dsp/webrtc/common_audio/signal_processing/cross_correlation_neon.c \
|
||||||
|
webrtc_dsp/webrtc/common_audio/signal_processing/downsample_fast_neon.c \
|
||||||
|
webrtc_dsp/webrtc/common_audio/signal_processing/min_max_operations_neon.c \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_core_neon.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aecm/aecm_core_neon.cc \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/ns/nsx_core_neon.c \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/utility/ooura_fft_neon.cc
|
||||||
|
# webrtc_dsp/webrtc/common_audio/signal_processing/filter_ar_fast_q12_armv7.S
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
SRC += \
|
||||||
|
webrtc_dsp/webrtc/common_audio/signal_processing/complex_bit_reverse.c \
|
||||||
|
webrtc_dsp/webrtc/common_audio/signal_processing/spl_sqrt_floor.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
SRC += \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/ns/noise_suppression_x.c \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/ns/noise_suppression.c \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/ns/ns_core.c \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/ns/nsx_core_c.c \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/ns/nsx_core.c \
|
||||||
|
webrtc_dsp/webrtc/common_audio/fft4g.c
|
||||||
|
|
||||||
|
SRC += \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/agc/legacy/analog_agc.c \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/agc/legacy/digital_agc.c
|
||||||
|
|
||||||
|
# headers
|
||||||
|
SRC += \
|
||||||
|
webrtc_dsp/webrtc/base/array_view.h \
|
||||||
|
webrtc_dsp/webrtc/base/atomicops.h \
|
||||||
|
webrtc_dsp/webrtc/base/basictypes.h \
|
||||||
|
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.h \
|
||||||
|
webrtc_dsp/webrtc/base/type_traits.h \
|
||||||
|
webrtc_dsp/webrtc/common_audio/channel_buffer.h \
|
||||||
|
webrtc_dsp/webrtc/common_audio/fft4g.h \
|
||||||
|
webrtc_dsp/webrtc/common_audio/include/audio_util.h \
|
||||||
|
webrtc_dsp/webrtc/common_audio/ring_buffer.h \
|
||||||
|
webrtc_dsp/webrtc/common_audio/signal_processing/complex_fft_tables.h \
|
||||||
|
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_armv7.h \
|
||||||
|
webrtc_dsp/webrtc/common_audio/signal_processing/include/spl_inl_mips.h \
|
||||||
|
webrtc_dsp/webrtc/common_audio/signal_processing/resample_by_2_internal.h \
|
||||||
|
webrtc_dsp/webrtc/common_audio/sparse_fir_filter.h \
|
||||||
|
webrtc_dsp/webrtc/common_audio/wav_file.h \
|
||||||
|
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.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_core_optimized_methods.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aec/aec_resampler.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aec/echo_cancellation.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aecm/aecm_core.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aecm/aecm_defines.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/aecm/echo_control_mobile.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/agc/legacy/analog_agc.h \
|
||||||
|
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.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/ns/defines.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/ns/noise_suppression.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/ns/noise_suppression_x.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/ns/ns_core.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/ns/nsx_core.h \
|
||||||
|
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.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/three_band_filter_bank.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/utility/block_mean_calculator.h \
|
||||||
|
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.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/utility/ooura_fft.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/utility/ooura_fft_tables_common.h \
|
||||||
|
webrtc_dsp/webrtc/modules/audio_processing/utility/ooura_fft_tables_neon_sse2.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/typedefs.h
|
||||||
|
|
||||||
|
else
|
||||||
|
CFLAGS += -DTGVOIP_NO_DSP
|
||||||
|
endif
|
||||||
|
|
||||||
|
libtgvoip_la_SOURCES = $(SRC) $(TGVOIP_HDRS)
|
||||||
|
tgvoipincludedir = $(includedir)/tgvoip
|
||||||
|
nobase_tgvoipinclude_HEADERS = $(TGVOIP_HDRS)
|
||||||
|
|
||||||
|
CXXFLAGS += -std=gnu++0x $(CFLAGS)
|
||||||
2283
Makefile.in
Normal file
2283
Makefile.in
Normal file
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@ AudioMixer::AudioMixer() : bufferPool(960*2, 16), processedQueue(16), semaphore(
|
|||||||
AudioMixer::~AudioMixer(){
|
AudioMixer::~AudioMixer(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioMixer::SetOutput(const std::unique_ptr<MediaStreamItf>& output){
|
void AudioMixer::SetOutput(MediaStreamItf* output){
|
||||||
output->SetCallback(OutputCallback, this);
|
output->SetCallback(OutputCallback, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
AudioMixer();
|
AudioMixer();
|
||||||
virtual ~AudioMixer();
|
virtual ~AudioMixer();
|
||||||
void SetOutput(const std::unique_ptr<MediaStreamItf>& output);
|
void SetOutput(MediaStreamItf* output);
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
void AddInput(std::shared_ptr<MediaStreamItf> input);
|
void AddInput(std::shared_ptr<MediaStreamItf> input);
|
||||||
|
|||||||
170
MessageThread.cpp
Executable file
170
MessageThread.cpp
Executable file
@ -0,0 +1,170 @@
|
|||||||
|
//
|
||||||
|
// Created by Grishka on 17.06.2018.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "MessageThread.h"
|
||||||
|
#include "VoIPController.h"
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
|
using namespace tgvoip;
|
||||||
|
|
||||||
|
MessageThread::MessageThread() : Thread(new MethodPointer<MessageThread>(&MessageThread::Run, this), NULL){
|
||||||
|
|
||||||
|
SetName("MessageThread");
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
event=CreateEvent(NULL, false, false, NULL);
|
||||||
|
#else
|
||||||
|
pthread_cond_init(&cond, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageThread::~MessageThread(){
|
||||||
|
Stop();
|
||||||
|
#ifdef _WIN32
|
||||||
|
CloseHandle(event);
|
||||||
|
#else
|
||||||
|
pthread_cond_destroy(&cond);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageThread::Stop(){
|
||||||
|
if(running){
|
||||||
|
running=false;
|
||||||
|
#ifdef _WIN32
|
||||||
|
SetEvent(event);
|
||||||
|
#else
|
||||||
|
pthread_cond_signal(&cond);
|
||||||
|
#endif
|
||||||
|
Join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageThread::Run(void* arg){
|
||||||
|
queueMutex.Lock();
|
||||||
|
while(running){
|
||||||
|
double currentTime=VoIPController::GetCurrentTime();
|
||||||
|
double waitTimeout=queue.empty() ? DBL_MAX : (queue[0].deliverAt-currentTime);
|
||||||
|
//LOGW("MessageThread wait timeout %f", waitTimeout);
|
||||||
|
if(waitTimeout>0.0){
|
||||||
|
#ifdef _WIN32
|
||||||
|
queueMutex.Unlock();
|
||||||
|
DWORD actualWaitTimeout=waitTimeout==DBL_MAX ? INFINITE : ((DWORD)round(waitTimeout*1000.0));
|
||||||
|
WaitForSingleObject(event, actualWaitTimeout);
|
||||||
|
// we don't really care if a context switch happens here and anything gets added to the queue by another thread
|
||||||
|
// since any new no-delay messages will get delivered on this iteration anyway
|
||||||
|
queueMutex.Lock();
|
||||||
|
#else
|
||||||
|
if(waitTimeout!=DBL_MAX){
|
||||||
|
struct timeval now;
|
||||||
|
struct timespec timeout;
|
||||||
|
gettimeofday(&now, NULL);
|
||||||
|
waitTimeout+=now.tv_sec;
|
||||||
|
waitTimeout+=(now.tv_usec/1000000.0);
|
||||||
|
timeout.tv_sec=(time_t)(floor(waitTimeout));
|
||||||
|
timeout.tv_nsec=(long)((waitTimeout-floor(waitTimeout))*1000000000.0);
|
||||||
|
pthread_cond_timedwait(&cond, queueMutex.NativeHandle(), &timeout);
|
||||||
|
}else{
|
||||||
|
pthread_cond_wait(&cond, queueMutex.NativeHandle());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
currentTime=VoIPController::GetCurrentTime();
|
||||||
|
std::vector<Message> msgsToDeliverNow;
|
||||||
|
for(std::vector<Message>::iterator m=queue.begin();m!=queue.end();){
|
||||||
|
if(m->deliverAt==0.0 || currentTime>=m->deliverAt){
|
||||||
|
msgsToDeliverNow.push_back(*m);
|
||||||
|
m=queue.erase(m);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++m;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Message& m:msgsToDeliverNow){
|
||||||
|
//LOGI("MessageThread delivering %u", m.msg);
|
||||||
|
cancelCurrent=false;
|
||||||
|
if(m.deliverAt==0.0)
|
||||||
|
m.deliverAt=VoIPController::GetCurrentTime();
|
||||||
|
if(m.func!=nullptr){
|
||||||
|
m.func();
|
||||||
|
}
|
||||||
|
if(!cancelCurrent && m.interval>0.0){
|
||||||
|
m.deliverAt+=m.interval;
|
||||||
|
InsertMessageInternal(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
queueMutex.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t MessageThread::Post(std::function<void()> func, double delay, double interval){
|
||||||
|
assert(delay>=0);
|
||||||
|
//LOGI("MessageThread post [function] delay %f", delay);
|
||||||
|
if(!IsCurrent()){
|
||||||
|
queueMutex.Lock();
|
||||||
|
}
|
||||||
|
double currentTime=VoIPController::GetCurrentTime();
|
||||||
|
Message m{lastMessageID++, delay==0.0 ? 0.0 : (currentTime+delay), interval, func};
|
||||||
|
InsertMessageInternal(m);
|
||||||
|
if(!IsCurrent()){
|
||||||
|
#ifdef _WIN32
|
||||||
|
SetEvent(event);
|
||||||
|
#else
|
||||||
|
pthread_cond_signal(&cond);
|
||||||
|
#endif
|
||||||
|
queueMutex.Unlock();
|
||||||
|
}
|
||||||
|
return m.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageThread::InsertMessageInternal(MessageThread::Message &m){
|
||||||
|
if(queue.empty()){
|
||||||
|
queue.push_back(m);
|
||||||
|
}else{
|
||||||
|
if(queue[0].deliverAt>m.deliverAt){
|
||||||
|
queue.insert(queue.begin(), m);
|
||||||
|
}else{
|
||||||
|
std::vector<Message>::iterator insertAfter=queue.begin();
|
||||||
|
for(; insertAfter!=queue.end(); ++insertAfter){
|
||||||
|
std::vector<Message>::iterator next=std::next(insertAfter);
|
||||||
|
if(next==queue.end() || (next->deliverAt>m.deliverAt && insertAfter->deliverAt<=m.deliverAt)){
|
||||||
|
queue.insert(next, m);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageThread::Cancel(uint32_t id){
|
||||||
|
if(!IsCurrent()){
|
||||||
|
queueMutex.Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(std::vector<Message>::iterator m=queue.begin();m!=queue.end();){
|
||||||
|
if(m->id==id){
|
||||||
|
m=queue.erase(m);
|
||||||
|
}else{
|
||||||
|
++m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!IsCurrent()){
|
||||||
|
queueMutex.Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageThread::CancelSelf(){
|
||||||
|
assert(IsCurrent());
|
||||||
|
cancelCurrent=true;
|
||||||
|
}
|
||||||
50
MessageThread.h
Executable file
50
MessageThread.h
Executable file
@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// Created by Grishka on 17.06.2018.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef LIBTGVOIP_MESSAGETHREAD_H
|
||||||
|
#define LIBTGVOIP_MESSAGETHREAD_H
|
||||||
|
|
||||||
|
#include "threading.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace tgvoip{
|
||||||
|
class MessageThread : public Thread{
|
||||||
|
public:
|
||||||
|
MessageThread();
|
||||||
|
virtual ~MessageThread();
|
||||||
|
uint32_t Post(std::function<void()> func, double delay=0, double interval=0);
|
||||||
|
void Cancel(uint32_t id);
|
||||||
|
void CancelSelf();
|
||||||
|
void Stop();
|
||||||
|
|
||||||
|
enum{
|
||||||
|
INVALID_ID=0
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
struct Message{
|
||||||
|
uint32_t id;
|
||||||
|
double deliverAt;
|
||||||
|
double interval;
|
||||||
|
std::function<void()> func;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Run(void* arg);
|
||||||
|
void InsertMessageInternal(Message& m);
|
||||||
|
|
||||||
|
bool running=true;
|
||||||
|
std::vector<Message> queue;
|
||||||
|
Mutex queueMutex;
|
||||||
|
uint32_t lastMessageID=1;
|
||||||
|
bool cancelCurrent=false;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
HANDLE event;
|
||||||
|
#else
|
||||||
|
pthread_cond_t cond;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //LIBTGVOIP_MESSAGETHREAD_H
|
||||||
@ -10,6 +10,11 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <opus/opus.h>
|
||||||
|
#else
|
||||||
|
#include "opus.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "VoIPController.h"
|
#include "VoIPController.h"
|
||||||
|
|
||||||
@ -27,6 +32,11 @@ tgvoip::OpusDecoder::OpusDecoder(const std::unique_ptr<MediaStreamItf>& dst, boo
|
|||||||
Initialize(isAsync, needEC);
|
Initialize(isAsync, needEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tgvoip::OpusDecoder::OpusDecoder(MediaStreamItf* dst, bool isAsync, bool needEC){
|
||||||
|
dst->SetCallback(OpusDecoder::Callback, this);
|
||||||
|
Initialize(isAsync, needEC);
|
||||||
|
}
|
||||||
|
|
||||||
void tgvoip::OpusDecoder::Initialize(bool isAsync, bool needEC){
|
void tgvoip::OpusDecoder::Initialize(bool isAsync, bool needEC){
|
||||||
async=isAsync;
|
async=isAsync;
|
||||||
if(async){
|
if(async){
|
||||||
|
|||||||
@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "MediaStreamItf.h"
|
#include "MediaStreamItf.h"
|
||||||
#include "opus.h"
|
|
||||||
#include "threading.h"
|
#include "threading.h"
|
||||||
#include "BlockingQueue.h"
|
#include "BlockingQueue.h"
|
||||||
#include "Buffers.h"
|
#include "Buffers.h"
|
||||||
@ -19,6 +18,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
struct OpusDecoder;
|
||||||
|
|
||||||
namespace tgvoip{
|
namespace tgvoip{
|
||||||
class OpusDecoder {
|
class OpusDecoder {
|
||||||
public:
|
public:
|
||||||
@ -28,6 +29,7 @@ public:
|
|||||||
|
|
||||||
OpusDecoder(const std::shared_ptr<MediaStreamItf>& dst, bool isAsync, bool needEC);
|
OpusDecoder(const std::shared_ptr<MediaStreamItf>& dst, bool isAsync, bool needEC);
|
||||||
OpusDecoder(const std::unique_ptr<MediaStreamItf>& dst, bool isAsync, bool needEC);
|
OpusDecoder(const std::unique_ptr<MediaStreamItf>& dst, bool isAsync, bool needEC);
|
||||||
|
OpusDecoder(MediaStreamItf* dst, bool isAsync, bool needEC);
|
||||||
virtual ~OpusDecoder();
|
virtual ~OpusDecoder();
|
||||||
size_t HandleCallback(unsigned char* data, size_t len);
|
size_t HandleCallback(unsigned char* data, size_t len);
|
||||||
void SetEchoCanceller(EchoCanceller* canceller);
|
void SetEchoCanceller(EchoCanceller* canceller);
|
||||||
@ -65,7 +67,6 @@ private:
|
|||||||
bool async;
|
bool async;
|
||||||
unsigned char nextBuffer[8192];
|
unsigned char nextBuffer[8192];
|
||||||
unsigned char decodeBuffer[8192];
|
unsigned char decodeBuffer[8192];
|
||||||
bool first;
|
|
||||||
size_t nextLen;
|
size_t nextLen;
|
||||||
unsigned int packetsPerFrame;
|
unsigned int packetsPerFrame;
|
||||||
ptrdiff_t remainingDataLen;
|
ptrdiff_t remainingDataLen;
|
||||||
|
|||||||
@ -8,6 +8,11 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "VoIPServerConfig.h"
|
#include "VoIPServerConfig.h"
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <opus/opus.h>
|
||||||
|
#else
|
||||||
|
#include "opus.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
tgvoip::OpusEncoder::OpusEncoder(MediaStreamItf *source, bool needSecondary):queue(11), bufferPool(960*2, 10){
|
tgvoip::OpusEncoder::OpusEncoder(MediaStreamItf *source, bool needSecondary):queue(11), bufferPool(960*2, 10){
|
||||||
this->source=source;
|
this->source=source;
|
||||||
|
|||||||
@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "MediaStreamItf.h"
|
#include "MediaStreamItf.h"
|
||||||
#include "opus.h"
|
|
||||||
#include "threading.h"
|
#include "threading.h"
|
||||||
#include "BlockingQueue.h"
|
#include "BlockingQueue.h"
|
||||||
#include "Buffers.h"
|
#include "Buffers.h"
|
||||||
@ -17,6 +16,8 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct OpusEncoder;
|
||||||
|
|
||||||
namespace tgvoip{
|
namespace tgvoip{
|
||||||
class OpusEncoder{
|
class OpusEncoder{
|
||||||
public:
|
public:
|
||||||
|
|||||||
1100
VoIPController.cpp
1100
VoIPController.cpp
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,7 @@
|
|||||||
#include "audio/AudioInput.h"
|
#include "audio/AudioInput.h"
|
||||||
#include "BlockingQueue.h"
|
#include "BlockingQueue.h"
|
||||||
#include "audio/AudioOutput.h"
|
#include "audio/AudioOutput.h"
|
||||||
|
#include "audio/AudioIO.h"
|
||||||
#include "JitterBuffer.h"
|
#include "JitterBuffer.h"
|
||||||
#include "OpusDecoder.h"
|
#include "OpusDecoder.h"
|
||||||
#include "OpusEncoder.h"
|
#include "OpusEncoder.h"
|
||||||
@ -31,8 +32,9 @@
|
|||||||
#include "NetworkSocket.h"
|
#include "NetworkSocket.h"
|
||||||
#include "Buffers.h"
|
#include "Buffers.h"
|
||||||
#include "PacketReassembler.h"
|
#include "PacketReassembler.h"
|
||||||
|
#include "MessageThread.h"
|
||||||
|
|
||||||
#define LIBTGVOIP_VERSION "2.1.1"
|
#define LIBTGVOIP_VERSION "2.2"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#undef GetCurrentTime
|
#undef GetCurrentTime
|
||||||
@ -124,7 +126,7 @@ namespace tgvoip{
|
|||||||
private:
|
private:
|
||||||
double lastPingTime;
|
double lastPingTime;
|
||||||
uint32_t lastPingSeq;
|
uint32_t lastPingSeq;
|
||||||
double rtts[6];
|
HistoricBuffer<double, 6> rtts;
|
||||||
double averageRTT;
|
double averageRTT;
|
||||||
NetworkSocket* socket;
|
NetworkSocket* socket;
|
||||||
int udpPongCount;
|
int udpPongCount;
|
||||||
@ -251,7 +253,6 @@ namespace tgvoip{
|
|||||||
* @param cfg
|
* @param cfg
|
||||||
*/
|
*/
|
||||||
void SetConfig(const Config& cfg);
|
void SetConfig(const Config& cfg);
|
||||||
float GetOutputLevel();
|
|
||||||
void DebugCtl(int request, int param);
|
void DebugCtl(int request, int param);
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -360,11 +361,15 @@ namespace tgvoip{
|
|||||||
void (*connectionStateChanged)(VoIPController*, int);
|
void (*connectionStateChanged)(VoIPController*, int);
|
||||||
void (*signalBarCountChanged)(VoIPController*, int);
|
void (*signalBarCountChanged)(VoIPController*, int);
|
||||||
void (*groupCallKeySent)(VoIPController*);
|
void (*groupCallKeySent)(VoIPController*);
|
||||||
void (*groupCallKeyReceived)(VoIPController*, unsigned char*);
|
void (*groupCallKeyReceived)(VoIPController*, const unsigned char*);
|
||||||
void (*upgradeToGroupCallRequested)(VoIPController*);
|
void (*upgradeToGroupCallRequested)(VoIPController*);
|
||||||
};
|
};
|
||||||
void SetCallbacks(Callbacks callbacks);
|
void SetCallbacks(Callbacks callbacks);
|
||||||
|
|
||||||
|
float GetOutputLevel(){
|
||||||
|
return 0.0f;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Stream;
|
struct Stream;
|
||||||
struct UnacknowledgedExtraData;
|
struct UnacknowledgedExtraData;
|
||||||
@ -391,7 +396,7 @@ namespace tgvoip{
|
|||||||
struct QueuedPacket{
|
struct QueuedPacket{
|
||||||
Buffer data;
|
Buffer data;
|
||||||
unsigned char type;
|
unsigned char type;
|
||||||
uint32_t seqs[16];
|
HistoricBuffer<uint32_t, 16> seqs;
|
||||||
double firstSentTime;
|
double firstSentTime;
|
||||||
double lastSentTime;
|
double lastSentTime;
|
||||||
double retryInterval;
|
double retryInterval;
|
||||||
@ -407,6 +412,7 @@ namespace tgvoip{
|
|||||||
virtual void OnAudioOutputReady();
|
virtual void OnAudioOutputReady();
|
||||||
virtual void SendExtra(Buffer& data, unsigned char type);
|
virtual void SendExtra(Buffer& data, unsigned char type);
|
||||||
void SendStreamFlags(Stream& stream);
|
void SendStreamFlags(Stream& stream);
|
||||||
|
void InitializeTimers();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Stream{
|
struct Stream{
|
||||||
@ -438,10 +444,9 @@ namespace tgvoip{
|
|||||||
|
|
||||||
void RunRecvThread(void* arg);
|
void RunRecvThread(void* arg);
|
||||||
void RunSendThread(void* arg);
|
void RunSendThread(void* arg);
|
||||||
void RunTickThread(void* arg);
|
|
||||||
void HandleAudioInput(unsigned char* data, size_t len, unsigned char* secondaryData, size_t secondaryLen);
|
void HandleAudioInput(unsigned char* data, size_t len, unsigned char* secondaryData, size_t secondaryLen);
|
||||||
void HandleVideoInput(EncodedVideoFrame& frame);
|
void HandleVideoInput(EncodedVideoFrame& frame);
|
||||||
void UpdateAudioBitrate();
|
void UpdateAudioBitrateLimit();
|
||||||
void SetState(int state);
|
void SetState(int state);
|
||||||
void UpdateAudioOutputState();
|
void UpdateAudioOutputState();
|
||||||
void InitUDPProxy();
|
void InitUDPProxy();
|
||||||
@ -460,6 +465,17 @@ namespace tgvoip{
|
|||||||
void StartAudio();
|
void StartAudio();
|
||||||
void ProcessAcknowledgedOutgoingExtra(UnacknowledgedExtraData& extra);
|
void ProcessAcknowledgedOutgoingExtra(UnacknowledgedExtraData& extra);
|
||||||
void AddIPv6Relays();
|
void AddIPv6Relays();
|
||||||
|
void AddTCPRelays();
|
||||||
|
void SendUdpPings();
|
||||||
|
void EvaluateUdpPingResults();
|
||||||
|
void UpdateRTT();
|
||||||
|
void UpdateCongestion();
|
||||||
|
void UpdateAudioBitrate();
|
||||||
|
void UpdateSignalBars();
|
||||||
|
void UpdateQueuedPackets();
|
||||||
|
void SendNopPacket();
|
||||||
|
void TickJitterBufferAngCongestionControl();
|
||||||
|
|
||||||
int state;
|
int state;
|
||||||
std::vector<std::shared_ptr<Endpoint>> endpoints;
|
std::vector<std::shared_ptr<Endpoint>> endpoints;
|
||||||
std::shared_ptr<Endpoint> currentEndpoint;
|
std::shared_ptr<Endpoint> currentEndpoint;
|
||||||
@ -472,11 +488,12 @@ namespace tgvoip{
|
|||||||
uint32_t lastSentSeq;
|
uint32_t lastSentSeq;
|
||||||
std::vector<RecentOutgoingPacket> recentOutgoingPackets;
|
std::vector<RecentOutgoingPacket> recentOutgoingPackets;
|
||||||
double recvPacketTimes[32];
|
double recvPacketTimes[32];
|
||||||
uint32_t sendLossCountHistory[32];
|
HistoricBuffer<uint32_t, 10, double> sendLossCountHistory;
|
||||||
uint32_t audioTimestampIn;
|
uint32_t audioTimestampIn;
|
||||||
uint32_t audioTimestampOut;
|
uint32_t audioTimestampOut;
|
||||||
|
std::shared_ptr<tgvoip::audio::AudioIO> audioIO;
|
||||||
tgvoip::audio::AudioInput* audioInput;
|
tgvoip::audio::AudioInput* audioInput;
|
||||||
std::unique_ptr<tgvoip::audio::AudioOutput> audioOutput;
|
tgvoip::audio::AudioOutput* audioOutput;
|
||||||
OpusEncoder* encoder;
|
OpusEncoder* encoder;
|
||||||
BlockingQueue<PendingOutgoingPacket>* sendQueue;
|
BlockingQueue<PendingOutgoingPacket>* sendQueue;
|
||||||
EchoCanceller* echoCanceller;
|
EchoCanceller* echoCanceller;
|
||||||
@ -487,12 +504,11 @@ namespace tgvoip{
|
|||||||
bool audioOutStarted;
|
bool audioOutStarted;
|
||||||
Thread* recvThread;
|
Thread* recvThread;
|
||||||
Thread* sendThread;
|
Thread* sendThread;
|
||||||
Thread* tickThread;
|
|
||||||
uint32_t packetsReceived;
|
uint32_t packetsReceived;
|
||||||
uint32_t recvLossCount;
|
uint32_t recvLossCount;
|
||||||
uint32_t prevSendLossCount;
|
uint32_t prevSendLossCount;
|
||||||
uint32_t firstSentPing;
|
uint32_t firstSentPing;
|
||||||
double rttHistory[32];
|
HistoricBuffer<double, 32> rttHistory;
|
||||||
bool waitingForAcks;
|
bool waitingForAcks;
|
||||||
int networkType;
|
int networkType;
|
||||||
int dontSendPackets;
|
int dontSendPackets;
|
||||||
@ -532,10 +548,9 @@ namespace tgvoip{
|
|||||||
bool useTCP;
|
bool useTCP;
|
||||||
bool useUDP;
|
bool useUDP;
|
||||||
bool didAddTcpRelays;
|
bool didAddTcpRelays;
|
||||||
double setEstablishedAt;
|
|
||||||
SocketSelectCanceller* selectCanceller;
|
SocketSelectCanceller* selectCanceller;
|
||||||
NetworkSocket* openingTcpSocket;
|
NetworkSocket* openingTcpSocket;
|
||||||
unsigned char signalBarsHistory[4];
|
HistoricBuffer<unsigned char, 4, int> signalBarsHistory;
|
||||||
|
|
||||||
BufferPool outgoingPacketsBufferPool;
|
BufferPool outgoingPacketsBufferPool;
|
||||||
int udpConnectivityState;
|
int udpConnectivityState;
|
||||||
@ -550,8 +565,6 @@ namespace tgvoip{
|
|||||||
std::string proxyPassword;
|
std::string proxyPassword;
|
||||||
IPv4Address* resolvedProxyAddress;
|
IPv4Address* resolvedProxyAddress;
|
||||||
|
|
||||||
int signalBarCount;
|
|
||||||
|
|
||||||
AutomaticGainControl* outputAGC;
|
AutomaticGainControl* outputAGC;
|
||||||
bool outputAGCEnabled;
|
bool outputAGCEnabled;
|
||||||
uint32_t peerCapabilities;
|
uint32_t peerCapabilities;
|
||||||
@ -576,6 +589,11 @@ namespace tgvoip{
|
|||||||
bool didAddIPv6Relays;
|
bool didAddIPv6Relays;
|
||||||
bool didSendIPv6Endpoint;
|
bool didSendIPv6Endpoint;
|
||||||
int publicEndpointsReqCount=0;
|
int publicEndpointsReqCount=0;
|
||||||
|
MessageThread messageThread;
|
||||||
|
bool wasEstablished=false;
|
||||||
|
|
||||||
|
uint32_t initTimeoutID=MessageThread::INVALID_ID;
|
||||||
|
uint32_t noStreamsNopID=MessageThread::INVALID_ID;
|
||||||
|
|
||||||
/*** server config values ***/
|
/*** server config values ***/
|
||||||
uint32_t maxAudioBitrate;
|
uint32_t maxAudioBitrate;
|
||||||
@ -594,11 +612,6 @@ namespace tgvoip{
|
|||||||
double relayToP2pSwitchThreshold;
|
double relayToP2pSwitchThreshold;
|
||||||
double reconnectingTimeout;
|
double reconnectingTimeout;
|
||||||
|
|
||||||
/*** platform-specific things **/
|
|
||||||
#ifdef __APPLE__
|
|
||||||
audio::AudioUnitIO* appleAudioIO;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
static double machTimebase;
|
static double machTimebase;
|
||||||
|
|||||||
@ -467,7 +467,7 @@ void VoIPGroupController::SendUdpPing(shared_ptr<Endpoint> endpoint){
|
|||||||
void VoIPGroupController::SetNetworkType(int type){
|
void VoIPGroupController::SetNetworkType(int type){
|
||||||
networkType=type;
|
networkType=type;
|
||||||
UpdateDataSavingState();
|
UpdateDataSavingState();
|
||||||
UpdateAudioBitrate();
|
UpdateAudioBitrateLimit();
|
||||||
string itfName=udpSocket->GetLocalInterfaceInfo(NULL, NULL);
|
string itfName=udpSocket->GetLocalInterfaceInfo(NULL, NULL);
|
||||||
if(itfName!=activeNetItfName){
|
if(itfName!=activeNetItfName){
|
||||||
udpSocket->OnActiveInterfaceChanged();
|
udpSocket->OnActiveInterfaceChanged();
|
||||||
@ -544,7 +544,7 @@ void VoIPGroupController::SendRelayPings(){
|
|||||||
|
|
||||||
void VoIPGroupController::OnAudioOutputReady(){
|
void VoIPGroupController::OnAudioOutputReady(){
|
||||||
encoder->SetDTX(true);
|
encoder->SetDTX(true);
|
||||||
audioMixer->SetOutput((unique_ptr<MediaStreamItf>&)audioOutput);
|
audioMixer->SetOutput(audioOutput);
|
||||||
audioMixer->SetEchoCanceller(echoCanceller);
|
audioMixer->SetEchoCanceller(echoCanceller);
|
||||||
audioMixer->Start();
|
audioMixer->Start();
|
||||||
audioOutput->Start();
|
audioOutput->Start();
|
||||||
|
|||||||
10184
aclocal.m4
vendored
Normal file
10184
aclocal.m4
vendored
Normal file
File diff suppressed because it is too large
Load Diff
88
audio/AudioIO.cpp
Normal file
88
audio/AudioIO.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
//
|
||||||
|
// libtgvoip is free and unencumbered public domain software.
|
||||||
|
// For more information, see http://unlicense.org or the UNLICENSE file
|
||||||
|
// you should have received with this source code distribution.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "AudioIO.h"
|
||||||
|
#include "../logging.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
#include "../os/android/AudioInputAndroid.h"
|
||||||
|
#include "../os/android/AudioOutputAndroid.h"
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#include <TargetConditionals.h>
|
||||||
|
#include "../os/darwin/AudioUnitIO.h"
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
#include "../os/darwin/AudioInputAudioUnitOSX.h"
|
||||||
|
#include "../os/darwin/AudioOutputAudioUnitOSX.h"
|
||||||
|
#endif
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#ifdef TGVOIP_WINXP_COMPAT
|
||||||
|
#include "../os/windows/AudioInputWave.h"
|
||||||
|
#include "../os/windows/AudioOutputWave.h"
|
||||||
|
#endif
|
||||||
|
#include "../os/windows/AudioInputWASAPI.h"
|
||||||
|
#include "../os/windows/AudioOutputWASAPI.h"
|
||||||
|
#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__gnu_hurd__)
|
||||||
|
#ifndef WITHOUT_ALSA
|
||||||
|
#include "../os/linux/AudioInputALSA.h"
|
||||||
|
#include "../os/linux/AudioOutputALSA.h"
|
||||||
|
#endif
|
||||||
|
#ifndef WITHOUT_PULSE
|
||||||
|
#include "../os/linux/AudioPulse.h"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#error "Unsupported operating system"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace tgvoip;
|
||||||
|
using namespace tgvoip::audio;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
shared_ptr<AudioIO> AudioIO::Create(){
|
||||||
|
std::string inputDevice="default", outputDevice="default";
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
return std::make_shared<ContextlessAudioIO<AudioInputAndroid, AudioOutputAndroid>>();
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
if(kCFCoreFoundationVersionNumber<kCFCoreFoundationVersionNumber10_7)
|
||||||
|
return std::make_shared<ContextlessAudioIO<AudioInputAudioUnitLegacy, AudioOutputAudioUnitLegacy>>(inputDevice, outputDevice);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
return std::make_shared<AudioUnitIO>();
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#ifdef TGVOIP_WINXP_COMPAT
|
||||||
|
if(LOBYTE(LOWORD(GetVersion()))<6)
|
||||||
|
return std::make_shared<ContextlessAudioIO<AudioInputWave, AudioOutputWave>>(inputDevice, outputDevice);
|
||||||
|
#endif
|
||||||
|
return std::make_shared<ContextlessAudioIO<AudioInputWASAPI, AudioOutputWASAPI>>(inputDevice, outputDevice);
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#ifndef WITHOUT_ALSA
|
||||||
|
#ifndef WITHOUT_PULSE
|
||||||
|
if(AudioPulse::Load()){
|
||||||
|
std::shared_ptr<AudioIO> io=std::make_shared<AudioPulse>(inputDevice, outputDevice);
|
||||||
|
if(!io->Failed() && io->GetInput()->IsInitialized() && io->GetOutput()->IsInitialized())
|
||||||
|
return io;
|
||||||
|
LOGW("PulseAudio available but not working; trying ALSA");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return std::make_shared<ContextlessAudioIO<AudioInputALSA, AudioOutputALSA>>(inputDevice, outputDevice);
|
||||||
|
#else
|
||||||
|
return std::make_shared<AudioPulse>(inputDevice, outputDevice);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioIO::Failed(){
|
||||||
|
return failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AudioIO::GetErrorDescription(){
|
||||||
|
return error;
|
||||||
|
}
|
||||||
62
audio/AudioIO.h
Normal file
62
audio/AudioIO.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// libtgvoip is free and unencumbered public domain software.
|
||||||
|
// For more information, see http://unlicense.org or the UNLICENSE file
|
||||||
|
// you should have received with this source code distribution.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LIBTGVOIP_AUDIOIO_H
|
||||||
|
#define LIBTGVOIP_AUDIOIO_H
|
||||||
|
|
||||||
|
#include "AudioInput.h"
|
||||||
|
#include "AudioOutput.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace tgvoip{
|
||||||
|
namespace audio {
|
||||||
|
class AudioIO{
|
||||||
|
public:
|
||||||
|
virtual ~AudioIO(){};
|
||||||
|
static std::shared_ptr<AudioIO> Create();
|
||||||
|
virtual AudioInput* GetInput()=0;
|
||||||
|
virtual AudioOutput* GetOutput()=0;
|
||||||
|
bool Failed();
|
||||||
|
std::string GetErrorDescription();
|
||||||
|
protected:
|
||||||
|
bool failed=false;
|
||||||
|
std::string error;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class I, class O> class ContextlessAudioIO : public AudioIO{
|
||||||
|
public:
|
||||||
|
ContextlessAudioIO(){
|
||||||
|
input=new I();
|
||||||
|
output=new O();
|
||||||
|
}
|
||||||
|
|
||||||
|
ContextlessAudioIO(std::string inputDeviceID, std::string outputDeviceID){
|
||||||
|
input=new I(inputDeviceID);
|
||||||
|
output=new O(outputDeviceID);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~ContextlessAudioIO(){
|
||||||
|
delete input;
|
||||||
|
delete output;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual AudioInput* GetInput(){
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual AudioOutput* GetOutput(){
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
I* input;
|
||||||
|
O* output;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //LIBTGVOIP_AUDIOIO_H
|
||||||
@ -6,6 +6,11 @@
|
|||||||
|
|
||||||
#include "AudioInput.h"
|
#include "AudioInput.h"
|
||||||
#include "../logging.h"
|
#include "../logging.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
#include "../os/android/AudioInputAndroid.h"
|
#include "../os/android/AudioInputAndroid.h"
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
@ -20,8 +25,12 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "../os/windows/AudioInputWASAPI.h"
|
#include "../os/windows/AudioInputWASAPI.h"
|
||||||
#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__gnu_hurd__)
|
#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__gnu_hurd__)
|
||||||
|
#ifndef WITHOUT_ALSA
|
||||||
#include "../os/linux/AudioInputALSA.h"
|
#include "../os/linux/AudioInputALSA.h"
|
||||||
#include "../os/linux/AudioInputPulse.h"
|
#endif
|
||||||
|
#ifndef WITHOUT_PULSE
|
||||||
|
#include "../os/linux/AudioPulse.h"
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#error "Unsupported operating system"
|
#error "Unsupported operating system"
|
||||||
#endif
|
#endif
|
||||||
@ -39,7 +48,7 @@ AudioInput::AudioInput(std::string deviceID) : currentDevice(deviceID){
|
|||||||
failed=false;
|
failed=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioInput *AudioInput::Create(std::string deviceID, void* platformSpecific){
|
/*AudioInput *AudioInput::Create(std::string deviceID, void* platformSpecific){
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
return new AudioInputAndroid();
|
return new AudioInputAndroid();
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
@ -65,7 +74,7 @@ AudioInput *AudioInput::Create(std::string deviceID, void* platformSpecific){
|
|||||||
}
|
}
|
||||||
return new AudioInputALSA(deviceID);
|
return new AudioInputALSA(deviceID);
|
||||||
#endif
|
#endif
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
AudioInput::~AudioInput(){
|
AudioInput::~AudioInput(){
|
||||||
@ -88,8 +97,14 @@ void AudioInput::EnumerateDevices(std::vector<AudioInputDevice>& devs){
|
|||||||
#endif
|
#endif
|
||||||
AudioInputWASAPI::EnumerateDevices(devs);
|
AudioInputWASAPI::EnumerateDevices(devs);
|
||||||
#elif defined(__linux__) && !defined(__ANDROID__)
|
#elif defined(__linux__) && !defined(__ANDROID__)
|
||||||
if(!AudioInputPulse::IsAvailable() || !AudioInputPulse::EnumerateDevices(devs))
|
#if !defined(WITHOUT_PULSE) && !defined(WITHOUT_ALSA)
|
||||||
|
if(!AudioInputPulse::EnumerateDevices(devs))
|
||||||
AudioInputALSA::EnumerateDevices(devs);
|
AudioInputALSA::EnumerateDevices(devs);
|
||||||
|
#elif defined(WITHOUT_PULSE)
|
||||||
|
AudioInputALSA::EnumerateDevices(devs);
|
||||||
|
#else
|
||||||
|
AudioInputPulse::EnumerateDevices(devs)
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,11 +24,10 @@ public:
|
|||||||
AudioInput(std::string deviceID);
|
AudioInput(std::string deviceID);
|
||||||
virtual ~AudioInput();
|
virtual ~AudioInput();
|
||||||
|
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels)=0;
|
|
||||||
bool IsInitialized();
|
bool IsInitialized();
|
||||||
virtual std::string GetCurrentDevice();
|
virtual std::string GetCurrentDevice();
|
||||||
virtual void SetCurrentDevice(std::string deviceID);
|
virtual void SetCurrentDevice(std::string deviceID);
|
||||||
static AudioInput* Create(std::string deviceID, void* platformSpecific);
|
//static AudioInput* Create(std::string deviceID, void* platformSpecific);
|
||||||
static void EnumerateDevices(std::vector<AudioInputDevice>& devs);
|
static void EnumerateDevices(std::vector<AudioInputDevice>& devs);
|
||||||
static int32_t GetEstimatedDelay();
|
static int32_t GetEstimatedDelay();
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,11 @@
|
|||||||
#include "AudioOutput.h"
|
#include "AudioOutput.h"
|
||||||
#include "../logging.h"
|
#include "../logging.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
#include "../os/android/AudioOutputOpenSLES.h"
|
#include "../os/android/AudioOutputOpenSLES.h"
|
||||||
#include "../os/android/AudioOutputAndroid.h"
|
#include "../os/android/AudioOutputAndroid.h"
|
||||||
@ -23,8 +28,13 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "../os/windows/AudioOutputWASAPI.h"
|
#include "../os/windows/AudioOutputWASAPI.h"
|
||||||
#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__gnu_hurd__)
|
#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__gnu_hurd__)
|
||||||
|
#ifndef WITHOUT_ALSA
|
||||||
#include "../os/linux/AudioOutputALSA.h"
|
#include "../os/linux/AudioOutputALSA.h"
|
||||||
|
#endif
|
||||||
|
#ifndef WITHOUT_PULSE
|
||||||
#include "../os/linux/AudioOutputPulse.h"
|
#include "../os/linux/AudioOutputPulse.h"
|
||||||
|
#include "../os/linux/AudioPulse.h"
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#error "Unsupported operating system"
|
#error "Unsupported operating system"
|
||||||
#endif
|
#endif
|
||||||
@ -34,7 +44,7 @@ using namespace tgvoip::audio;
|
|||||||
|
|
||||||
int32_t AudioOutput::estimatedDelay=60;
|
int32_t AudioOutput::estimatedDelay=60;
|
||||||
|
|
||||||
std::unique_ptr<AudioOutput> AudioOutput::Create(std::string deviceID, void* platformSpecific){
|
/*std::unique_ptr<AudioOutput> AudioOutput::Create(std::string deviceID, void* platformSpecific){
|
||||||
#if defined(__ANDROID__)
|
#if defined(__ANDROID__)
|
||||||
return std::unique_ptr<AudioOutput>(new AudioOutputAndroid());
|
return std::unique_ptr<AudioOutput>(new AudioOutputAndroid());
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
@ -60,7 +70,7 @@ std::unique_ptr<AudioOutput> AudioOutput::Create(std::string deviceID, void* pla
|
|||||||
}
|
}
|
||||||
return std::unique_ptr<AudioOutput>(new AudioOutputALSA(deviceID));
|
return std::unique_ptr<AudioOutput>(new AudioOutputALSA(deviceID));
|
||||||
#endif
|
#endif
|
||||||
}
|
}*/
|
||||||
|
|
||||||
AudioOutput::AudioOutput() : currentDevice("default"){
|
AudioOutput::AudioOutput() : currentDevice("default"){
|
||||||
failed=false;
|
failed=false;
|
||||||
@ -85,10 +95,6 @@ int32_t AudioOutput::GetEstimatedDelay(){
|
|||||||
return estimatedDelay;
|
return estimatedDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
float AudioOutput::GetLevel(){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void AudioOutput::EnumerateDevices(std::vector<AudioOutputDevice>& devs){
|
void AudioOutput::EnumerateDevices(std::vector<AudioOutputDevice>& devs){
|
||||||
#if defined(__APPLE__) && TARGET_OS_OSX
|
#if defined(__APPLE__) && TARGET_OS_OSX
|
||||||
@ -102,8 +108,14 @@ void AudioOutput::EnumerateDevices(std::vector<AudioOutputDevice>& devs){
|
|||||||
#endif
|
#endif
|
||||||
AudioOutputWASAPI::EnumerateDevices(devs);
|
AudioOutputWASAPI::EnumerateDevices(devs);
|
||||||
#elif defined(__linux__) && !defined(__ANDROID__)
|
#elif defined(__linux__) && !defined(__ANDROID__)
|
||||||
if(!AudioOutputPulse::IsAvailable() || !AudioOutputPulse::EnumerateDevices(devs))
|
#if !defined(WITHOUT_PULSE) && !defined(WITHOUT_ALSA)
|
||||||
|
if(!AudioOutputPulse::EnumerateDevices(devs))
|
||||||
AudioOutputALSA::EnumerateDevices(devs);
|
AudioOutputALSA::EnumerateDevices(devs);
|
||||||
|
#elif defined(WITHOUT_PULSE)
|
||||||
|
AudioOutputALSA::EnumerateDevices(devs);
|
||||||
|
#else
|
||||||
|
AudioOutputPulse::EnumerateDevices(devs)
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,13 +24,11 @@ public:
|
|||||||
AudioOutput();
|
AudioOutput();
|
||||||
AudioOutput(std::string deviceID);
|
AudioOutput(std::string deviceID);
|
||||||
virtual ~AudioOutput();
|
virtual ~AudioOutput();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels)=0;
|
|
||||||
virtual bool IsPlaying()=0;
|
virtual bool IsPlaying()=0;
|
||||||
virtual float GetLevel();
|
|
||||||
static int32_t GetEstimatedDelay();
|
static int32_t GetEstimatedDelay();
|
||||||
virtual std::string GetCurrentDevice();
|
virtual std::string GetCurrentDevice();
|
||||||
virtual void SetCurrentDevice(std::string deviceID);
|
virtual void SetCurrentDevice(std::string deviceID);
|
||||||
static std::unique_ptr<AudioOutput> Create(std::string deviceID, void* platformSpecific);
|
//static std::unique_ptr<AudioOutput> Create(std::string deviceID, void* platformSpecific);
|
||||||
static void EnumerateDevices(std::vector<AudioOutputDevice>& devs);
|
static void EnumerateDevices(std::vector<AudioOutputDevice>& devs);
|
||||||
bool IsInitialized();
|
bool IsInitialized();
|
||||||
|
|
||||||
|
|||||||
@ -103,7 +103,7 @@ namespace tgvoip {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void groupCallKeyReceived(VoIPController *cntrlr, unsigned char *key){
|
void groupCallKeyReceived(VoIPController *cntrlr, const unsigned char *key){
|
||||||
impl_data_android_t *impl=(impl_data_android_t *) cntrlr->implData;
|
impl_data_android_t *impl=(impl_data_android_t *) cntrlr->implData;
|
||||||
if(!impl->javaObject)
|
if(!impl->javaObject)
|
||||||
return;
|
return;
|
||||||
|
|||||||
348
compile
Executable file
348
compile
Executable file
@ -0,0 +1,348 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# Wrapper for compilers which do not understand '-c -o'.
|
||||||
|
|
||||||
|
scriptversion=2018-03-07.03; # UTC
|
||||||
|
|
||||||
|
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||||
|
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# This file is maintained in Automake, please report
|
||||||
|
# bugs to <bug-automake@gnu.org> or send patches to
|
||||||
|
# <automake-patches@gnu.org>.
|
||||||
|
|
||||||
|
nl='
|
||||||
|
'
|
||||||
|
|
||||||
|
# We need space, tab and new line, in precisely that order. Quoting is
|
||||||
|
# there to prevent tools from complaining about whitespace usage.
|
||||||
|
IFS=" "" $nl"
|
||||||
|
|
||||||
|
file_conv=
|
||||||
|
|
||||||
|
# func_file_conv build_file lazy
|
||||||
|
# Convert a $build file to $host form and store it in $file
|
||||||
|
# Currently only supports Windows hosts. If the determined conversion
|
||||||
|
# type is listed in (the comma separated) LAZY, no conversion will
|
||||||
|
# take place.
|
||||||
|
func_file_conv ()
|
||||||
|
{
|
||||||
|
file=$1
|
||||||
|
case $file in
|
||||||
|
/ | /[!/]*) # absolute file, and not a UNC file
|
||||||
|
if test -z "$file_conv"; then
|
||||||
|
# lazily determine how to convert abs files
|
||||||
|
case `uname -s` in
|
||||||
|
MINGW*)
|
||||||
|
file_conv=mingw
|
||||||
|
;;
|
||||||
|
CYGWIN*)
|
||||||
|
file_conv=cygwin
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
file_conv=wine
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
case $file_conv/,$2, in
|
||||||
|
*,$file_conv,*)
|
||||||
|
;;
|
||||||
|
mingw/*)
|
||||||
|
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||||
|
;;
|
||||||
|
cygwin/*)
|
||||||
|
file=`cygpath -m "$file" || echo "$file"`
|
||||||
|
;;
|
||||||
|
wine/*)
|
||||||
|
file=`winepath -w "$file" || echo "$file"`
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# func_cl_dashL linkdir
|
||||||
|
# Make cl look for libraries in LINKDIR
|
||||||
|
func_cl_dashL ()
|
||||||
|
{
|
||||||
|
func_file_conv "$1"
|
||||||
|
if test -z "$lib_path"; then
|
||||||
|
lib_path=$file
|
||||||
|
else
|
||||||
|
lib_path="$lib_path;$file"
|
||||||
|
fi
|
||||||
|
linker_opts="$linker_opts -LIBPATH:$file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# func_cl_dashl library
|
||||||
|
# Do a library search-path lookup for cl
|
||||||
|
func_cl_dashl ()
|
||||||
|
{
|
||||||
|
lib=$1
|
||||||
|
found=no
|
||||||
|
save_IFS=$IFS
|
||||||
|
IFS=';'
|
||||||
|
for dir in $lib_path $LIB
|
||||||
|
do
|
||||||
|
IFS=$save_IFS
|
||||||
|
if $shared && test -f "$dir/$lib.dll.lib"; then
|
||||||
|
found=yes
|
||||||
|
lib=$dir/$lib.dll.lib
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if test -f "$dir/$lib.lib"; then
|
||||||
|
found=yes
|
||||||
|
lib=$dir/$lib.lib
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if test -f "$dir/lib$lib.a"; then
|
||||||
|
found=yes
|
||||||
|
lib=$dir/lib$lib.a
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS=$save_IFS
|
||||||
|
|
||||||
|
if test "$found" != yes; then
|
||||||
|
lib=$lib.lib
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# func_cl_wrapper cl arg...
|
||||||
|
# Adjust compile command to suit cl
|
||||||
|
func_cl_wrapper ()
|
||||||
|
{
|
||||||
|
# Assume a capable shell
|
||||||
|
lib_path=
|
||||||
|
shared=:
|
||||||
|
linker_opts=
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
if test -n "$eat"; then
|
||||||
|
eat=
|
||||||
|
else
|
||||||
|
case $1 in
|
||||||
|
-o)
|
||||||
|
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||||
|
eat=1
|
||||||
|
case $2 in
|
||||||
|
*.o | *.[oO][bB][jJ])
|
||||||
|
func_file_conv "$2"
|
||||||
|
set x "$@" -Fo"$file"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
func_file_conv "$2"
|
||||||
|
set x "$@" -Fe"$file"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
-I)
|
||||||
|
eat=1
|
||||||
|
func_file_conv "$2" mingw
|
||||||
|
set x "$@" -I"$file"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-I*)
|
||||||
|
func_file_conv "${1#-I}" mingw
|
||||||
|
set x "$@" -I"$file"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-l)
|
||||||
|
eat=1
|
||||||
|
func_cl_dashl "$2"
|
||||||
|
set x "$@" "$lib"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-l*)
|
||||||
|
func_cl_dashl "${1#-l}"
|
||||||
|
set x "$@" "$lib"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-L)
|
||||||
|
eat=1
|
||||||
|
func_cl_dashL "$2"
|
||||||
|
;;
|
||||||
|
-L*)
|
||||||
|
func_cl_dashL "${1#-L}"
|
||||||
|
;;
|
||||||
|
-static)
|
||||||
|
shared=false
|
||||||
|
;;
|
||||||
|
-Wl,*)
|
||||||
|
arg=${1#-Wl,}
|
||||||
|
save_ifs="$IFS"; IFS=','
|
||||||
|
for flag in $arg; do
|
||||||
|
IFS="$save_ifs"
|
||||||
|
linker_opts="$linker_opts $flag"
|
||||||
|
done
|
||||||
|
IFS="$save_ifs"
|
||||||
|
;;
|
||||||
|
-Xlinker)
|
||||||
|
eat=1
|
||||||
|
linker_opts="$linker_opts $2"
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
|
||||||
|
func_file_conv "$1"
|
||||||
|
set x "$@" -Tp"$file"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
|
||||||
|
func_file_conv "$1" mingw
|
||||||
|
set x "$@" "$file"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
if test -n "$linker_opts"; then
|
||||||
|
linker_opts="-link$linker_opts"
|
||||||
|
fi
|
||||||
|
exec "$@" $linker_opts
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
eat=
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
'')
|
||||||
|
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||||
|
exit 1;
|
||||||
|
;;
|
||||||
|
-h | --h*)
|
||||||
|
cat <<\EOF
|
||||||
|
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||||
|
|
||||||
|
Wrapper for compilers which do not understand '-c -o'.
|
||||||
|
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||||
|
arguments, and rename the output as expected.
|
||||||
|
|
||||||
|
If you are trying to build a whole package this is not the
|
||||||
|
right script to run: please start by reading the file 'INSTALL'.
|
||||||
|
|
||||||
|
Report bugs to <bug-automake@gnu.org>.
|
||||||
|
EOF
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
-v | --v*)
|
||||||
|
echo "compile $scriptversion"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
|
||||||
|
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
|
||||||
|
func_cl_wrapper "$@" # Doesn't return...
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
ofile=
|
||||||
|
cfile=
|
||||||
|
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
if test -n "$eat"; then
|
||||||
|
eat=
|
||||||
|
else
|
||||||
|
case $1 in
|
||||||
|
-o)
|
||||||
|
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||||
|
# So we strip '-o arg' only if arg is an object.
|
||||||
|
eat=1
|
||||||
|
case $2 in
|
||||||
|
*.o | *.obj)
|
||||||
|
ofile=$2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set x "$@" -o "$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*.c)
|
||||||
|
cfile=$1
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -z "$ofile" || test -z "$cfile"; then
|
||||||
|
# If no '-o' option was seen then we might have been invoked from a
|
||||||
|
# pattern rule where we don't need one. That is ok -- this is a
|
||||||
|
# normal compilation that the losing compiler can handle. If no
|
||||||
|
# '.c' file was seen then we are probably linking. That is also
|
||||||
|
# ok.
|
||||||
|
exec "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Name of file we expect compiler to create.
|
||||||
|
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||||
|
|
||||||
|
# Create the lock directory.
|
||||||
|
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
|
||||||
|
# that we are using for the .o file. Also, base the name on the expected
|
||||||
|
# object file name, since that is what matters with a parallel build.
|
||||||
|
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||||
|
while true; do
|
||||||
|
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
# FIXME: race condition here if user kills between mkdir and trap.
|
||||||
|
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||||
|
|
||||||
|
# Run the compile.
|
||||||
|
"$@"
|
||||||
|
ret=$?
|
||||||
|
|
||||||
|
if test -f "$cofile"; then
|
||||||
|
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||||
|
elif test -f "${cofile}bj"; then
|
||||||
|
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rmdir "$lockdir"
|
||||||
|
exit $ret
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: shell-script
|
||||||
|
# sh-indentation: 2
|
||||||
|
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC0"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
||||||
1476
config.guess
vendored
Executable file
1476
config.guess
vendored
Executable file
File diff suppressed because it is too large
Load Diff
265
config.h.in
Normal file
265
config.h.in
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||||
|
systems. This function is required for `alloca.c' support on those systems.
|
||||||
|
*/
|
||||||
|
#undef CRAY_STACKSEG_END
|
||||||
|
|
||||||
|
/* Define to 1 if using `alloca.c'. */
|
||||||
|
#undef C_ALLOCA
|
||||||
|
|
||||||
|
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||||
|
#undef HAVE_ALLOCA
|
||||||
|
|
||||||
|
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||||
|
*/
|
||||||
|
#undef HAVE_ALLOCA_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||||
|
#undef HAVE_ARPA_INET_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `clock_gettime' function. */
|
||||||
|
#undef HAVE_CLOCK_GETTIME
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
|
#undef HAVE_DLFCN_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <float.h> header file. */
|
||||||
|
#undef HAVE_FLOAT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `floor' function. */
|
||||||
|
#undef HAVE_FLOOR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `gettimeofday' function. */
|
||||||
|
#undef HAVE_GETTIMEOFDAY
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `inet_ntoa' function. */
|
||||||
|
#undef HAVE_INET_NTOA
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `crypto' library (-lcrypto). */
|
||||||
|
#undef HAVE_LIBCRYPTO
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `dl' library (-ldl). */
|
||||||
|
#undef HAVE_LIBDL
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `m' library (-lm). */
|
||||||
|
#undef HAVE_LIBM
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `opus' library (-lopus). */
|
||||||
|
#undef HAVE_LIBOPUS
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `pthread' library (-lpthread). */
|
||||||
|
#undef HAVE_LIBPTHREAD
|
||||||
|
|
||||||
|
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||||
|
to 0 otherwise. */
|
||||||
|
#undef HAVE_MALLOC
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <malloc.h> header file. */
|
||||||
|
#undef HAVE_MALLOC_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `memmove' function. */
|
||||||
|
#undef HAVE_MEMMOVE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `memset' function. */
|
||||||
|
#undef HAVE_MEMSET
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <netdb.h> header file. */
|
||||||
|
#undef HAVE_NETDB_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||||
|
#undef HAVE_NETINET_IN_H
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `ptrdiff_t'. */
|
||||||
|
#undef HAVE_PTRDIFF_T
|
||||||
|
|
||||||
|
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
|
||||||
|
and to 0 otherwise. */
|
||||||
|
#undef HAVE_REALLOC
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `select' function. */
|
||||||
|
#undef HAVE_SELECT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `socket' function. */
|
||||||
|
#undef HAVE_SOCKET
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `sqrt' function. */
|
||||||
|
#undef HAVE_SQRT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stddef.h> header file. */
|
||||||
|
#undef HAVE_STDDEF_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#undef HAVE_STDINT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#undef HAVE_STDLIB_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strcasecmp' function. */
|
||||||
|
#undef HAVE_STRCASECMP
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strchr' function. */
|
||||||
|
#undef HAVE_STRCHR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strerror' function. */
|
||||||
|
#undef HAVE_STRERROR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#undef HAVE_STRINGS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#undef HAVE_STRING_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strncasecmp' function. */
|
||||||
|
#undef HAVE_STRNCASECMP
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strstr' function. */
|
||||||
|
#undef HAVE_STRSTR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strtol' function. */
|
||||||
|
#undef HAVE_STRTOL
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strtoul' function. */
|
||||||
|
#undef HAVE_STRTOUL
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||||
|
#undef HAVE_SYS_IOCTL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||||
|
#undef HAVE_SYS_SOCKET_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#undef HAVE_SYS_STAT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||||
|
#undef HAVE_SYS_TIME_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#undef HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `uname' function. */
|
||||||
|
#undef HAVE_UNAME
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <wchar.h> header file. */
|
||||||
|
#undef HAVE_WCHAR_H
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `_Bool'. */
|
||||||
|
#undef HAVE__BOOL
|
||||||
|
|
||||||
|
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||||
|
#undef LT_OBJDIR
|
||||||
|
|
||||||
|
/* Name of package */
|
||||||
|
#undef PACKAGE
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#undef PACKAGE_BUGREPORT
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#undef PACKAGE_NAME
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#undef PACKAGE_STRING
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#undef PACKAGE_TARNAME
|
||||||
|
|
||||||
|
/* Define to the home page for this package. */
|
||||||
|
#undef PACKAGE_URL
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
|
/* If using the C implementation of alloca, define if you know the
|
||||||
|
direction of stack growth for your system; otherwise it will be
|
||||||
|
automatically deduced at runtime.
|
||||||
|
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||||
|
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||||
|
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||||
|
#undef STACK_DIRECTION
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
|
/* Version number of package */
|
||||||
|
#undef VERSION
|
||||||
|
|
||||||
|
/* Define to disable ALSA support */
|
||||||
|
#undef WITHOUT_ALSA
|
||||||
|
|
||||||
|
/* Define to disable PulseAudio support */
|
||||||
|
#undef WITHOUT_PULSE
|
||||||
|
|
||||||
|
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
|
||||||
|
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||||
|
#define below would cause a syntax error. */
|
||||||
|
#undef _UINT32_T
|
||||||
|
|
||||||
|
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
|
||||||
|
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||||
|
#define below would cause a syntax error. */
|
||||||
|
#undef _UINT64_T
|
||||||
|
|
||||||
|
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
|
||||||
|
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||||
|
#define below would cause a syntax error. */
|
||||||
|
#undef _UINT8_T
|
||||||
|
|
||||||
|
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||||
|
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#undef inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Define to the type of a signed integer type of width exactly 16 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef int16_t
|
||||||
|
|
||||||
|
/* Define to the type of a signed integer type of width exactly 32 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef int32_t
|
||||||
|
|
||||||
|
/* Define to the type of a signed integer type of width exactly 64 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef int64_t
|
||||||
|
|
||||||
|
/* Define to the type of a signed integer type of width exactly 8 bits if such
|
||||||
|
a type exists and the standard includes do not define it. */
|
||||||
|
#undef int8_t
|
||||||
|
|
||||||
|
/* Define to rpl_malloc if the replacement function should be used. */
|
||||||
|
#undef malloc
|
||||||
|
|
||||||
|
/* Define to rpl_realloc if the replacement function should be used. */
|
||||||
|
#undef realloc
|
||||||
|
|
||||||
|
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||||
|
#undef size_t
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> does not define. */
|
||||||
|
#undef ssize_t
|
||||||
|
|
||||||
|
/* Define to the type of an unsigned integer type of width exactly 16 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef uint16_t
|
||||||
|
|
||||||
|
/* Define to the type of an unsigned integer type of width exactly 32 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef uint32_t
|
||||||
|
|
||||||
|
/* Define to the type of an unsigned integer type of width exactly 64 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef uint64_t
|
||||||
|
|
||||||
|
/* Define to the type of an unsigned integer type of width exactly 8 bits if
|
||||||
|
such a type exists and the standard includes do not define it. */
|
||||||
|
#undef uint8_t
|
||||||
1801
config.sub
vendored
Executable file
1801
config.sub
vendored
Executable file
File diff suppressed because it is too large
Load Diff
110
configure.ac
Normal file
110
configure.ac
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
# -*- Autoconf -*-
|
||||||
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
AC_PREREQ([2.69])
|
||||||
|
AC_INIT([libtgvoip], [2.2], [https://github.com/grishka/libtgvoip/issues])
|
||||||
|
AC_CONFIG_SRCDIR([config.h.in])
|
||||||
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
AM_INIT_AUTOMAKE([subdir-objects])
|
||||||
|
AM_SILENT_RULES([yes])
|
||||||
|
LT_INIT
|
||||||
|
|
||||||
|
# Checks for programs.
|
||||||
|
AC_PROG_CXX
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_OBJCXX
|
||||||
|
AM_PROG_AS
|
||||||
|
AC_PROG_RANLIB
|
||||||
|
|
||||||
|
# Checks for libraries.
|
||||||
|
AC_CHECK_LIB([crypto], [SHA1], [], [AC_MSG_FAILURE([libssl-dev is required but not found])])
|
||||||
|
AC_CHECK_LIB([m], [floorf])
|
||||||
|
AC_CHECK_LIB([opus], [opus_decoder_create], [], [AC_MSG_FAILURE([libopus-dev is required but not found])])
|
||||||
|
AC_CHECK_LIB([pthread], [pthread_create])
|
||||||
|
|
||||||
|
AC_CANONICAL_HOST
|
||||||
|
|
||||||
|
AS_CASE([$host_cpu],
|
||||||
|
[i?86], [cpu_x86=yes],
|
||||||
|
[x86_64], [cpu_x86=yes],
|
||||||
|
[arm*], [cpu_arm=yes],
|
||||||
|
[AS_ECHO("!! WARNING: libtgvoip wasn't tested with your CPU architecture ($host_cpu)")]
|
||||||
|
)
|
||||||
|
AS_CASE([$host_cpu],
|
||||||
|
[armv7*], [cpu_armv7=yes]
|
||||||
|
)
|
||||||
|
AS_ECHO("Detected CPU: $host_cpu")
|
||||||
|
AM_CONDITIONAL(TARGET_CPU_X86, test "x$cpu_x86" == xyes)
|
||||||
|
AM_CONDITIONAL(TARGET_CPU_ARM, test "x$cpu_arm" == xyes)
|
||||||
|
AM_CONDITIONAL(TARGET_CPU_ARMV7, test "x$cpu_armv7" == xyes)
|
||||||
|
AS_ECHO("Detected OS: $host_os")
|
||||||
|
|
||||||
|
AS_CASE([$host_os],
|
||||||
|
[darwin*], [os_osx=yes]
|
||||||
|
)
|
||||||
|
AM_CONDITIONAL(TARGET_OS_OSX, test "x$os_osx" == xyes)
|
||||||
|
|
||||||
|
AS_IF([test "x$os_osx" != xyes], [ # Linux
|
||||||
|
AC_CHECK_LIB([dl], [dlopen])
|
||||||
|
|
||||||
|
AC_ARG_WITH([pulse], [AS_HELP_STRING([--without-pulse], [disable PulseAudio support])], [], [with_pulse=yes])
|
||||||
|
AC_ARG_WITH([alsa], [AS_HELP_STRING([--without-alsa], [disable ALSA support])], [], [with_alsa=yes])
|
||||||
|
|
||||||
|
AS_IF([test "x$with_pulse" == xno && test "x$with_alsa" == xno], [
|
||||||
|
AC_MSG_FAILURE([You can only disable either ALSA or PulseAudio, not both]);
|
||||||
|
])
|
||||||
|
|
||||||
|
AS_IF([test "x$with_pulse" != xno], [
|
||||||
|
AC_CHECK_LIB([pulse], [pa_context_new], [
|
||||||
|
AS_ECHO_N( ) # what is the proper way to check for a library without linking it?
|
||||||
|
], [
|
||||||
|
AC_MSG_FAILURE([libpulse-dev is required during build, but you don't have it installed. Use --without-pulse to disable PulseAudio support.])
|
||||||
|
])
|
||||||
|
], [
|
||||||
|
AC_DEFINE([WITHOUT_PULSE], [1], [Define to disable PulseAudio support])
|
||||||
|
])
|
||||||
|
|
||||||
|
AS_IF([test "x$with_alsa" != xno], [
|
||||||
|
AC_CHECK_LIB([asound], [snd_pcm_open], [
|
||||||
|
AS_ECHO_N( ) # what is the proper way to check for a library without linking it?
|
||||||
|
], [
|
||||||
|
AC_MSG_FAILURE([libasound-dev is required during build, but you don't have it installed. Use --without-alsa to disable ALSA support.])
|
||||||
|
])
|
||||||
|
], [
|
||||||
|
AC_DEFINE([WITHOUT_ALSA], [1], [Define to disable ALSA support])
|
||||||
|
])
|
||||||
|
]);
|
||||||
|
|
||||||
|
AM_CONDITIONAL(WITH_PULSE, test "x$with_pulse" == xyes)
|
||||||
|
AM_CONDITIONAL(WITH_ALSA, test "x$with_alsa" == xyes)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([dsp], [AS_HELP_STRING([--disable-dsp], [disable signal processing (echo cancellation, noise suppression, and automatic gain control)])], [], [enable_dsp=yes])
|
||||||
|
AM_CONDITIONAL(ENABLE_DSP, test "x$enable_dsp" == xyes)
|
||||||
|
|
||||||
|
# Checks for header files.
|
||||||
|
AC_FUNC_ALLOCA
|
||||||
|
AC_CHECK_HEADERS([arpa/inet.h float.h malloc.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h wchar.h])
|
||||||
|
|
||||||
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_CHECK_HEADER_STDBOOL
|
||||||
|
AC_C_INLINE
|
||||||
|
AC_TYPE_INT16_T
|
||||||
|
AC_TYPE_INT32_T
|
||||||
|
AC_TYPE_INT64_T
|
||||||
|
AC_TYPE_INT8_T
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_TYPE_SSIZE_T
|
||||||
|
AC_TYPE_UINT16_T
|
||||||
|
AC_TYPE_UINT32_T
|
||||||
|
AC_TYPE_UINT64_T
|
||||||
|
AC_TYPE_UINT8_T
|
||||||
|
AC_CHECK_TYPES([ptrdiff_t])
|
||||||
|
|
||||||
|
# Checks for library functions.
|
||||||
|
AC_FUNC_ERROR_AT_LINE
|
||||||
|
AC_FUNC_MALLOC
|
||||||
|
AC_FUNC_REALLOC
|
||||||
|
AC_CHECK_FUNCS([clock_gettime floor gettimeofday inet_ntoa memmove memset select socket sqrt strcasecmp strchr strerror strncasecmp strstr strtol strtoul uname])
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([Makefile])
|
||||||
|
AC_OUTPUT
|
||||||
791
depcomp
Executable file
791
depcomp
Executable file
@ -0,0 +1,791 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# depcomp - compile a program generating dependencies as side-effects
|
||||||
|
|
||||||
|
scriptversion=2018-03-07.03; # UTC
|
||||||
|
|
||||||
|
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
'')
|
||||||
|
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||||
|
exit 1;
|
||||||
|
;;
|
||||||
|
-h | --h*)
|
||||||
|
cat <<\EOF
|
||||||
|
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||||
|
|
||||||
|
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||||
|
as side-effects.
|
||||||
|
|
||||||
|
Environment variables:
|
||||||
|
depmode Dependency tracking mode.
|
||||||
|
source Source file read by 'PROGRAMS ARGS'.
|
||||||
|
object Object file output by 'PROGRAMS ARGS'.
|
||||||
|
DEPDIR directory where to store dependencies.
|
||||||
|
depfile Dependency file to output.
|
||||||
|
tmpdepfile Temporary file to use when outputting dependencies.
|
||||||
|
libtool Whether libtool is used (yes/no).
|
||||||
|
|
||||||
|
Report bugs to <bug-automake@gnu.org>.
|
||||||
|
EOF
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
-v | --v*)
|
||||||
|
echo "depcomp $scriptversion"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Get the directory component of the given path, and save it in the
|
||||||
|
# global variables '$dir'. Note that this directory component will
|
||||||
|
# be either empty or ending with a '/' character. This is deliberate.
|
||||||
|
set_dir_from ()
|
||||||
|
{
|
||||||
|
case $1 in
|
||||||
|
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
|
||||||
|
*) dir=;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get the suffix-stripped basename of the given path, and save it the
|
||||||
|
# global variable '$base'.
|
||||||
|
set_base_from ()
|
||||||
|
{
|
||||||
|
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
|
||||||
|
}
|
||||||
|
|
||||||
|
# If no dependency file was actually created by the compiler invocation,
|
||||||
|
# we still have to create a dummy depfile, to avoid errors with the
|
||||||
|
# Makefile "include basename.Plo" scheme.
|
||||||
|
make_dummy_depfile ()
|
||||||
|
{
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Factor out some common post-processing of the generated depfile.
|
||||||
|
# Requires the auxiliary global variable '$tmpdepfile' to be set.
|
||||||
|
aix_post_process_depfile ()
|
||||||
|
{
|
||||||
|
# If the compiler actually managed to produce a dependency file,
|
||||||
|
# post-process it.
|
||||||
|
if test -f "$tmpdepfile"; then
|
||||||
|
# Each line is of the form 'foo.o: dependency.h'.
|
||||||
|
# Do two passes, one to just change these to
|
||||||
|
# $object: dependency.h
|
||||||
|
# and one to simply output
|
||||||
|
# dependency.h:
|
||||||
|
# which is needed to avoid the deleted-header problem.
|
||||||
|
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
|
||||||
|
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
|
||||||
|
} > "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
else
|
||||||
|
make_dummy_depfile
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# A tabulation character.
|
||||||
|
tab=' '
|
||||||
|
# A newline character.
|
||||||
|
nl='
|
||||||
|
'
|
||||||
|
# Character ranges might be problematic outside the C locale.
|
||||||
|
# These definitions help.
|
||||||
|
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||||
|
lower=abcdefghijklmnopqrstuvwxyz
|
||||||
|
digits=0123456789
|
||||||
|
alpha=${upper}${lower}
|
||||||
|
|
||||||
|
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||||
|
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||||
|
depfile=${depfile-`echo "$object" |
|
||||||
|
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||||
|
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||||
|
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
|
||||||
|
# Avoid interferences from the environment.
|
||||||
|
gccflag= dashmflag=
|
||||||
|
|
||||||
|
# Some modes work just like other modes, but use different flags. We
|
||||||
|
# parameterize here, but still list the modes in the big case below,
|
||||||
|
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||||
|
# here, because this file can only contain one case statement.
|
||||||
|
if test "$depmode" = hp; then
|
||||||
|
# HP compiler uses -M and no extra arg.
|
||||||
|
gccflag=-M
|
||||||
|
depmode=gcc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$depmode" = dashXmstdout; then
|
||||||
|
# This is just like dashmstdout with a different argument.
|
||||||
|
dashmflag=-xM
|
||||||
|
depmode=dashmstdout
|
||||||
|
fi
|
||||||
|
|
||||||
|
cygpath_u="cygpath -u -f -"
|
||||||
|
if test "$depmode" = msvcmsys; then
|
||||||
|
# This is just like msvisualcpp but w/o cygpath translation.
|
||||||
|
# Just convert the backslash-escaped backslashes to single forward
|
||||||
|
# slashes to satisfy depend.m4
|
||||||
|
cygpath_u='sed s,\\\\,/,g'
|
||||||
|
depmode=msvisualcpp
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$depmode" = msvc7msys; then
|
||||||
|
# This is just like msvc7 but w/o cygpath translation.
|
||||||
|
# Just convert the backslash-escaped backslashes to single forward
|
||||||
|
# slashes to satisfy depend.m4
|
||||||
|
cygpath_u='sed s,\\\\,/,g'
|
||||||
|
depmode=msvc7
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$depmode" = xlc; then
|
||||||
|
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
|
||||||
|
gccflag=-qmakedep=gcc,-MF
|
||||||
|
depmode=gcc
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$depmode" in
|
||||||
|
gcc3)
|
||||||
|
## gcc 3 implements dependency tracking that does exactly what
|
||||||
|
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||||
|
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||||
|
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||||
|
## the command line argument order; so add the flags where they
|
||||||
|
## appear in depend2.am. Note that the slowdown incurred here
|
||||||
|
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case $arg in
|
||||||
|
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||||
|
*) set fnord "$@" "$arg" ;;
|
||||||
|
esac
|
||||||
|
shift # fnord
|
||||||
|
shift # $arg
|
||||||
|
done
|
||||||
|
"$@"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
mv "$tmpdepfile" "$depfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
gcc)
|
||||||
|
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
|
||||||
|
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
|
||||||
|
## (see the conditional assignment to $gccflag above).
|
||||||
|
## There are various ways to get dependency output from gcc. Here's
|
||||||
|
## why we pick this rather obscure method:
|
||||||
|
## - Don't want to use -MD because we'd like the dependencies to end
|
||||||
|
## up in a subdir. Having to rename by hand is ugly.
|
||||||
|
## (We might end up doing this anyway to support other compilers.)
|
||||||
|
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||||
|
## -MM, not -M (despite what the docs say). Also, it might not be
|
||||||
|
## supported by the other compilers which use the 'gcc' depmode.
|
||||||
|
## - Using -M directly means running the compiler twice (even worse
|
||||||
|
## than renaming).
|
||||||
|
if test -z "$gccflag"; then
|
||||||
|
gccflag=-MD,
|
||||||
|
fi
|
||||||
|
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
# The second -e expression handles DOS-style file names with drive
|
||||||
|
# letters.
|
||||||
|
sed -e 's/^[^:]*: / /' \
|
||||||
|
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||||
|
## This next piece of magic avoids the "deleted header file" problem.
|
||||||
|
## The problem is that when a header file which appears in a .P file
|
||||||
|
## is deleted, the dependency causes make to die (because there is
|
||||||
|
## typically no way to rebuild the header). We avoid this by adding
|
||||||
|
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||||
|
## this for us directly.
|
||||||
|
## Some versions of gcc put a space before the ':'. On the theory
|
||||||
|
## that the space means something, we add a space to the output as
|
||||||
|
## well. hp depmode also adds that space, but also prefixes the VPATH
|
||||||
|
## to the object. Take care to not repeat it in the output.
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
tr ' ' "$nl" < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
|
||||||
|
| sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
hp)
|
||||||
|
# This case exists only to let depend.m4 do its work. It works by
|
||||||
|
# looking at the text of this script. This case will never be run,
|
||||||
|
# since it is checked for above.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
sgi)
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||||
|
else
|
||||||
|
"$@" -MDupdate "$tmpdepfile"
|
||||||
|
fi
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
# Clip off the initial element (the dependent). Don't try to be
|
||||||
|
# clever and replace this with sed code, as IRIX sed won't handle
|
||||||
|
# lines with more than a fixed number of characters (4096 in
|
||||||
|
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||||
|
# the IRIX cc adds comments like '#:fec' to the end of the
|
||||||
|
# dependency line.
|
||||||
|
tr ' ' "$nl" < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
|
||||||
|
| tr "$nl" ' ' >> "$depfile"
|
||||||
|
echo >> "$depfile"
|
||||||
|
# The second pass generates a dummy entry for each header file.
|
||||||
|
tr ' ' "$nl" < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||||
|
>> "$depfile"
|
||||||
|
else
|
||||||
|
make_dummy_depfile
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
xlc)
|
||||||
|
# This case exists only to let depend.m4 do its work. It works by
|
||||||
|
# looking at the text of this script. This case will never be run,
|
||||||
|
# since it is checked for above.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
aix)
|
||||||
|
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||||
|
# in a .u file. In older versions, this file always lives in the
|
||||||
|
# current directory. Also, the AIX compiler puts '$object:' at the
|
||||||
|
# start of each line; $object doesn't have directory information.
|
||||||
|
# Version 6 uses the directory in both cases.
|
||||||
|
set_dir_from "$object"
|
||||||
|
set_base_from "$object"
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
tmpdepfile1=$dir$base.u
|
||||||
|
tmpdepfile2=$base.u
|
||||||
|
tmpdepfile3=$dir.libs/$base.u
|
||||||
|
"$@" -Wc,-M
|
||||||
|
else
|
||||||
|
tmpdepfile1=$dir$base.u
|
||||||
|
tmpdepfile2=$dir$base.u
|
||||||
|
tmpdepfile3=$dir$base.u
|
||||||
|
"$@" -M
|
||||||
|
fi
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||||
|
do
|
||||||
|
test -f "$tmpdepfile" && break
|
||||||
|
done
|
||||||
|
aix_post_process_depfile
|
||||||
|
;;
|
||||||
|
|
||||||
|
tcc)
|
||||||
|
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
|
||||||
|
# FIXME: That version still under development at the moment of writing.
|
||||||
|
# Make that this statement remains true also for stable, released
|
||||||
|
# versions.
|
||||||
|
# It will wrap lines (doesn't matter whether long or short) with a
|
||||||
|
# trailing '\', as in:
|
||||||
|
#
|
||||||
|
# foo.o : \
|
||||||
|
# foo.c \
|
||||||
|
# foo.h \
|
||||||
|
#
|
||||||
|
# It will put a trailing '\' even on the last line, and will use leading
|
||||||
|
# spaces rather than leading tabs (at least since its commit 0394caf7
|
||||||
|
# "Emit spaces for -MD").
|
||||||
|
"$@" -MD -MF "$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
|
||||||
|
# We have to change lines of the first kind to '$object: \'.
|
||||||
|
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
|
||||||
|
# And for each line of the second kind, we have to emit a 'dep.h:'
|
||||||
|
# dummy dependency, to avoid the deleted-header problem.
|
||||||
|
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
## The order of this option in the case statement is important, since the
|
||||||
|
## shell code in configure will try each of these formats in the order
|
||||||
|
## listed in this file. A plain '-MD' option would be understood by many
|
||||||
|
## compilers, so we must ensure this comes after the gcc and icc options.
|
||||||
|
pgcc)
|
||||||
|
# Portland's C compiler understands '-MD'.
|
||||||
|
# Will always output deps to 'file.d' where file is the root name of the
|
||||||
|
# source file under compilation, even if file resides in a subdirectory.
|
||||||
|
# The object file name does not affect the name of the '.d' file.
|
||||||
|
# pgcc 10.2 will output
|
||||||
|
# foo.o: sub/foo.c sub/foo.h
|
||||||
|
# and will wrap long lines using '\' :
|
||||||
|
# foo.o: sub/foo.c ... \
|
||||||
|
# sub/foo.h ... \
|
||||||
|
# ...
|
||||||
|
set_dir_from "$object"
|
||||||
|
# Use the source, not the object, to determine the base name, since
|
||||||
|
# that's sadly what pgcc will do too.
|
||||||
|
set_base_from "$source"
|
||||||
|
tmpdepfile=$base.d
|
||||||
|
|
||||||
|
# For projects that build the same source file twice into different object
|
||||||
|
# files, the pgcc approach of using the *source* file root name can cause
|
||||||
|
# problems in parallel builds. Use a locking strategy to avoid stomping on
|
||||||
|
# the same $tmpdepfile.
|
||||||
|
lockdir=$base.d-lock
|
||||||
|
trap "
|
||||||
|
echo '$0: caught signal, cleaning up...' >&2
|
||||||
|
rmdir '$lockdir'
|
||||||
|
exit 1
|
||||||
|
" 1 2 13 15
|
||||||
|
numtries=100
|
||||||
|
i=$numtries
|
||||||
|
while test $i -gt 0; do
|
||||||
|
# mkdir is a portable test-and-set.
|
||||||
|
if mkdir "$lockdir" 2>/dev/null; then
|
||||||
|
# This process acquired the lock.
|
||||||
|
"$@" -MD
|
||||||
|
stat=$?
|
||||||
|
# Release the lock.
|
||||||
|
rmdir "$lockdir"
|
||||||
|
break
|
||||||
|
else
|
||||||
|
# If the lock is being held by a different process, wait
|
||||||
|
# until the winning process is done or we timeout.
|
||||||
|
while test -d "$lockdir" && test $i -gt 0; do
|
||||||
|
sleep 1
|
||||||
|
i=`expr $i - 1`
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
i=`expr $i - 1`
|
||||||
|
done
|
||||||
|
trap - 1 2 13 15
|
||||||
|
if test $i -le 0; then
|
||||||
|
echo "$0: failed to acquire lock after $numtries attempts" >&2
|
||||||
|
echo "$0: check lockdir '$lockdir'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
# Each line is of the form `foo.o: dependent.h',
|
||||||
|
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||||
|
# Do two passes, one to just change these to
|
||||||
|
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||||
|
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||||
|
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
# correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
|
||||||
|
| sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
hp2)
|
||||||
|
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||||
|
# compilers, which have integrated preprocessors. The correct option
|
||||||
|
# to use with these is +Maked; it writes dependencies to a file named
|
||||||
|
# 'foo.d', which lands next to the object file, wherever that
|
||||||
|
# happens to be.
|
||||||
|
# Much of this is similar to the tru64 case; see comments there.
|
||||||
|
set_dir_from "$object"
|
||||||
|
set_base_from "$object"
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
tmpdepfile1=$dir$base.d
|
||||||
|
tmpdepfile2=$dir.libs/$base.d
|
||||||
|
"$@" -Wc,+Maked
|
||||||
|
else
|
||||||
|
tmpdepfile1=$dir$base.d
|
||||||
|
tmpdepfile2=$dir$base.d
|
||||||
|
"$@" +Maked
|
||||||
|
fi
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||||
|
do
|
||||||
|
test -f "$tmpdepfile" && break
|
||||||
|
done
|
||||||
|
if test -f "$tmpdepfile"; then
|
||||||
|
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||||
|
# Add 'dependent.h:' lines.
|
||||||
|
sed -ne '2,${
|
||||||
|
s/^ *//
|
||||||
|
s/ \\*$//
|
||||||
|
s/$/:/
|
||||||
|
p
|
||||||
|
}' "$tmpdepfile" >> "$depfile"
|
||||||
|
else
|
||||||
|
make_dummy_depfile
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||||
|
;;
|
||||||
|
|
||||||
|
tru64)
|
||||||
|
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||||
|
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
|
||||||
|
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||||
|
# dependencies in 'foo.d' instead, so we check for that too.
|
||||||
|
# Subdirectories are respected.
|
||||||
|
set_dir_from "$object"
|
||||||
|
set_base_from "$object"
|
||||||
|
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
# Libtool generates 2 separate objects for the 2 libraries. These
|
||||||
|
# two compilations output dependencies in $dir.libs/$base.o.d and
|
||||||
|
# in $dir$base.o.d. We have to check for both files, because
|
||||||
|
# one of the two compilations can be disabled. We should prefer
|
||||||
|
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||||
|
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||||
|
# the former would cause a distcleancheck panic.
|
||||||
|
tmpdepfile1=$dir$base.o.d # libtool 1.5
|
||||||
|
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
|
||||||
|
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||||
|
"$@" -Wc,-MD
|
||||||
|
else
|
||||||
|
tmpdepfile1=$dir$base.d
|
||||||
|
tmpdepfile2=$dir$base.d
|
||||||
|
tmpdepfile3=$dir$base.d
|
||||||
|
"$@" -MD
|
||||||
|
fi
|
||||||
|
|
||||||
|
stat=$?
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||||
|
do
|
||||||
|
test -f "$tmpdepfile" && break
|
||||||
|
done
|
||||||
|
# Same post-processing that is required for AIX mode.
|
||||||
|
aix_post_process_depfile
|
||||||
|
;;
|
||||||
|
|
||||||
|
msvc7)
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
showIncludes=-Wc,-showIncludes
|
||||||
|
else
|
||||||
|
showIncludes=-showIncludes
|
||||||
|
fi
|
||||||
|
"$@" $showIncludes > "$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
grep -v '^Note: including file: ' "$tmpdepfile"
|
||||||
|
if test $stat -ne 0; then
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
# The first sed program below extracts the file names and escapes
|
||||||
|
# backslashes for cygpath. The second sed program outputs the file
|
||||||
|
# name when reading, but also accumulates all include files in the
|
||||||
|
# hold buffer in order to output them again at the end. This only
|
||||||
|
# works with sed implementations that can handle large buffers.
|
||||||
|
sed < "$tmpdepfile" -n '
|
||||||
|
/^Note: including file: *\(.*\)/ {
|
||||||
|
s//\1/
|
||||||
|
s/\\/\\\\/g
|
||||||
|
p
|
||||||
|
}' | $cygpath_u | sort -u | sed -n '
|
||||||
|
s/ /\\ /g
|
||||||
|
s/\(.*\)/'"$tab"'\1 \\/p
|
||||||
|
s/.\(.*\) \\/\1:/
|
||||||
|
H
|
||||||
|
$ {
|
||||||
|
s/.*/'"$tab"'/
|
||||||
|
G
|
||||||
|
p
|
||||||
|
}' >> "$depfile"
|
||||||
|
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
msvc7msys)
|
||||||
|
# This case exists only to let depend.m4 do its work. It works by
|
||||||
|
# looking at the text of this script. This case will never be run,
|
||||||
|
# since it is checked for above.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
#nosideeffect)
|
||||||
|
# This comment above is used by automake to tell side-effect
|
||||||
|
# dependency tracking mechanisms from slower ones.
|
||||||
|
|
||||||
|
dashmstdout)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the preprocessed file to stdout, regardless of -o.
|
||||||
|
"$@" || exit $?
|
||||||
|
|
||||||
|
# Remove the call to Libtool.
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test "X$1" != 'X--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove '-o $object'.
|
||||||
|
IFS=" "
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case $arg in
|
||||||
|
-o)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
$object)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift # fnord
|
||||||
|
shift # $arg
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
test -z "$dashmflag" && dashmflag=-M
|
||||||
|
# Require at least two characters before searching for ':'
|
||||||
|
# in the target name. This is to cope with DOS-style filenames:
|
||||||
|
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
|
||||||
|
"$@" $dashmflag |
|
||||||
|
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
|
||||||
|
rm -f "$depfile"
|
||||||
|
cat < "$tmpdepfile" > "$depfile"
|
||||||
|
# Some versions of the HPUX 10.20 sed can't process this sed invocation
|
||||||
|
# correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
tr ' ' "$nl" < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||||
|
| sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
dashXmstdout)
|
||||||
|
# This case only exists to satisfy depend.m4. It is never actually
|
||||||
|
# run, as this mode is specially recognized in the preamble.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
makedepend)
|
||||||
|
"$@" || exit $?
|
||||||
|
# Remove any Libtool call
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test "X$1" != 'X--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
# X makedepend
|
||||||
|
shift
|
||||||
|
cleared=no eat=no
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case $cleared in
|
||||||
|
no)
|
||||||
|
set ""; shift
|
||||||
|
cleared=yes ;;
|
||||||
|
esac
|
||||||
|
if test $eat = yes; then
|
||||||
|
eat=no
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
case "$arg" in
|
||||||
|
-D*|-I*)
|
||||||
|
set fnord "$@" "$arg"; shift ;;
|
||||||
|
# Strip any option that makedepend may not understand. Remove
|
||||||
|
# the object too, otherwise makedepend will parse it as a source file.
|
||||||
|
-arch)
|
||||||
|
eat=yes ;;
|
||||||
|
-*|$object)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"; shift ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||||
|
touch "$tmpdepfile"
|
||||||
|
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||||
|
rm -f "$depfile"
|
||||||
|
# makedepend may prepend the VPATH from the source file name to the object.
|
||||||
|
# No need to regex-escape $object, excess matching of '.' is harmless.
|
||||||
|
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
|
||||||
|
# Some versions of the HPUX 10.20 sed can't process the last invocation
|
||||||
|
# correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed '1,2d' "$tmpdepfile" \
|
||||||
|
| tr ' ' "$nl" \
|
||||||
|
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
|
||||||
|
| sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||||
|
;;
|
||||||
|
|
||||||
|
cpp)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the preprocessed file to stdout.
|
||||||
|
"$@" || exit $?
|
||||||
|
|
||||||
|
# Remove the call to Libtool.
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test "X$1" != 'X--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove '-o $object'.
|
||||||
|
IFS=" "
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case $arg in
|
||||||
|
-o)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
$object)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift # fnord
|
||||||
|
shift # $arg
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
"$@" -E \
|
||||||
|
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||||
|
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||||
|
| sed '$ s: \\$::' > "$tmpdepfile"
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
cat < "$tmpdepfile" >> "$depfile"
|
||||||
|
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
msvisualcpp)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the preprocessed file to stdout.
|
||||||
|
"$@" || exit $?
|
||||||
|
|
||||||
|
# Remove the call to Libtool.
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
while test "X$1" != 'X--mode=compile'; do
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
IFS=" "
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
case "$arg" in
|
||||||
|
-o)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
$object)
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||||
|
set fnord "$@"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set fnord "$@" "$arg"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
"$@" -E 2>/dev/null |
|
||||||
|
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
|
||||||
|
echo "$tab" >> "$depfile"
|
||||||
|
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
msvcmsys)
|
||||||
|
# This case exists only to let depend.m4 do its work. It works by
|
||||||
|
# looking at the text of this script. This case will never be run,
|
||||||
|
# since it is checked for above.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
none)
|
||||||
|
exec "$@"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Unknown depmode $depmode" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: shell-script
|
||||||
|
# sh-indentation: 2
|
||||||
|
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC0"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
||||||
518
install-sh
Executable file
518
install-sh
Executable file
@ -0,0 +1,518 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# install - install a program, script, or datafile
|
||||||
|
|
||||||
|
scriptversion=2018-03-11.20; # UTC
|
||||||
|
|
||||||
|
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||||
|
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||||
|
# following copyright and license.
|
||||||
|
#
|
||||||
|
# Copyright (C) 1994 X Consortium
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||||
|
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
# Except as contained in this notice, the name of the X Consortium shall not
|
||||||
|
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||||
|
# ings in this Software without prior written authorization from the X Consor-
|
||||||
|
# tium.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FSF changes to this file are in the public domain.
|
||||||
|
#
|
||||||
|
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||||
|
# 'make' implicit rules from creating a file called install from it
|
||||||
|
# when there is no Makefile.
|
||||||
|
#
|
||||||
|
# This script is compatible with the BSD install script, but was written
|
||||||
|
# from scratch.
|
||||||
|
|
||||||
|
tab=' '
|
||||||
|
nl='
|
||||||
|
'
|
||||||
|
IFS=" $tab$nl"
|
||||||
|
|
||||||
|
# Set DOITPROG to "echo" to test this script.
|
||||||
|
|
||||||
|
doit=${DOITPROG-}
|
||||||
|
doit_exec=${doit:-exec}
|
||||||
|
|
||||||
|
# Put in absolute file names if you don't have them in your path;
|
||||||
|
# or use environment vars.
|
||||||
|
|
||||||
|
chgrpprog=${CHGRPPROG-chgrp}
|
||||||
|
chmodprog=${CHMODPROG-chmod}
|
||||||
|
chownprog=${CHOWNPROG-chown}
|
||||||
|
cmpprog=${CMPPROG-cmp}
|
||||||
|
cpprog=${CPPROG-cp}
|
||||||
|
mkdirprog=${MKDIRPROG-mkdir}
|
||||||
|
mvprog=${MVPROG-mv}
|
||||||
|
rmprog=${RMPROG-rm}
|
||||||
|
stripprog=${STRIPPROG-strip}
|
||||||
|
|
||||||
|
posix_mkdir=
|
||||||
|
|
||||||
|
# Desired mode of installed file.
|
||||||
|
mode=0755
|
||||||
|
|
||||||
|
chgrpcmd=
|
||||||
|
chmodcmd=$chmodprog
|
||||||
|
chowncmd=
|
||||||
|
mvcmd=$mvprog
|
||||||
|
rmcmd="$rmprog -f"
|
||||||
|
stripcmd=
|
||||||
|
|
||||||
|
src=
|
||||||
|
dst=
|
||||||
|
dir_arg=
|
||||||
|
dst_arg=
|
||||||
|
|
||||||
|
copy_on_change=false
|
||||||
|
is_target_a_directory=possibly
|
||||||
|
|
||||||
|
usage="\
|
||||||
|
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||||
|
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||||
|
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||||
|
or: $0 [OPTION]... -d DIRECTORIES...
|
||||||
|
|
||||||
|
In the 1st form, copy SRCFILE to DSTFILE.
|
||||||
|
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||||
|
In the 4th, create DIRECTORIES.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help display this help and exit.
|
||||||
|
--version display version info and exit.
|
||||||
|
|
||||||
|
-c (ignored)
|
||||||
|
-C install only if different (preserve the last data modification time)
|
||||||
|
-d create directories instead of installing files.
|
||||||
|
-g GROUP $chgrpprog installed files to GROUP.
|
||||||
|
-m MODE $chmodprog installed files to MODE.
|
||||||
|
-o USER $chownprog installed files to USER.
|
||||||
|
-s $stripprog installed files.
|
||||||
|
-t DIRECTORY install into DIRECTORY.
|
||||||
|
-T report an error if DSTFILE is a directory.
|
||||||
|
|
||||||
|
Environment variables override the default commands:
|
||||||
|
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||||
|
RMPROG STRIPPROG
|
||||||
|
"
|
||||||
|
|
||||||
|
while test $# -ne 0; do
|
||||||
|
case $1 in
|
||||||
|
-c) ;;
|
||||||
|
|
||||||
|
-C) copy_on_change=true;;
|
||||||
|
|
||||||
|
-d) dir_arg=true;;
|
||||||
|
|
||||||
|
-g) chgrpcmd="$chgrpprog $2"
|
||||||
|
shift;;
|
||||||
|
|
||||||
|
--help) echo "$usage"; exit $?;;
|
||||||
|
|
||||||
|
-m) mode=$2
|
||||||
|
case $mode in
|
||||||
|
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
|
||||||
|
echo "$0: invalid mode: $mode" >&2
|
||||||
|
exit 1;;
|
||||||
|
esac
|
||||||
|
shift;;
|
||||||
|
|
||||||
|
-o) chowncmd="$chownprog $2"
|
||||||
|
shift;;
|
||||||
|
|
||||||
|
-s) stripcmd=$stripprog;;
|
||||||
|
|
||||||
|
-t)
|
||||||
|
is_target_a_directory=always
|
||||||
|
dst_arg=$2
|
||||||
|
# Protect names problematic for 'test' and other utilities.
|
||||||
|
case $dst_arg in
|
||||||
|
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||||
|
esac
|
||||||
|
shift;;
|
||||||
|
|
||||||
|
-T) is_target_a_directory=never;;
|
||||||
|
|
||||||
|
--version) echo "$0 $scriptversion"; exit $?;;
|
||||||
|
|
||||||
|
--) shift
|
||||||
|
break;;
|
||||||
|
|
||||||
|
-*) echo "$0: invalid option: $1" >&2
|
||||||
|
exit 1;;
|
||||||
|
|
||||||
|
*) break;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# We allow the use of options -d and -T together, by making -d
|
||||||
|
# take the precedence; this is for compatibility with GNU install.
|
||||||
|
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
if test -n "$dst_arg"; then
|
||||||
|
echo "$0: target directory not allowed when installing a directory." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||||
|
# When -d is used, all remaining arguments are directories to create.
|
||||||
|
# When -t is used, the destination is already specified.
|
||||||
|
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
if test -n "$dst_arg"; then
|
||||||
|
# $@ is not empty: it contains at least $arg.
|
||||||
|
set fnord "$@" "$dst_arg"
|
||||||
|
shift # fnord
|
||||||
|
fi
|
||||||
|
shift # arg
|
||||||
|
dst_arg=$arg
|
||||||
|
# Protect names problematic for 'test' and other utilities.
|
||||||
|
case $dst_arg in
|
||||||
|
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test $# -eq 0; then
|
||||||
|
if test -z "$dir_arg"; then
|
||||||
|
echo "$0: no input file specified." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# It's OK to call 'install-sh -d' without argument.
|
||||||
|
# This can happen when creating conditional directories.
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$dir_arg"; then
|
||||||
|
if test $# -gt 1 || test "$is_target_a_directory" = always; then
|
||||||
|
if test ! -d "$dst_arg"; then
|
||||||
|
echo "$0: $dst_arg: Is not a directory." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$dir_arg"; then
|
||||||
|
do_exit='(exit $ret); exit $ret'
|
||||||
|
trap "ret=129; $do_exit" 1
|
||||||
|
trap "ret=130; $do_exit" 2
|
||||||
|
trap "ret=141; $do_exit" 13
|
||||||
|
trap "ret=143; $do_exit" 15
|
||||||
|
|
||||||
|
# Set umask so as not to create temps with too-generous modes.
|
||||||
|
# However, 'strip' requires both read and write access to temps.
|
||||||
|
case $mode in
|
||||||
|
# Optimize common cases.
|
||||||
|
*644) cp_umask=133;;
|
||||||
|
*755) cp_umask=22;;
|
||||||
|
|
||||||
|
*[0-7])
|
||||||
|
if test -z "$stripcmd"; then
|
||||||
|
u_plus_rw=
|
||||||
|
else
|
||||||
|
u_plus_rw='% 200'
|
||||||
|
fi
|
||||||
|
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||||
|
*)
|
||||||
|
if test -z "$stripcmd"; then
|
||||||
|
u_plus_rw=
|
||||||
|
else
|
||||||
|
u_plus_rw=,u+rw
|
||||||
|
fi
|
||||||
|
cp_umask=$mode$u_plus_rw;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
for src
|
||||||
|
do
|
||||||
|
# Protect names problematic for 'test' and other utilities.
|
||||||
|
case $src in
|
||||||
|
-* | [=\(\)!]) src=./$src;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
dst=$src
|
||||||
|
dstdir=$dst
|
||||||
|
test -d "$dstdir"
|
||||||
|
dstdir_status=$?
|
||||||
|
else
|
||||||
|
|
||||||
|
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||||
|
# might cause directories to be created, which would be especially bad
|
||||||
|
# if $src (and thus $dsttmp) contains '*'.
|
||||||
|
if test ! -f "$src" && test ! -d "$src"; then
|
||||||
|
echo "$0: $src does not exist." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$dst_arg"; then
|
||||||
|
echo "$0: no destination specified." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
dst=$dst_arg
|
||||||
|
|
||||||
|
# If destination is a directory, append the input filename.
|
||||||
|
if test -d "$dst"; then
|
||||||
|
if test "$is_target_a_directory" = never; then
|
||||||
|
echo "$0: $dst_arg: Is a directory" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
dstdir=$dst
|
||||||
|
dstbase=`basename "$src"`
|
||||||
|
case $dst in
|
||||||
|
*/) dst=$dst$dstbase;;
|
||||||
|
*) dst=$dst/$dstbase;;
|
||||||
|
esac
|
||||||
|
dstdir_status=0
|
||||||
|
else
|
||||||
|
dstdir=`dirname "$dst"`
|
||||||
|
test -d "$dstdir"
|
||||||
|
dstdir_status=$?
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $dstdir in
|
||||||
|
*/) dstdirslash=$dstdir;;
|
||||||
|
*) dstdirslash=$dstdir/;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
obsolete_mkdir_used=false
|
||||||
|
|
||||||
|
if test $dstdir_status != 0; then
|
||||||
|
case $posix_mkdir in
|
||||||
|
'')
|
||||||
|
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||||
|
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||||
|
umask=`umask`
|
||||||
|
case $stripcmd.$umask in
|
||||||
|
# Optimize common cases.
|
||||||
|
*[2367][2367]) mkdir_umask=$umask;;
|
||||||
|
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||||
|
|
||||||
|
*[0-7])
|
||||||
|
mkdir_umask=`expr $umask + 22 \
|
||||||
|
- $umask % 100 % 40 + $umask % 20 \
|
||||||
|
- $umask % 10 % 4 + $umask % 2
|
||||||
|
`;;
|
||||||
|
*) mkdir_umask=$umask,go-w;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# With -d, create the new directory with the user-specified mode.
|
||||||
|
# Otherwise, rely on $mkdir_umask.
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
mkdir_mode=-m$mode
|
||||||
|
else
|
||||||
|
mkdir_mode=
|
||||||
|
fi
|
||||||
|
|
||||||
|
posix_mkdir=false
|
||||||
|
case $umask in
|
||||||
|
*[123567][0-7][0-7])
|
||||||
|
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||||
|
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Note that $RANDOM variable is not portable (e.g. dash); Use it
|
||||||
|
# here however when possible just to lower collision chance.
|
||||||
|
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||||
|
|
||||||
|
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||||
|
|
||||||
|
# Because "mkdir -p" follows existing symlinks and we likely work
|
||||||
|
# directly in world-writeable /tmp, make sure that the '$tmpdir'
|
||||||
|
# directory is successfully created first before we actually test
|
||||||
|
# 'mkdir -p' feature.
|
||||||
|
if (umask $mkdir_umask &&
|
||||||
|
$mkdirprog $mkdir_mode "$tmpdir" &&
|
||||||
|
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
if test -z "$dir_arg" || {
|
||||||
|
# Check for POSIX incompatibilities with -m.
|
||||||
|
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||||
|
# other-writable bit of parent directory when it shouldn't.
|
||||||
|
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||||
|
test_tmpdir="$tmpdir/a"
|
||||||
|
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
|
||||||
|
case $ls_ld_tmpdir in
|
||||||
|
d????-?r-*) different_mode=700;;
|
||||||
|
d????-?--*) different_mode=755;;
|
||||||
|
*) false;;
|
||||||
|
esac &&
|
||||||
|
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
|
||||||
|
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
|
||||||
|
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
then posix_mkdir=:
|
||||||
|
fi
|
||||||
|
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
|
||||||
|
else
|
||||||
|
# Remove any dirs left behind by ancient mkdir implementations.
|
||||||
|
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
|
||||||
|
fi
|
||||||
|
trap '' 0;;
|
||||||
|
esac;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if
|
||||||
|
$posix_mkdir && (
|
||||||
|
umask $mkdir_umask &&
|
||||||
|
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||||
|
)
|
||||||
|
then :
|
||||||
|
else
|
||||||
|
|
||||||
|
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||||
|
# or it failed possibly due to a race condition. Create the
|
||||||
|
# directory the slow way, step by step, checking for races as we go.
|
||||||
|
|
||||||
|
case $dstdir in
|
||||||
|
/*) prefix='/';;
|
||||||
|
[-=\(\)!]*) prefix='./';;
|
||||||
|
*) prefix='';;
|
||||||
|
esac
|
||||||
|
|
||||||
|
oIFS=$IFS
|
||||||
|
IFS=/
|
||||||
|
set -f
|
||||||
|
set fnord $dstdir
|
||||||
|
shift
|
||||||
|
set +f
|
||||||
|
IFS=$oIFS
|
||||||
|
|
||||||
|
prefixes=
|
||||||
|
|
||||||
|
for d
|
||||||
|
do
|
||||||
|
test X"$d" = X && continue
|
||||||
|
|
||||||
|
prefix=$prefix$d
|
||||||
|
if test -d "$prefix"; then
|
||||||
|
prefixes=
|
||||||
|
else
|
||||||
|
if $posix_mkdir; then
|
||||||
|
(umask=$mkdir_umask &&
|
||||||
|
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||||
|
# Don't fail if two instances are running concurrently.
|
||||||
|
test -d "$prefix" || exit 1
|
||||||
|
else
|
||||||
|
case $prefix in
|
||||||
|
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||||
|
*) qprefix=$prefix;;
|
||||||
|
esac
|
||||||
|
prefixes="$prefixes '$qprefix'"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
prefix=$prefix/
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -n "$prefixes"; then
|
||||||
|
# Don't fail if two instances are running concurrently.
|
||||||
|
(umask $mkdir_umask &&
|
||||||
|
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||||
|
test -d "$dstdir" || exit 1
|
||||||
|
obsolete_mkdir_used=true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||||
|
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||||
|
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||||
|
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||||
|
else
|
||||||
|
|
||||||
|
# Make a couple of temp file names in the proper directory.
|
||||||
|
dsttmp=${dstdirslash}_inst.$$_
|
||||||
|
rmtmp=${dstdirslash}_rm.$$_
|
||||||
|
|
||||||
|
# Trap to clean up those temp files at exit.
|
||||||
|
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||||
|
|
||||||
|
# Copy the file name to the temp name.
|
||||||
|
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||||
|
|
||||||
|
# and set any options; do chmod last to preserve setuid bits.
|
||||||
|
#
|
||||||
|
# If any of these fail, we abort the whole thing. If we want to
|
||||||
|
# ignore errors from any of these, just make sure not to ignore
|
||||||
|
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||||
|
#
|
||||||
|
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||||
|
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||||
|
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||||
|
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||||
|
|
||||||
|
# If -C, don't bother to copy if it wouldn't change the file.
|
||||||
|
if $copy_on_change &&
|
||||||
|
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||||
|
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||||
|
set -f &&
|
||||||
|
set X $old && old=:$2:$4:$5:$6 &&
|
||||||
|
set X $new && new=:$2:$4:$5:$6 &&
|
||||||
|
set +f &&
|
||||||
|
test "$old" = "$new" &&
|
||||||
|
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
rm -f "$dsttmp"
|
||||||
|
else
|
||||||
|
# Rename the file to the real destination.
|
||||||
|
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||||
|
|
||||||
|
# The rename failed, perhaps because mv can't rename something else
|
||||||
|
# to itself, or perhaps because mv is so ancient that it does not
|
||||||
|
# support -f.
|
||||||
|
{
|
||||||
|
# Now remove or move aside any old file at destination location.
|
||||||
|
# We try this two ways since rm can't unlink itself on some
|
||||||
|
# systems and the destination file might be busy for other
|
||||||
|
# reasons. In this case, the final cleanup might fail but the new
|
||||||
|
# file should still install successfully.
|
||||||
|
{
|
||||||
|
test ! -f "$dst" ||
|
||||||
|
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||||
|
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||||
|
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||||
|
} ||
|
||||||
|
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||||
|
(exit 1); exit 1
|
||||||
|
}
|
||||||
|
} &&
|
||||||
|
|
||||||
|
# Now rename the file to the real destination.
|
||||||
|
$doit $mvcmd "$dsttmp" "$dst"
|
||||||
|
}
|
||||||
|
fi || exit 1
|
||||||
|
|
||||||
|
trap '' 0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC0"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
||||||
@ -61,6 +61,10 @@
|
|||||||
'<(tgvoip_src_loc)/NetworkSocket.h',
|
'<(tgvoip_src_loc)/NetworkSocket.h',
|
||||||
'<(tgvoip_src_loc)/PacketReassembler.cpp',
|
'<(tgvoip_src_loc)/PacketReassembler.cpp',
|
||||||
'<(tgvoip_src_loc)/PacketReassembler.h',
|
'<(tgvoip_src_loc)/PacketReassembler.h',
|
||||||
|
'<(tgvoip_src_loc)/MessageThread.cpp',
|
||||||
|
'<(tgvoip_src_loc)/MessageThread.h',
|
||||||
|
'<(tgvoip_src_loc)/audio/AudioIO.cpp',
|
||||||
|
'<(tgvoip_src_loc)/audio/AudioIO.h',
|
||||||
|
|
||||||
# Windows
|
# Windows
|
||||||
'<(tgvoip_src_loc)/os/windows/NetworkSocketWinsock.cpp',
|
'<(tgvoip_src_loc)/os/windows/NetworkSocketWinsock.cpp',
|
||||||
@ -97,8 +101,8 @@
|
|||||||
'<(tgvoip_src_loc)/os/linux/AudioOutputPulse.h',
|
'<(tgvoip_src_loc)/os/linux/AudioOutputPulse.h',
|
||||||
'<(tgvoip_src_loc)/os/linux/AudioInputPulse.cpp',
|
'<(tgvoip_src_loc)/os/linux/AudioInputPulse.cpp',
|
||||||
'<(tgvoip_src_loc)/os/linux/AudioInputPulse.h',
|
'<(tgvoip_src_loc)/os/linux/AudioInputPulse.h',
|
||||||
'<(tgvoip_src_loc)/os/linux/PulseAudioLoader.cpp',
|
'<(tgvoip_src_loc)/os/linux/AudioPulse.cpp',
|
||||||
'<(tgvoip_src_loc)/os/linux/PulseAudioLoader.h',
|
'<(tgvoip_src_loc)/os/linux/AudioPulse.h',
|
||||||
|
|
||||||
# POSIX
|
# POSIX
|
||||||
'<(tgvoip_src_loc)/os/posix/NetworkSocketPosix.cpp',
|
'<(tgvoip_src_loc)/os/posix/NetworkSocketPosix.cpp',
|
||||||
|
|||||||
@ -189,6 +189,10 @@
|
|||||||
69A6DE1C1E95ECF000000E69 /* wav_file.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DE181E95ECF000000E69 /* wav_file.h */; };
|
69A6DE1C1E95ECF000000E69 /* wav_file.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DE181E95ECF000000E69 /* wav_file.h */; };
|
||||||
69A6DE1D1E95ECF000000E69 /* wav_header.cc in Sources */ = {isa = PBXBuildFile; fileRef = 69A6DE191E95ECF000000E69 /* wav_header.cc */; };
|
69A6DE1D1E95ECF000000E69 /* wav_header.cc in Sources */ = {isa = PBXBuildFile; fileRef = 69A6DE191E95ECF000000E69 /* wav_header.cc */; };
|
||||||
69A6DE1E1E95ECF000000E69 /* wav_header.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DE1A1E95ECF000000E69 /* wav_header.h */; };
|
69A6DE1E1E95ECF000000E69 /* wav_header.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DE1A1E95ECF000000E69 /* wav_header.h */; };
|
||||||
|
69E357B020F88955002E163B /* AudioIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 69E357A720F88954002E163B /* AudioIO.cpp */; };
|
||||||
|
69E357B120F88955002E163B /* AudioIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 69E357AF20F88954002E163B /* AudioIO.h */; };
|
||||||
|
69FB0B2D20F6860E00827817 /* MessageThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 69FB0B2420F6860D00827817 /* MessageThread.cpp */; };
|
||||||
|
69FB0B2E20F6860E00827817 /* MessageThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 69FB0B2C20F6860D00827817 /* MessageThread.h */; };
|
||||||
D00ACA4F20222F5D0045D427 /* SetupLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = D00ACA4D20222F5D0045D427 /* SetupLogging.h */; };
|
D00ACA4F20222F5D0045D427 /* SetupLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = D00ACA4D20222F5D0045D427 /* SetupLogging.h */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
@ -429,7 +433,11 @@
|
|||||||
69A6DE181E95ECF000000E69 /* wav_file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wav_file.h; sourceTree = "<group>"; };
|
69A6DE181E95ECF000000E69 /* wav_file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wav_file.h; sourceTree = "<group>"; };
|
||||||
69A6DE191E95ECF000000E69 /* wav_header.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wav_header.cc; sourceTree = "<group>"; };
|
69A6DE191E95ECF000000E69 /* wav_header.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wav_header.cc; sourceTree = "<group>"; };
|
||||||
69A6DE1A1E95ECF000000E69 /* wav_header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wav_header.h; sourceTree = "<group>"; };
|
69A6DE1A1E95ECF000000E69 /* wav_header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wav_header.h; sourceTree = "<group>"; };
|
||||||
|
69E357A720F88954002E163B /* AudioIO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudioIO.cpp; sourceTree = "<group>"; };
|
||||||
|
69E357AF20F88954002E163B /* AudioIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioIO.h; sourceTree = "<group>"; };
|
||||||
69F842361E67540700C110F7 /* libtgvoip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libtgvoip.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
69F842361E67540700C110F7 /* libtgvoip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libtgvoip.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
69FB0B2420F6860D00827817 /* MessageThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MessageThread.cpp; sourceTree = "<group>"; };
|
||||||
|
69FB0B2C20F6860D00827817 /* MessageThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageThread.h; sourceTree = "<group>"; };
|
||||||
D00ACA4D20222F5D0045D427 /* SetupLogging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SetupLogging.h; sourceTree = "<group>"; };
|
D00ACA4D20222F5D0045D427 /* SetupLogging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SetupLogging.h; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
@ -476,6 +484,8 @@
|
|||||||
692AB8AA1E6759DD00706ACC /* logging.h */,
|
692AB8AA1E6759DD00706ACC /* logging.h */,
|
||||||
692AB8AB1E6759DD00706ACC /* MediaStreamItf.cpp */,
|
692AB8AB1E6759DD00706ACC /* MediaStreamItf.cpp */,
|
||||||
692AB8AC1E6759DD00706ACC /* MediaStreamItf.h */,
|
692AB8AC1E6759DD00706ACC /* MediaStreamItf.h */,
|
||||||
|
69FB0B2420F6860D00827817 /* MessageThread.cpp */,
|
||||||
|
69FB0B2C20F6860D00827817 /* MessageThread.h */,
|
||||||
69015D921E9D848700AC9763 /* NetworkSocket.cpp */,
|
69015D921E9D848700AC9763 /* NetworkSocket.cpp */,
|
||||||
69015D931E9D848700AC9763 /* NetworkSocket.h */,
|
69015D931E9D848700AC9763 /* NetworkSocket.h */,
|
||||||
692AB8AD1E6759DD00706ACC /* OpusDecoder.cpp */,
|
692AB8AD1E6759DD00706ACC /* OpusDecoder.cpp */,
|
||||||
@ -502,6 +512,8 @@
|
|||||||
692AB8891E6759DD00706ACC /* AudioInput.h */,
|
692AB8891E6759DD00706ACC /* AudioInput.h */,
|
||||||
692AB88A1E6759DD00706ACC /* AudioOutput.cpp */,
|
692AB88A1E6759DD00706ACC /* AudioOutput.cpp */,
|
||||||
692AB88B1E6759DD00706ACC /* AudioOutput.h */,
|
692AB88B1E6759DD00706ACC /* AudioOutput.h */,
|
||||||
|
69E357A720F88954002E163B /* AudioIO.cpp */,
|
||||||
|
69E357AF20F88954002E163B /* AudioIO.h */,
|
||||||
69791A551EE8272A00BB85FB /* Resampler.cpp */,
|
69791A551EE8272A00BB85FB /* Resampler.cpp */,
|
||||||
69791A561EE8272A00BB85FB /* Resampler.h */,
|
69791A561EE8272A00BB85FB /* Resampler.h */,
|
||||||
);
|
);
|
||||||
@ -910,6 +922,7 @@
|
|||||||
69A6DDFF1E95EC7700000E69 /* windows_private.h in Headers */,
|
69A6DDFF1E95EC7700000E69 /* windows_private.h in Headers */,
|
||||||
69A6DD961E95EC7700000E69 /* basictypes.h in Headers */,
|
69A6DD961E95EC7700000E69 /* basictypes.h in Headers */,
|
||||||
69A6DE161E95EC7800000E69 /* typedefs.h in Headers */,
|
69A6DE161E95EC7800000E69 /* typedefs.h in Headers */,
|
||||||
|
69E357B120F88955002E163B /* AudioIO.h in Headers */,
|
||||||
69A6DDE21E95EC7700000E69 /* aec_resampler.h in Headers */,
|
69A6DDE21E95EC7700000E69 /* aec_resampler.h in Headers */,
|
||||||
69A6DD9F1E95EC7700000E69 /* stringutils.h in Headers */,
|
69A6DD9F1E95EC7700000E69 /* stringutils.h in Headers */,
|
||||||
69A6DDDB1E95EC7700000E69 /* aec_common.h in Headers */,
|
69A6DDDB1E95EC7700000E69 /* aec_common.h in Headers */,
|
||||||
@ -919,6 +932,7 @@
|
|||||||
69A6DD991E95EC7700000E69 /* constructormagic.h in Headers */,
|
69A6DD991E95EC7700000E69 /* constructormagic.h in Headers */,
|
||||||
69A6DDA01E95EC7700000E69 /* type_traits.h in Headers */,
|
69A6DDA01E95EC7700000E69 /* type_traits.h in Headers */,
|
||||||
69A6DDBE1E95EC7700000E69 /* real_fft.h in Headers */,
|
69A6DDBE1E95EC7700000E69 /* real_fft.h in Headers */,
|
||||||
|
69FB0B2E20F6860E00827817 /* MessageThread.h in Headers */,
|
||||||
692AB8FC1E6759DD00706ACC /* AudioOutputAudioUnit.h in Headers */,
|
692AB8FC1E6759DD00706ACC /* AudioOutputAudioUnit.h in Headers */,
|
||||||
69A6DD941E95EC7700000E69 /* array_view.h in Headers */,
|
69A6DD941E95EC7700000E69 /* array_view.h in Headers */,
|
||||||
692AB8D01E6759DD00706ACC /* BlockingQueue.h in Headers */,
|
692AB8D01E6759DD00706ACC /* BlockingQueue.h in Headers */,
|
||||||
@ -1151,12 +1165,14 @@
|
|||||||
69A6DDB41E95EC7700000E69 /* downsample_fast.c in Sources */,
|
69A6DDB41E95EC7700000E69 /* downsample_fast.c in Sources */,
|
||||||
69A6DDEA1E95EC7700000E69 /* echo_control_mobile.cc in Sources */,
|
69A6DDEA1E95EC7700000E69 /* echo_control_mobile.cc in Sources */,
|
||||||
69A6DDF41E95EC7700000E69 /* noise_suppression.c in Sources */,
|
69A6DDF41E95EC7700000E69 /* noise_suppression.c in Sources */,
|
||||||
|
69FB0B2D20F6860E00827817 /* MessageThread.cpp in Sources */,
|
||||||
692AB8CF1E6759DD00706ACC /* BlockingQueue.cpp in Sources */,
|
692AB8CF1E6759DD00706ACC /* BlockingQueue.cpp in Sources */,
|
||||||
69A6DDC31E95EC7700000E69 /* levinson_durbin.c in Sources */,
|
69A6DDC31E95EC7700000E69 /* levinson_durbin.c in Sources */,
|
||||||
69A6DDF61E95EC7700000E69 /* noise_suppression_x.c in Sources */,
|
69A6DDF61E95EC7700000E69 /* noise_suppression_x.c in Sources */,
|
||||||
69A6DE1B1E95ECF000000E69 /* wav_file.cc in Sources */,
|
69A6DE1B1E95ECF000000E69 /* wav_file.cc in Sources */,
|
||||||
69A6DDCE1E95EC7700000E69 /* resample_by_2_internal.c in Sources */,
|
69A6DDCE1E95EC7700000E69 /* resample_by_2_internal.c in Sources */,
|
||||||
692AB8CB1E6759DD00706ACC /* AudioInput.cpp in Sources */,
|
692AB8CB1E6759DD00706ACC /* AudioInput.cpp in Sources */,
|
||||||
|
69E357B020F88955002E163B /* AudioIO.cpp in Sources */,
|
||||||
69A6DDCC1E95EC7700000E69 /* resample_48khz.c in Sources */,
|
69A6DDCC1E95EC7700000E69 /* resample_48khz.c in Sources */,
|
||||||
69A6DDAC1E95EC7700000E69 /* complex_bit_reverse_arm.S in Sources */,
|
69A6DDAC1E95EC7700000E69 /* complex_bit_reverse_arm.S in Sources */,
|
||||||
69A6DDD81E95EC7700000E69 /* vector_scaling_operations.c in Sources */,
|
69A6DDD81E95EC7700000E69 /* vector_scaling_operations.c in Sources */,
|
||||||
|
|||||||
@ -46,6 +46,8 @@
|
|||||||
695B20621EBD39FF00E31757 /* DarwinSpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 695B20601EBD39FF00E31757 /* DarwinSpecific.h */; };
|
695B20621EBD39FF00E31757 /* DarwinSpecific.h in Headers */ = {isa = PBXBuildFile; fileRef = 695B20601EBD39FF00E31757 /* DarwinSpecific.h */; };
|
||||||
6971220F20C8107F00971C2C /* PacketReassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6971220D20C8107E00971C2C /* PacketReassembler.cpp */; };
|
6971220F20C8107F00971C2C /* PacketReassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6971220D20C8107E00971C2C /* PacketReassembler.cpp */; };
|
||||||
6971221020C8107F00971C2C /* PacketReassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6971220E20C8107F00971C2C /* PacketReassembler.h */; };
|
6971221020C8107F00971C2C /* PacketReassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 6971220E20C8107F00971C2C /* PacketReassembler.h */; };
|
||||||
|
6976FD0320F6A7060019939E /* MessageThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6976FD0120F6A7050019939E /* MessageThread.cpp */; };
|
||||||
|
6976FD0420F6A7060019939E /* MessageThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 6976FD0220F6A7060019939E /* MessageThread.h */; };
|
||||||
698848421F4B39F700076DF0 /* AudioInputAudioUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6988483C1F4B39F700076DF0 /* AudioInputAudioUnit.h */; };
|
698848421F4B39F700076DF0 /* AudioInputAudioUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6988483C1F4B39F700076DF0 /* AudioInputAudioUnit.h */; };
|
||||||
698848441F4B39F700076DF0 /* AudioOutputAudioUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6988483E1F4B39F700076DF0 /* AudioOutputAudioUnit.h */; };
|
698848441F4B39F700076DF0 /* AudioOutputAudioUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6988483E1F4B39F700076DF0 /* AudioOutputAudioUnit.h */; };
|
||||||
698848461F4B39F700076DF0 /* AudioUnitIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 698848401F4B39F700076DF0 /* AudioUnitIO.h */; };
|
698848461F4B39F700076DF0 /* AudioUnitIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 698848401F4B39F700076DF0 /* AudioUnitIO.h */; };
|
||||||
@ -186,7 +188,6 @@
|
|||||||
69A6DF461E9614B700000E69 /* AudioOutputAudioUnitOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DF421E9614B700000E69 /* AudioOutputAudioUnitOSX.h */; };
|
69A6DF461E9614B700000E69 /* AudioOutputAudioUnitOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = 69A6DF421E9614B700000E69 /* AudioOutputAudioUnitOSX.h */; };
|
||||||
69AC14911F4B41CF00AC3173 /* Resampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 69AC148F1F4B41CF00AC3173 /* Resampler.h */; };
|
69AC14911F4B41CF00AC3173 /* Resampler.h in Headers */ = {isa = PBXBuildFile; fileRef = 69AC148F1F4B41CF00AC3173 /* Resampler.h */; };
|
||||||
C2A87DD81F4B6A33002D3F73 /* Resampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DD71F4B6A33002D3F73 /* Resampler.cpp */; };
|
C2A87DD81F4B6A33002D3F73 /* Resampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DD71F4B6A33002D3F73 /* Resampler.cpp */; };
|
||||||
C2A87DDA1F4B6A57002D3F73 /* DarwinSpecific.mm in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DD91F4B6A57002D3F73 /* DarwinSpecific.mm */; };
|
|
||||||
C2A87DDF1F4B6A61002D3F73 /* AudioInputAudioUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DDB1F4B6A61002D3F73 /* AudioInputAudioUnit.cpp */; };
|
C2A87DDF1F4B6A61002D3F73 /* AudioInputAudioUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DDB1F4B6A61002D3F73 /* AudioInputAudioUnit.cpp */; };
|
||||||
C2A87DE01F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DDD1F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp */; };
|
C2A87DE01F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DDD1F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp */; };
|
||||||
C2A87DE41F4B6AD3002D3F73 /* AudioUnitIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DE31F4B6AD3002D3F73 /* AudioUnitIO.cpp */; };
|
C2A87DE41F4B6AD3002D3F73 /* AudioUnitIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2A87DE31F4B6AD3002D3F73 /* AudioUnitIO.cpp */; };
|
||||||
@ -235,6 +236,13 @@
|
|||||||
remoteGlobalIDString = D020FB0A1D99637100F279AA;
|
remoteGlobalIDString = D020FB0A1D99637100F279AA;
|
||||||
remoteInfo = LegacyDatabase;
|
remoteInfo = LegacyDatabase;
|
||||||
};
|
};
|
||||||
|
6976FCFF20F6A6EF0019939E /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 692AB9071E675E8800706ACC /* Telegraph.xcodeproj */;
|
||||||
|
proxyType = 2;
|
||||||
|
remoteGlobalIDString = 099120C01EEAA63400F1366E;
|
||||||
|
remoteInfo = Widget;
|
||||||
|
};
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@ -280,6 +288,8 @@
|
|||||||
695B20611EBD39FF00E31757 /* DarwinSpecific.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = DarwinSpecific.mm; path = ../../../../../libtgvoip/os/darwin/DarwinSpecific.mm; sourceTree = "<group>"; };
|
695B20611EBD39FF00E31757 /* DarwinSpecific.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = DarwinSpecific.mm; path = ../../../../../libtgvoip/os/darwin/DarwinSpecific.mm; sourceTree = "<group>"; };
|
||||||
6971220D20C8107E00971C2C /* PacketReassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PacketReassembler.cpp; sourceTree = "<group>"; };
|
6971220D20C8107E00971C2C /* PacketReassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PacketReassembler.cpp; sourceTree = "<group>"; };
|
||||||
6971220E20C8107F00971C2C /* PacketReassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PacketReassembler.h; sourceTree = "<group>"; };
|
6971220E20C8107F00971C2C /* PacketReassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PacketReassembler.h; sourceTree = "<group>"; };
|
||||||
|
6976FD0120F6A7050019939E /* MessageThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MessageThread.cpp; sourceTree = "<group>"; };
|
||||||
|
6976FD0220F6A7060019939E /* MessageThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageThread.h; sourceTree = "<group>"; };
|
||||||
6988483B1F4B39F700076DF0 /* AudioInputAudioUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioInputAudioUnit.cpp; path = ../../../../../libtgvoip/os/darwin/AudioInputAudioUnit.cpp; sourceTree = "<group>"; };
|
6988483B1F4B39F700076DF0 /* AudioInputAudioUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioInputAudioUnit.cpp; path = ../../../../../libtgvoip/os/darwin/AudioInputAudioUnit.cpp; sourceTree = "<group>"; };
|
||||||
6988483C1F4B39F700076DF0 /* AudioInputAudioUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioInputAudioUnit.h; path = ../../../../../libtgvoip/os/darwin/AudioInputAudioUnit.h; sourceTree = "<group>"; };
|
6988483C1F4B39F700076DF0 /* AudioInputAudioUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioInputAudioUnit.h; path = ../../../../../libtgvoip/os/darwin/AudioInputAudioUnit.h; sourceTree = "<group>"; };
|
||||||
6988483D1F4B39F700076DF0 /* AudioOutputAudioUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioOutputAudioUnit.cpp; path = ../../../../../libtgvoip/os/darwin/AudioOutputAudioUnit.cpp; sourceTree = "<group>"; };
|
6988483D1F4B39F700076DF0 /* AudioOutputAudioUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AudioOutputAudioUnit.cpp; path = ../../../../../libtgvoip/os/darwin/AudioOutputAudioUnit.cpp; sourceTree = "<group>"; };
|
||||||
@ -425,7 +435,6 @@
|
|||||||
69AC148F1F4B41CF00AC3173 /* Resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Resampler.h; path = "../../../../Telegram-iOS/submodules/libtgvoip/audio/Resampler.h"; sourceTree = "<group>"; };
|
69AC148F1F4B41CF00AC3173 /* Resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Resampler.h; path = "../../../../Telegram-iOS/submodules/libtgvoip/audio/Resampler.h"; sourceTree = "<group>"; };
|
||||||
69F842361E67540700C110F7 /* libtgvoip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libtgvoip.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
69F842361E67540700C110F7 /* libtgvoip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libtgvoip.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
C2A87DD71F4B6A33002D3F73 /* Resampler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Resampler.cpp; path = audio/Resampler.cpp; sourceTree = "<group>"; };
|
C2A87DD71F4B6A33002D3F73 /* Resampler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Resampler.cpp; path = audio/Resampler.cpp; sourceTree = "<group>"; };
|
||||||
C2A87DD91F4B6A57002D3F73 /* DarwinSpecific.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = DarwinSpecific.mm; path = os/darwin/DarwinSpecific.mm; sourceTree = "<group>"; };
|
|
||||||
C2A87DDB1F4B6A61002D3F73 /* AudioInputAudioUnit.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioInputAudioUnit.cpp; path = os/darwin/AudioInputAudioUnit.cpp; sourceTree = "<group>"; };
|
C2A87DDB1F4B6A61002D3F73 /* AudioInputAudioUnit.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioInputAudioUnit.cpp; path = os/darwin/AudioInputAudioUnit.cpp; sourceTree = "<group>"; };
|
||||||
C2A87DDC1F4B6A61002D3F73 /* AudioInputAudioUnitOSX.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioInputAudioUnitOSX.cpp; path = os/darwin/AudioInputAudioUnitOSX.cpp; sourceTree = "<group>"; };
|
C2A87DDC1F4B6A61002D3F73 /* AudioInputAudioUnitOSX.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioInputAudioUnitOSX.cpp; path = os/darwin/AudioInputAudioUnitOSX.cpp; sourceTree = "<group>"; };
|
||||||
C2A87DDD1F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioOutputAudioUnit.cpp; path = os/darwin/AudioOutputAudioUnit.cpp; sourceTree = "<group>"; };
|
C2A87DDD1F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioOutputAudioUnit.cpp; path = os/darwin/AudioOutputAudioUnit.cpp; sourceTree = "<group>"; };
|
||||||
@ -479,6 +488,8 @@
|
|||||||
692AB8AA1E6759DD00706ACC /* logging.h */,
|
692AB8AA1E6759DD00706ACC /* logging.h */,
|
||||||
692AB8AB1E6759DD00706ACC /* MediaStreamItf.cpp */,
|
692AB8AB1E6759DD00706ACC /* MediaStreamItf.cpp */,
|
||||||
692AB8AC1E6759DD00706ACC /* MediaStreamItf.h */,
|
692AB8AC1E6759DD00706ACC /* MediaStreamItf.h */,
|
||||||
|
6976FD0120F6A7050019939E /* MessageThread.cpp */,
|
||||||
|
6976FD0220F6A7060019939E /* MessageThread.h */,
|
||||||
690725C01EBBD5F2005D860B /* NetworkSocket.cpp */,
|
690725C01EBBD5F2005D860B /* NetworkSocket.cpp */,
|
||||||
690725C11EBBD5F2005D860B /* NetworkSocket.h */,
|
690725C11EBBD5F2005D860B /* NetworkSocket.h */,
|
||||||
692AB8AD1E6759DD00706ACC /* OpusDecoder.cpp */,
|
692AB8AD1E6759DD00706ACC /* OpusDecoder.cpp */,
|
||||||
@ -559,6 +570,7 @@
|
|||||||
692AB9171E675E8800706ACC /* watchkitapp Extension.appex */,
|
692AB9171E675E8800706ACC /* watchkitapp Extension.appex */,
|
||||||
692AB9191E675E8800706ACC /* SiriIntents.appex */,
|
692AB9191E675E8800706ACC /* SiriIntents.appex */,
|
||||||
692AB91B1E675E8800706ACC /* LegacyDatabase.framework */,
|
692AB91B1E675E8800706ACC /* LegacyDatabase.framework */,
|
||||||
|
6976FD0020F6A6EF0019939E /* Widget.appex */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -855,7 +867,6 @@
|
|||||||
C2A87DDC1F4B6A61002D3F73 /* AudioInputAudioUnitOSX.cpp */,
|
C2A87DDC1F4B6A61002D3F73 /* AudioInputAudioUnitOSX.cpp */,
|
||||||
C2A87DDD1F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp */,
|
C2A87DDD1F4B6A61002D3F73 /* AudioOutputAudioUnit.cpp */,
|
||||||
C2A87DDE1F4B6A61002D3F73 /* AudioOutputAudioUnitOSX.cpp */,
|
C2A87DDE1F4B6A61002D3F73 /* AudioOutputAudioUnitOSX.cpp */,
|
||||||
C2A87DD91F4B6A57002D3F73 /* DarwinSpecific.mm */,
|
|
||||||
C2A87DD71F4B6A33002D3F73 /* Resampler.cpp */,
|
C2A87DD71F4B6A33002D3F73 /* Resampler.cpp */,
|
||||||
692AB8861E6759BF00706ACC /* libtgvoip */,
|
692AB8861E6759BF00706ACC /* libtgvoip */,
|
||||||
69F842371E67540700C110F7 /* Products */,
|
69F842371E67540700C110F7 /* Products */,
|
||||||
@ -900,6 +911,7 @@
|
|||||||
69A6DF3B1E96149300000E69 /* cpu_features_wrapper.h in Headers */,
|
69A6DF3B1E96149300000E69 /* cpu_features_wrapper.h in Headers */,
|
||||||
69A6DF211E96149300000E69 /* ns_core.h in Headers */,
|
69A6DF211E96149300000E69 /* ns_core.h in Headers */,
|
||||||
69A6DF051E96149300000E69 /* aec_core.h in Headers */,
|
69A6DF051E96149300000E69 /* aec_core.h in Headers */,
|
||||||
|
6976FD0420F6A7060019939E /* MessageThread.h in Headers */,
|
||||||
69A6DF441E9614B700000E69 /* AudioInputAudioUnitOSX.h in Headers */,
|
69A6DF441E9614B700000E69 /* AudioInputAudioUnitOSX.h in Headers */,
|
||||||
692AB8D91E6759DD00706ACC /* CongestionControl.h in Headers */,
|
692AB8D91E6759DD00706ACC /* CongestionControl.h in Headers */,
|
||||||
69A6DF031E96149300000E69 /* aec_common.h in Headers */,
|
69A6DF031E96149300000E69 /* aec_common.h in Headers */,
|
||||||
@ -1066,6 +1078,13 @@
|
|||||||
remoteRef = 692AB91A1E675E8800706ACC /* PBXContainerItemProxy */;
|
remoteRef = 692AB91A1E675E8800706ACC /* PBXContainerItemProxy */;
|
||||||
sourceTree = BUILT_PRODUCTS_DIR;
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
};
|
};
|
||||||
|
6976FD0020F6A6EF0019939E /* Widget.appex */ = {
|
||||||
|
isa = PBXReferenceProxy;
|
||||||
|
fileType = "wrapper.app-extension";
|
||||||
|
path = Widget.appex;
|
||||||
|
remoteRef = 6976FCFF20F6A6EF0019939E /* PBXContainerItemProxy */;
|
||||||
|
sourceTree = BUILT_PRODUCTS_DIR;
|
||||||
|
};
|
||||||
/* End PBXReferenceProxy section */
|
/* End PBXReferenceProxy section */
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
@ -1100,6 +1119,7 @@
|
|||||||
692AB9041E6759DD00706ACC /* VoIPServerConfig.cpp in Sources */,
|
692AB9041E6759DD00706ACC /* VoIPServerConfig.cpp in Sources */,
|
||||||
69A6DF0B1E96149300000E69 /* echo_cancellation.cc in Sources */,
|
69A6DF0B1E96149300000E69 /* echo_cancellation.cc in Sources */,
|
||||||
69A6DED61E96149300000E69 /* cross_correlation_neon.c in Sources */,
|
69A6DED61E96149300000E69 /* cross_correlation_neon.c in Sources */,
|
||||||
|
6976FD0320F6A7060019939E /* MessageThread.cpp in Sources */,
|
||||||
69A6DEF71E96149300000E69 /* spl_sqrt.c in Sources */,
|
69A6DEF71E96149300000E69 /* spl_sqrt.c in Sources */,
|
||||||
69A6DEED1E96149300000E69 /* real_fft.c in Sources */,
|
69A6DEED1E96149300000E69 /* real_fft.c in Sources */,
|
||||||
692AB9021E6759DD00706ACC /* VoIPController.cpp in Sources */,
|
692AB9021E6759DD00706ACC /* VoIPController.cpp in Sources */,
|
||||||
@ -1135,7 +1155,6 @@
|
|||||||
692AB8E61E6759DD00706ACC /* JitterBuffer.cpp in Sources */,
|
692AB8E61E6759DD00706ACC /* JitterBuffer.cpp in Sources */,
|
||||||
692AB8CB1E6759DD00706ACC /* AudioInput.cpp in Sources */,
|
692AB8CB1E6759DD00706ACC /* AudioInput.cpp in Sources */,
|
||||||
692AB8CD1E6759DD00706ACC /* AudioOutput.cpp in Sources */,
|
692AB8CD1E6759DD00706ACC /* AudioOutput.cpp in Sources */,
|
||||||
C2A87DDA1F4B6A57002D3F73 /* DarwinSpecific.mm in Sources */,
|
|
||||||
C2A87DD81F4B6A33002D3F73 /* Resampler.cpp in Sources */,
|
C2A87DD81F4B6A33002D3F73 /* Resampler.cpp in Sources */,
|
||||||
69A6DEFA1E96149300000E69 /* splitting_filter_impl.c in Sources */,
|
69A6DEFA1E96149300000E69 /* splitting_filter_impl.c in Sources */,
|
||||||
69A6DEE01E96149300000E69 /* get_hanning_window.c in Sources */,
|
69A6DEE01E96149300000E69 /* get_hanning_window.c in Sources */,
|
||||||
|
|||||||
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@ -64,8 +64,13 @@ void tgvoip_log_file_write_header(FILE* file){
|
|||||||
#else
|
#else
|
||||||
struct utsname sysname;
|
struct utsname sysname;
|
||||||
uname(&sysname);
|
uname(&sysname);
|
||||||
char systemVersion[128];
|
std::string sysver(sysname.sysname);
|
||||||
snprintf(systemVersion, sizeof(systemVersion), "%s %s (%s)", sysname.sysname, sysname.release, sysname.version);
|
sysver+=" ";
|
||||||
|
sysver+=sysname.release;
|
||||||
|
sysver+=" (";
|
||||||
|
sysver+=sysname.version;
|
||||||
|
sysver+=")";
|
||||||
|
const char* systemVersion=sysver.c_str();
|
||||||
#endif
|
#endif
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
char osxVer[128];
|
char osxVer[128];
|
||||||
|
|||||||
215
missing
Executable file
215
missing
Executable file
@ -0,0 +1,215 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# Common wrapper for a few potentially missing GNU programs.
|
||||||
|
|
||||||
|
scriptversion=2018-03-07.03; # UTC
|
||||||
|
|
||||||
|
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
|
||||||
|
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
if test $# -eq 0; then
|
||||||
|
echo 1>&2 "Try '$0 --help' for more information"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
|
||||||
|
--is-lightweight)
|
||||||
|
# Used by our autoconf macros to check whether the available missing
|
||||||
|
# script is modern enough.
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
--run)
|
||||||
|
# Back-compat with the calling convention used by older automake.
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
-h|--h|--he|--hel|--help)
|
||||||
|
echo "\
|
||||||
|
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||||
|
|
||||||
|
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
|
||||||
|
to PROGRAM being missing or too old.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help display this help and exit
|
||||||
|
-v, --version output version information and exit
|
||||||
|
|
||||||
|
Supported PROGRAM values:
|
||||||
|
aclocal autoconf autoheader autom4te automake makeinfo
|
||||||
|
bison yacc flex lex help2man
|
||||||
|
|
||||||
|
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
|
||||||
|
'g' are ignored when checking the name.
|
||||||
|
|
||||||
|
Send bug reports to <bug-automake@gnu.org>."
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
|
||||||
|
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||||
|
echo "missing $scriptversion (GNU Automake)"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
|
||||||
|
-*)
|
||||||
|
echo 1>&2 "$0: unknown '$1' option"
|
||||||
|
echo 1>&2 "Try '$0 --help' for more information"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Run the given program, remember its exit status.
|
||||||
|
"$@"; st=$?
|
||||||
|
|
||||||
|
# If it succeeded, we are done.
|
||||||
|
test $st -eq 0 && exit 0
|
||||||
|
|
||||||
|
# Also exit now if we it failed (or wasn't found), and '--version' was
|
||||||
|
# passed; such an option is passed most likely to detect whether the
|
||||||
|
# program is present and works.
|
||||||
|
case $2 in --version|--help) exit $st;; esac
|
||||||
|
|
||||||
|
# Exit code 63 means version mismatch. This often happens when the user
|
||||||
|
# tries to use an ancient version of a tool on a file that requires a
|
||||||
|
# minimum version.
|
||||||
|
if test $st -eq 63; then
|
||||||
|
msg="probably too old"
|
||||||
|
elif test $st -eq 127; then
|
||||||
|
# Program was missing.
|
||||||
|
msg="missing on your system"
|
||||||
|
else
|
||||||
|
# Program was found and executed, but failed. Give up.
|
||||||
|
exit $st
|
||||||
|
fi
|
||||||
|
|
||||||
|
perl_URL=https://www.perl.org/
|
||||||
|
flex_URL=https://github.com/westes/flex
|
||||||
|
gnu_software_URL=https://www.gnu.org/software
|
||||||
|
|
||||||
|
program_details ()
|
||||||
|
{
|
||||||
|
case $1 in
|
||||||
|
aclocal|automake)
|
||||||
|
echo "The '$1' program is part of the GNU Automake package:"
|
||||||
|
echo "<$gnu_software_URL/automake>"
|
||||||
|
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
|
||||||
|
echo "<$gnu_software_URL/autoconf>"
|
||||||
|
echo "<$gnu_software_URL/m4/>"
|
||||||
|
echo "<$perl_URL>"
|
||||||
|
;;
|
||||||
|
autoconf|autom4te|autoheader)
|
||||||
|
echo "The '$1' program is part of the GNU Autoconf package:"
|
||||||
|
echo "<$gnu_software_URL/autoconf/>"
|
||||||
|
echo "It also requires GNU m4 and Perl in order to run:"
|
||||||
|
echo "<$gnu_software_URL/m4/>"
|
||||||
|
echo "<$perl_URL>"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
give_advice ()
|
||||||
|
{
|
||||||
|
# Normalize program name to check for.
|
||||||
|
normalized_program=`echo "$1" | sed '
|
||||||
|
s/^gnu-//; t
|
||||||
|
s/^gnu//; t
|
||||||
|
s/^g//; t'`
|
||||||
|
|
||||||
|
printf '%s\n' "'$1' is $msg."
|
||||||
|
|
||||||
|
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
|
||||||
|
case $normalized_program in
|
||||||
|
autoconf*)
|
||||||
|
echo "You should only need it if you modified 'configure.ac',"
|
||||||
|
echo "or m4 files included by it."
|
||||||
|
program_details 'autoconf'
|
||||||
|
;;
|
||||||
|
autoheader*)
|
||||||
|
echo "You should only need it if you modified 'acconfig.h' or"
|
||||||
|
echo "$configure_deps."
|
||||||
|
program_details 'autoheader'
|
||||||
|
;;
|
||||||
|
automake*)
|
||||||
|
echo "You should only need it if you modified 'Makefile.am' or"
|
||||||
|
echo "$configure_deps."
|
||||||
|
program_details 'automake'
|
||||||
|
;;
|
||||||
|
aclocal*)
|
||||||
|
echo "You should only need it if you modified 'acinclude.m4' or"
|
||||||
|
echo "$configure_deps."
|
||||||
|
program_details 'aclocal'
|
||||||
|
;;
|
||||||
|
autom4te*)
|
||||||
|
echo "You might have modified some maintainer files that require"
|
||||||
|
echo "the 'autom4te' program to be rebuilt."
|
||||||
|
program_details 'autom4te'
|
||||||
|
;;
|
||||||
|
bison*|yacc*)
|
||||||
|
echo "You should only need it if you modified a '.y' file."
|
||||||
|
echo "You may want to install the GNU Bison package:"
|
||||||
|
echo "<$gnu_software_URL/bison/>"
|
||||||
|
;;
|
||||||
|
lex*|flex*)
|
||||||
|
echo "You should only need it if you modified a '.l' file."
|
||||||
|
echo "You may want to install the Fast Lexical Analyzer package:"
|
||||||
|
echo "<$flex_URL>"
|
||||||
|
;;
|
||||||
|
help2man*)
|
||||||
|
echo "You should only need it if you modified a dependency" \
|
||||||
|
"of a man page."
|
||||||
|
echo "You may want to install the GNU Help2man package:"
|
||||||
|
echo "<$gnu_software_URL/help2man/>"
|
||||||
|
;;
|
||||||
|
makeinfo*)
|
||||||
|
echo "You should only need it if you modified a '.texi' file, or"
|
||||||
|
echo "any other file indirectly affecting the aspect of the manual."
|
||||||
|
echo "You might want to install the Texinfo package:"
|
||||||
|
echo "<$gnu_software_URL/texinfo/>"
|
||||||
|
echo "The spurious makeinfo call might also be the consequence of"
|
||||||
|
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
|
||||||
|
echo "want to install GNU make:"
|
||||||
|
echo "<$gnu_software_URL/make/>"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "You might have modified some files without having the proper"
|
||||||
|
echo "tools for further handling them. Check the 'README' file, it"
|
||||||
|
echo "often tells you about the needed prerequisites for installing"
|
||||||
|
echo "this package. You may also peek at any GNU archive site, in"
|
||||||
|
echo "case some other package contains this missing '$1' program."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
||||||
|
-e '2,$s/^/ /' >&2
|
||||||
|
|
||||||
|
# Propagate the correct exit status (expected to be 127 for a program
|
||||||
|
# not found, 63 for a program that failed due to version mismatch).
|
||||||
|
exit $st
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC0"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
||||||
@ -32,6 +32,8 @@ AudioInputAndroid::AudioInputAndroid(){
|
|||||||
jobject obj=env->NewObject(jniClass, ctor, (jlong)(intptr_t)this);
|
jobject obj=env->NewObject(jniClass, ctor, (jlong)(intptr_t)this);
|
||||||
javaObject=env->NewGlobalRef(obj);
|
javaObject=env->NewGlobalRef(obj);
|
||||||
|
|
||||||
|
env->CallVoidMethod(javaObject, initMethod, 48000, 16, 1, 960*2);
|
||||||
|
|
||||||
if(didAttach){
|
if(didAttach){
|
||||||
sharedJVM->DetachCurrentThread();
|
sharedJVM->DetachCurrentThread();
|
||||||
}
|
}
|
||||||
@ -59,23 +61,6 @@ AudioInputAndroid::~AudioInputAndroid(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInputAndroid::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
MutexGuard guard(mutex);
|
|
||||||
JNIEnv* env=NULL;
|
|
||||||
bool didAttach=false;
|
|
||||||
sharedJVM->GetEnv((void**) &env, JNI_VERSION_1_6);
|
|
||||||
if(!env){
|
|
||||||
sharedJVM->AttachCurrentThread(&env, NULL);
|
|
||||||
didAttach=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->CallVoidMethod(javaObject, initMethod, sampleRate, bitsPerSample, channels, 960*2);
|
|
||||||
|
|
||||||
if(didAttach){
|
|
||||||
sharedJVM->DetachCurrentThread();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioInputAndroid::Start(){
|
void AudioInputAndroid::Start(){
|
||||||
MutexGuard guard(mutex);
|
MutexGuard guard(mutex);
|
||||||
JNIEnv* env=NULL;
|
JNIEnv* env=NULL;
|
||||||
|
|||||||
@ -17,7 +17,6 @@ class AudioInputAndroid : public AudioInput{
|
|||||||
public:
|
public:
|
||||||
AudioInputAndroid();
|
AudioInputAndroid();
|
||||||
virtual ~AudioInputAndroid();
|
virtual ~AudioInputAndroid();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
void HandleCallback(JNIEnv* env, jobject buffer);
|
void HandleCallback(JNIEnv* env, jobject buffer);
|
||||||
|
|||||||
@ -32,6 +32,8 @@ AudioOutputAndroid::AudioOutputAndroid(){
|
|||||||
jobject obj=env->NewObject(jniClass, ctor, (jlong)(intptr_t)this);
|
jobject obj=env->NewObject(jniClass, ctor, (jlong)(intptr_t)this);
|
||||||
javaObject=env->NewGlobalRef(obj);
|
javaObject=env->NewGlobalRef(obj);
|
||||||
|
|
||||||
|
env->CallVoidMethod(javaObject, initMethod, 48000, 16, 1, 960*2);
|
||||||
|
|
||||||
if(didAttach){
|
if(didAttach){
|
||||||
sharedJVM->DetachCurrentThread();
|
sharedJVM->DetachCurrentThread();
|
||||||
}
|
}
|
||||||
@ -56,22 +58,6 @@ AudioOutputAndroid::~AudioOutputAndroid(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutputAndroid::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
JNIEnv* env=NULL;
|
|
||||||
bool didAttach=false;
|
|
||||||
sharedJVM->GetEnv((void**) &env, JNI_VERSION_1_6);
|
|
||||||
if(!env){
|
|
||||||
sharedJVM->AttachCurrentThread(&env, NULL);
|
|
||||||
didAttach=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->CallVoidMethod(javaObject, initMethod, sampleRate, bitsPerSample, channels, 960*2);
|
|
||||||
|
|
||||||
if(didAttach){
|
|
||||||
sharedJVM->DetachCurrentThread();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioOutputAndroid::Start(){
|
void AudioOutputAndroid::Start(){
|
||||||
JNIEnv* env=NULL;
|
JNIEnv* env=NULL;
|
||||||
bool didAttach=false;
|
bool didAttach=false;
|
||||||
@ -119,7 +105,3 @@ void AudioOutputAndroid::HandleCallback(JNIEnv* env, jbyteArray buffer){
|
|||||||
bool AudioOutputAndroid::IsPlaying(){
|
bool AudioOutputAndroid::IsPlaying(){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float AudioOutputAndroid::GetLevel(){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -17,11 +17,9 @@ public:
|
|||||||
|
|
||||||
AudioOutputAndroid();
|
AudioOutputAndroid();
|
||||||
virtual ~AudioOutputAndroid();
|
virtual ~AudioOutputAndroid();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual bool IsPlaying() override;
|
virtual bool IsPlaying() override;
|
||||||
virtual float GetLevel() override;
|
|
||||||
void HandleCallback(JNIEnv* env, jbyteArray buffer);
|
void HandleCallback(JNIEnv* env, jbyteArray buffer);
|
||||||
static jmethodID initMethod;
|
static jmethodID initMethod;
|
||||||
static jmethodID releaseMethod;
|
static jmethodID releaseMethod;
|
||||||
|
|||||||
@ -23,22 +23,15 @@ AudioInputAudioUnit::AudioInputAudioUnit(std::string deviceID, AudioUnitIO* io){
|
|||||||
#if TARGET_OS_OSX
|
#if TARGET_OS_OSX
|
||||||
io->SetCurrentDevice(true, deviceID);
|
io->SetCurrentDevice(true, deviceID);
|
||||||
#endif
|
#endif
|
||||||
io->AttachInput(this);
|
|
||||||
failed=io->IsFailed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioInputAudioUnit::~AudioInputAudioUnit(){
|
AudioInputAudioUnit::~AudioInputAudioUnit(){
|
||||||
io->DetachInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioInputAudioUnit::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
io->Configure(sampleRate, bitsPerSample, channels);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInputAudioUnit::Start(){
|
void AudioInputAudioUnit::Start(){
|
||||||
isRecording=true;
|
isRecording=true;
|
||||||
io->EnableInput(true);
|
io->EnableInput(true);
|
||||||
failed=io->IsFailed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInputAudioUnit::Stop(){
|
void AudioInputAudioUnit::Stop(){
|
||||||
|
|||||||
@ -18,7 +18,6 @@ class AudioInputAudioUnit : public AudioInput{
|
|||||||
public:
|
public:
|
||||||
AudioInputAudioUnit(std::string deviceID, AudioUnitIO* io);
|
AudioInputAudioUnit(std::string deviceID, AudioUnitIO* io);
|
||||||
virtual ~AudioInputAudioUnit();
|
virtual ~AudioInputAudioUnit();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
void HandleBufferCallback(AudioBufferList* ioData);
|
void HandleBufferCallback(AudioBufferList* ioData);
|
||||||
|
|||||||
@ -78,9 +78,6 @@ AudioInputAudioUnitLegacy::~AudioInputAudioUnitLegacy(){
|
|||||||
free(inBufferList.mBuffers[0].mData);
|
free(inBufferList.mBuffers[0].mData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInputAudioUnitLegacy::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioInputAudioUnitLegacy::Start(){
|
void AudioInputAudioUnitLegacy::Start(){
|
||||||
isRecording=true;
|
isRecording=true;
|
||||||
OSStatus status=AudioOutputUnitStart(unit);
|
OSStatus status=AudioOutputUnitStart(unit);
|
||||||
@ -96,7 +93,7 @@ void AudioInputAudioUnitLegacy::Stop(){
|
|||||||
OSStatus AudioInputAudioUnitLegacy::BufferCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData){
|
OSStatus AudioInputAudioUnitLegacy::BufferCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData){
|
||||||
AudioInputAudioUnitLegacy* input=(AudioInputAudioUnitLegacy*) inRefCon;
|
AudioInputAudioUnitLegacy* input=(AudioInputAudioUnitLegacy*) inRefCon;
|
||||||
input->inBufferList.mBuffers[0].mDataByteSize=10240;
|
input->inBufferList.mBuffers[0].mDataByteSize=10240;
|
||||||
OSStatus res=AudioUnitRender(input->unit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &input->inBufferList);
|
AudioUnitRender(input->unit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &input->inBufferList);
|
||||||
input->HandleBufferCallback(&input->inBufferList);
|
input->HandleBufferCallback(&input->inBufferList);
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
@ -213,7 +210,7 @@ void AudioInputAudioUnitLegacy::EnumerateDevices(std::vector<AudioInputDevice>&
|
|||||||
|
|
||||||
void AudioInputAudioUnitLegacy::SetCurrentDevice(std::string deviceID){
|
void AudioInputAudioUnitLegacy::SetCurrentDevice(std::string deviceID){
|
||||||
UInt32 size=sizeof(AudioDeviceID);
|
UInt32 size=sizeof(AudioDeviceID);
|
||||||
AudioDeviceID inputDevice=NULL;
|
AudioDeviceID inputDevice=0;
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
|
|
||||||
if(deviceID=="default"){
|
if(deviceID=="default"){
|
||||||
|
|||||||
@ -18,7 +18,6 @@ class AudioInputAudioUnitLegacy : public AudioInput{
|
|||||||
public:
|
public:
|
||||||
AudioInputAudioUnitLegacy(std::string deviceID);
|
AudioInputAudioUnitLegacy(std::string deviceID);
|
||||||
virtual ~AudioInputAudioUnitLegacy();
|
virtual ~AudioInputAudioUnitLegacy();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
void HandleBufferCallback(AudioBufferList* ioData);
|
void HandleBufferCallback(AudioBufferList* ioData);
|
||||||
|
|||||||
@ -19,35 +19,18 @@ using namespace tgvoip::audio;
|
|||||||
AudioOutputAudioUnit::AudioOutputAudioUnit(std::string deviceID, AudioUnitIO* io){
|
AudioOutputAudioUnit::AudioOutputAudioUnit(std::string deviceID, AudioUnitIO* io){
|
||||||
isPlaying=false;
|
isPlaying=false;
|
||||||
remainingDataSize=0;
|
remainingDataSize=0;
|
||||||
level=0.0;
|
|
||||||
this->io=io;
|
this->io=io;
|
||||||
#if TARGET_OS_OSX
|
#if TARGET_OS_OSX
|
||||||
io->SetCurrentDevice(false, deviceID);
|
io->SetCurrentDevice(false, deviceID);
|
||||||
#endif
|
#endif
|
||||||
io->AttachOutput(this);
|
|
||||||
failed=io->IsFailed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioOutputAudioUnit::~AudioOutputAudioUnit(){
|
AudioOutputAudioUnit::~AudioOutputAudioUnit(){
|
||||||
io->DetachOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioOutputAudioUnit::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
io->Configure(sampleRate, bitsPerSample, channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioOutputAudioUnit::IsPhone(){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioOutputAudioUnit::EnableLoudspeaker(bool enabled){
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutputAudioUnit::Start(){
|
void AudioOutputAudioUnit::Start(){
|
||||||
isPlaying=true;
|
isPlaying=true;
|
||||||
io->EnableOutput(true);
|
io->EnableOutput(true);
|
||||||
failed=io->IsFailed();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutputAudioUnit::Stop(){
|
void AudioOutputAudioUnit::Stop(){
|
||||||
@ -59,10 +42,6 @@ bool AudioOutputAudioUnit::IsPlaying(){
|
|||||||
return isPlaying;
|
return isPlaying;
|
||||||
}
|
}
|
||||||
|
|
||||||
float AudioOutputAudioUnit::GetLevel(){
|
|
||||||
return level / 9.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioOutputAudioUnit::HandleBufferCallback(AudioBufferList *ioData){
|
void AudioOutputAudioUnit::HandleBufferCallback(AudioBufferList *ioData){
|
||||||
int i;
|
int i;
|
||||||
for(i=0;i<ioData->mNumberBuffers;i++){
|
for(i=0;i<ioData->mNumberBuffers;i++){
|
||||||
|
|||||||
@ -17,13 +17,9 @@ class AudioOutputAudioUnit : public AudioOutput{
|
|||||||
public:
|
public:
|
||||||
AudioOutputAudioUnit(std::string deviceID, AudioUnitIO* io);
|
AudioOutputAudioUnit(std::string deviceID, AudioUnitIO* io);
|
||||||
virtual ~AudioOutputAudioUnit();
|
virtual ~AudioOutputAudioUnit();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual bool IsPhone();
|
|
||||||
virtual void EnableLoudspeaker(bool enabled);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual bool IsPlaying();
|
virtual bool IsPlaying();
|
||||||
virtual float GetLevel();
|
|
||||||
void HandleBufferCallback(AudioBufferList* ioData);
|
void HandleBufferCallback(AudioBufferList* ioData);
|
||||||
#if TARGET_OS_OSX
|
#if TARGET_OS_OSX
|
||||||
virtual void SetCurrentDevice(std::string deviceID);
|
virtual void SetCurrentDevice(std::string deviceID);
|
||||||
@ -34,9 +30,6 @@ private:
|
|||||||
unsigned char remainingData[10240];
|
unsigned char remainingData[10240];
|
||||||
size_t remainingDataSize;
|
size_t remainingDataSize;
|
||||||
AudioUnitIO* io;
|
AudioUnitIO* io;
|
||||||
float level;
|
|
||||||
int16_t absMax;
|
|
||||||
int count;
|
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,7 @@ using namespace tgvoip::audio;
|
|||||||
AudioOutputAudioUnitLegacy::AudioOutputAudioUnitLegacy(std::string deviceID){
|
AudioOutputAudioUnitLegacy::AudioOutputAudioUnitLegacy(std::string deviceID){
|
||||||
remainingDataSize=0;
|
remainingDataSize=0;
|
||||||
isPlaying=false;
|
isPlaying=false;
|
||||||
sysDevID=NULL;
|
sysDevID=0;
|
||||||
|
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
AudioComponentDescription inputDesc={
|
AudioComponentDescription inputDesc={
|
||||||
@ -100,9 +100,6 @@ AudioOutputAudioUnitLegacy::~AudioOutputAudioUnitLegacy(){
|
|||||||
AudioComponentInstanceDispose(unit);
|
AudioComponentInstanceDispose(unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutputAudioUnitLegacy::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioOutputAudioUnitLegacy::Start(){
|
void AudioOutputAudioUnitLegacy::Start(){
|
||||||
isPlaying=true;
|
isPlaying=true;
|
||||||
OSStatus status=AudioOutputUnitStart(unit);
|
OSStatus status=AudioOutputUnitStart(unit);
|
||||||
@ -127,8 +124,6 @@ bool AudioOutputAudioUnitLegacy::IsPlaying(){
|
|||||||
|
|
||||||
void AudioOutputAudioUnitLegacy::HandleBufferCallback(AudioBufferList *ioData){
|
void AudioOutputAudioUnitLegacy::HandleBufferCallback(AudioBufferList *ioData){
|
||||||
int i;
|
int i;
|
||||||
unsigned int k;
|
|
||||||
int16_t absVal=0;
|
|
||||||
for(i=0;i<ioData->mNumberBuffers;i++){
|
for(i=0;i<ioData->mNumberBuffers;i++){
|
||||||
AudioBuffer buf=ioData->mBuffers[i];
|
AudioBuffer buf=ioData->mBuffers[i];
|
||||||
if(!isPlaying){
|
if(!isPlaying){
|
||||||
@ -236,7 +231,7 @@ void AudioOutputAudioUnitLegacy::EnumerateDevices(std::vector<AudioOutputDevice>
|
|||||||
|
|
||||||
void AudioOutputAudioUnitLegacy::SetCurrentDevice(std::string deviceID){
|
void AudioOutputAudioUnitLegacy::SetCurrentDevice(std::string deviceID){
|
||||||
UInt32 size=sizeof(AudioDeviceID);
|
UInt32 size=sizeof(AudioDeviceID);
|
||||||
AudioDeviceID outputDevice=NULL;
|
AudioDeviceID outputDevice=0;
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
AudioObjectPropertyAddress dataSourceProp={
|
AudioObjectPropertyAddress dataSourceProp={
|
||||||
kAudioDevicePropertyDataSource,
|
kAudioDevicePropertyDataSource,
|
||||||
|
|||||||
@ -4,8 +4,8 @@
|
|||||||
// you should have received with this source code distribution.
|
// you should have received with this source code distribution.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef LIBTGVOIP_AUDIOINPUTAUDIOUNIT_OSX_H
|
#ifndef LIBTGVOIP_AUDIOOUTPUTAUDIOUNIT_OSX_H
|
||||||
#define LIBTGVOIP_AUDIOINPUTAUDIOUNIT_OSX_H
|
#define LIBTGVOIP_AUDIOOUTPUTAUDIOUNIT_OSX_H
|
||||||
|
|
||||||
#include <AudioUnit/AudioUnit.h>
|
#include <AudioUnit/AudioUnit.h>
|
||||||
#import <AudioToolbox/AudioToolbox.h>
|
#import <AudioToolbox/AudioToolbox.h>
|
||||||
@ -18,7 +18,6 @@ class AudioOutputAudioUnitLegacy : public AudioOutput{
|
|||||||
public:
|
public:
|
||||||
AudioOutputAudioUnitLegacy(std::string deviceID);
|
AudioOutputAudioUnitLegacy(std::string deviceID);
|
||||||
virtual ~AudioOutputAudioUnitLegacy();
|
virtual ~AudioOutputAudioUnitLegacy();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual bool IsPlaying();
|
virtual bool IsPlaying();
|
||||||
@ -40,4 +39,4 @@ private:
|
|||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif //LIBTGVOIP_AUDIOINPUTAUDIOUNIT_OSX_H
|
#endif //LIBTGVOIP_AUDIOOUTPUTAUDIOUNIT_OSX_H
|
||||||
|
|||||||
@ -109,6 +109,10 @@ AudioUnitIO::AudioUnitIO(){
|
|||||||
propertyAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice;
|
propertyAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice;
|
||||||
AudioObjectAddPropertyListener(kAudioObjectSystemObject, &propertyAddress, AudioUnitIO::DefaultDeviceChangedCallback, this);
|
AudioObjectAddPropertyListener(kAudioObjectSystemObject, &propertyAddress, AudioUnitIO::DefaultDeviceChangedCallback, this);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
input=new AudioInputAudioUnit("default", this);
|
||||||
|
output=new AudioOutputAudioUnit("default", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioUnitIO::~AudioUnitIO(){
|
AudioUnitIO::~AudioUnitIO(){
|
||||||
@ -121,16 +125,14 @@ AudioUnitIO::~AudioUnitIO(){
|
|||||||
propertyAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice;
|
propertyAddress.mSelector = kAudioHardwarePropertyDefaultInputDevice;
|
||||||
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &propertyAddress, AudioUnitIO::DefaultDeviceChangedCallback, this);
|
AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &propertyAddress, AudioUnitIO::DefaultDeviceChangedCallback, this);
|
||||||
#endif
|
#endif
|
||||||
|
delete input;
|
||||||
|
delete output;
|
||||||
AudioOutputUnitStop(unit);
|
AudioOutputUnitStop(unit);
|
||||||
AudioUnitUninitialize(unit);
|
AudioUnitUninitialize(unit);
|
||||||
AudioComponentInstanceDispose(unit);
|
AudioComponentInstanceDispose(unit);
|
||||||
free(inBufferList.mBuffers[0].mData);
|
free(inBufferList.mBuffers[0].mData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioUnitIO::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
OSStatus AudioUnitIO::BufferCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData){
|
OSStatus AudioUnitIO::BufferCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData){
|
||||||
((AudioUnitIO*)inRefCon)->BufferCallback(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData);
|
((AudioUnitIO*)inRefCon)->BufferCallback(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData);
|
||||||
return noErr;
|
return noErr;
|
||||||
@ -152,28 +154,6 @@ void AudioUnitIO::BufferCallback(AudioUnitRenderActionFlags *ioActionFlags, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioUnitIO::AttachInput(AudioInputAudioUnit *i){
|
|
||||||
assert(input==NULL);
|
|
||||||
input=i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioUnitIO::AttachOutput(AudioOutputAudioUnit *o){
|
|
||||||
assert(output==NULL);
|
|
||||||
output=o;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioUnitIO::DetachInput(){
|
|
||||||
assert(input!=NULL);
|
|
||||||
input=NULL;
|
|
||||||
inputEnabled=false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioUnitIO::DetachOutput(){
|
|
||||||
assert(output!=NULL);
|
|
||||||
output=NULL;
|
|
||||||
outputEnabled=false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioUnitIO::EnableInput(bool enabled){
|
void AudioUnitIO::EnableInput(bool enabled){
|
||||||
inputEnabled=enabled;
|
inputEnabled=enabled;
|
||||||
StartIfNeeded();
|
StartIfNeeded();
|
||||||
@ -194,8 +174,12 @@ void AudioUnitIO::StartIfNeeded(){
|
|||||||
CHECK_AU_ERROR(status, "Error starting AudioUnit");
|
CHECK_AU_ERROR(status, "Error starting AudioUnit");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioUnitIO::IsFailed(){
|
AudioInput* AudioUnitIO::GetInput(){
|
||||||
return failed;
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioOutput* AudioUnitIO::GetOutput(){
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TARGET_OS_OSX
|
#if TARGET_OS_OSX
|
||||||
@ -221,7 +205,7 @@ void AudioUnitIO::SetCurrentDevice(bool input, std::string deviceID){
|
|||||||
AudioUnitUninitialize(unit);
|
AudioUnitUninitialize(unit);
|
||||||
}
|
}
|
||||||
UInt32 size=sizeof(AudioDeviceID);
|
UInt32 size=sizeof(AudioDeviceID);
|
||||||
AudioDeviceID device=NULL;
|
AudioDeviceID device=0;
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
|
|
||||||
if(deviceID=="default"){
|
if(deviceID=="default"){
|
||||||
|
|||||||
@ -11,28 +11,25 @@
|
|||||||
#include <AudioToolbox/AudioToolbox.h>
|
#include <AudioToolbox/AudioToolbox.h>
|
||||||
#include "../../threading.h"
|
#include "../../threading.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "../../audio/AudioIO.h"
|
||||||
|
|
||||||
namespace tgvoip{ namespace audio{
|
namespace tgvoip{ namespace audio{
|
||||||
class AudioInputAudioUnit;
|
class AudioInputAudioUnit;
|
||||||
class AudioOutputAudioUnit;
|
class AudioOutputAudioUnit;
|
||||||
|
|
||||||
class AudioUnitIO{
|
class AudioUnitIO : public AudioIO{
|
||||||
public:
|
public:
|
||||||
AudioUnitIO();
|
AudioUnitIO();
|
||||||
~AudioUnitIO();
|
~AudioUnitIO();
|
||||||
void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
void AttachInput(AudioInputAudioUnit* i);
|
|
||||||
void AttachOutput(AudioOutputAudioUnit* o);
|
|
||||||
void DetachInput();
|
|
||||||
void DetachOutput();
|
|
||||||
void EnableInput(bool enabled);
|
void EnableInput(bool enabled);
|
||||||
void EnableOutput(bool enabled);
|
void EnableOutput(bool enabled);
|
||||||
bool IsFailed();
|
virtual AudioInput* GetInput();
|
||||||
|
virtual AudioOutput* GetOutput();
|
||||||
#if TARGET_OS_OSX
|
#if TARGET_OS_OSX
|
||||||
void SetCurrentDevice(bool input, std::string deviceID);
|
void SetCurrentDevice(bool input, std::string deviceID);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static OSStatus BufferCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
|
static OSStatus BufferCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData);
|
||||||
void BufferCallback(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 bus, UInt32 numFrames, AudioBufferList* ioData);
|
void BufferCallback(AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 bus, UInt32 numFrames, AudioBufferList* ioData);
|
||||||
void StartIfNeeded();
|
void StartIfNeeded();
|
||||||
@ -47,9 +44,8 @@ private:
|
|||||||
AudioBufferList inBufferList;
|
AudioBufferList inBufferList;
|
||||||
bool inputEnabled;
|
bool inputEnabled;
|
||||||
bool outputEnabled;
|
bool outputEnabled;
|
||||||
bool failed;
|
|
||||||
bool started;
|
bool started;
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#endif /* LIBTGVOIP_AUDIOUNITIO_H */
|
#endif /* LIBTGVOIP_AUDIOUNITIO_H */
|
||||||
|
|||||||
@ -12,7 +12,15 @@
|
|||||||
namespace tgvoip {
|
namespace tgvoip {
|
||||||
class DarwinSpecific{
|
class DarwinSpecific{
|
||||||
public:
|
public:
|
||||||
|
enum{
|
||||||
|
THREAD_PRIO_USER_INTERACTIVE,
|
||||||
|
THREAD_PRIO_USER_INITIATED,
|
||||||
|
THREAD_PRIO_UTILITY,
|
||||||
|
THREAD_PRIO_BACKGROUND,
|
||||||
|
THREAD_PRIO_DEFAULT
|
||||||
|
};
|
||||||
static void GetSystemName(char* buf, size_t len);
|
static void GetSystemName(char* buf, size_t len);
|
||||||
|
static void SetCurrentThreadPriority(int priority);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,3 +15,50 @@ void DarwinSpecific::GetSystemName(char* buf, size_t len){
|
|||||||
strcpy(buf, [v UTF8String]);
|
strcpy(buf, [v UTF8String]);
|
||||||
//[v getCString:buf maxLength:sizeof(buf) encoding:NSUTF8StringEncoding];
|
//[v getCString:buf maxLength:sizeof(buf) encoding:NSUTF8StringEncoding];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DarwinSpecific::SetCurrentThreadPriority(int priority){
|
||||||
|
NSThread* thread=[NSThread currentThread];
|
||||||
|
if([thread respondsToSelector:@selector(setQualityOfService:)]){
|
||||||
|
NSQualityOfService qos;
|
||||||
|
switch(priority){
|
||||||
|
case THREAD_PRIO_USER_INTERACTIVE:
|
||||||
|
qos=NSQualityOfServiceUserInteractive;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIO_USER_INITIATED:
|
||||||
|
qos=NSQualityOfServiceUserInitiated;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIO_UTILITY:
|
||||||
|
qos=NSQualityOfServiceUtility;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIO_BACKGROUND:
|
||||||
|
qos=NSQualityOfServiceBackground;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIO_DEFAULT:
|
||||||
|
default:
|
||||||
|
qos=NSQualityOfServiceDefault;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
[thread setQualityOfService:qos];
|
||||||
|
}else{
|
||||||
|
double p;
|
||||||
|
switch(priority){
|
||||||
|
case THREAD_PRIO_USER_INTERACTIVE:
|
||||||
|
p=1.0;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIO_USER_INITIATED:
|
||||||
|
p=0.8;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIO_UTILITY:
|
||||||
|
p=0.4;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIO_BACKGROUND:
|
||||||
|
p=0.2;
|
||||||
|
break;
|
||||||
|
case THREAD_PRIO_DEFAULT:
|
||||||
|
default:
|
||||||
|
p=0.5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
[NSThread setThreadPriority:p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -49,10 +49,6 @@ AudioInputALSA::~AudioInputALSA(){
|
|||||||
dlclose(lib);
|
dlclose(lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInputALSA::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioInputALSA::Start(){
|
void AudioInputALSA::Start(){
|
||||||
if(failed || isRecording)
|
if(failed || isRecording)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -19,7 +19,6 @@ class AudioInputALSA : public AudioInput{
|
|||||||
public:
|
public:
|
||||||
AudioInputALSA(std::string devID);
|
AudioInputALSA(std::string devID);
|
||||||
virtual ~AudioInputALSA();
|
virtual ~AudioInputALSA();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual void SetCurrentDevice(std::string devID);
|
virtual void SetCurrentDevice(std::string devID);
|
||||||
|
|||||||
@ -11,9 +11,8 @@
|
|||||||
#include "AudioInputPulse.h"
|
#include "AudioInputPulse.h"
|
||||||
#include "../../logging.h"
|
#include "../../logging.h"
|
||||||
#include "../../VoIPController.h"
|
#include "../../VoIPController.h"
|
||||||
#define TGVOIP_IN_AUDIO_IO
|
#include "AudioPulse.h"
|
||||||
#include "PulseAudioLoader.h"
|
#include "PulseFunctions.h"
|
||||||
#undef TGVOIP_IN_AUDIO_IO
|
|
||||||
#if !defined(__GLIBC__)
|
#if !defined(__GLIBC__)
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#endif
|
#endif
|
||||||
@ -23,74 +22,17 @@
|
|||||||
|
|
||||||
using namespace tgvoip::audio;
|
using namespace tgvoip::audio;
|
||||||
|
|
||||||
AudioInputPulse::AudioInputPulse(std::string devID){
|
AudioInputPulse::AudioInputPulse(pa_context* context, pa_threaded_mainloop* mainloop, std::string devID){
|
||||||
isRecording=false;
|
isRecording=false;
|
||||||
isConnected=false;
|
isConnected=false;
|
||||||
didStart=false;
|
didStart=false;
|
||||||
|
|
||||||
mainloop=NULL;
|
this->mainloop=mainloop;
|
||||||
mainloopApi=NULL;
|
this->context=context;
|
||||||
context=NULL;
|
|
||||||
stream=NULL;
|
stream=NULL;
|
||||||
remainingDataSize=0;
|
remainingDataSize=0;
|
||||||
|
|
||||||
if(!PulseAudioLoader::IncRef()){
|
|
||||||
failed=true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mainloop=pa_threaded_mainloop_new();
|
|
||||||
if(!mainloop){
|
|
||||||
LOGE("Error initializing PulseAudio (pa_threaded_mainloop_new)");
|
|
||||||
failed=true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mainloopApi=pa_threaded_mainloop_get_api(mainloop);
|
|
||||||
#ifndef MAXPATHLEN
|
|
||||||
char exeName[20];
|
|
||||||
#else
|
|
||||||
char exePath[MAXPATHLEN];
|
|
||||||
char exeName[MAXPATHLEN];
|
|
||||||
ssize_t lres=readlink("/proc/self/exe", exePath, sizeof(exePath));
|
|
||||||
if(lres==-1)
|
|
||||||
lres=readlink("/proc/curproc/file", exePath, sizeof(exePath));
|
|
||||||
if(lres==-1)
|
|
||||||
lres=readlink("/proc/curproc/exe", exePath, sizeof(exePath));
|
|
||||||
if(lres>0){
|
|
||||||
strcpy(exeName, basename(exePath));
|
|
||||||
}else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
snprintf(exeName, sizeof(exeName), "Process %d", getpid());
|
|
||||||
}
|
|
||||||
context=pa_context_new(mainloopApi, exeName);
|
|
||||||
if(!context){
|
|
||||||
LOGE("Error initializing PulseAudio (pa_context_new)");
|
|
||||||
failed=true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pa_context_set_state_callback(context, AudioInputPulse::ContextStateCallback, this);
|
|
||||||
isLocked=true;
|
|
||||||
pa_threaded_mainloop_lock(mainloop);
|
pa_threaded_mainloop_lock(mainloop);
|
||||||
int err=pa_threaded_mainloop_start(mainloop);
|
|
||||||
CHECK_ERROR(err, "pa_threaded_mainloop_start");
|
|
||||||
didStart=true;
|
|
||||||
|
|
||||||
err=pa_context_connect(context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL);
|
|
||||||
CHECK_ERROR(err, "pa_context_connect");
|
|
||||||
|
|
||||||
while(true){
|
|
||||||
pa_context_state_t contextState=pa_context_get_state(context);
|
|
||||||
if(!PA_CONTEXT_IS_GOOD(contextState)){
|
|
||||||
LOGE("Error initializing PulseAudio (PA_CONTEXT_IS_GOOD)");
|
|
||||||
failed=true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(contextState==PA_CONTEXT_READY)
|
|
||||||
break;
|
|
||||||
pa_threaded_mainloop_wait(mainloop);
|
|
||||||
}
|
|
||||||
|
|
||||||
pa_sample_spec sample_specifications{
|
pa_sample_spec sample_specifications{
|
||||||
.format=PA_SAMPLE_S16LE,
|
.format=PA_SAMPLE_S16LE,
|
||||||
.rate=48000,
|
.rate=48000,
|
||||||
@ -112,38 +54,10 @@ AudioInputPulse::AudioInputPulse(std::string devID){
|
|||||||
}
|
}
|
||||||
|
|
||||||
AudioInputPulse::~AudioInputPulse(){
|
AudioInputPulse::~AudioInputPulse(){
|
||||||
if(mainloop && didStart){
|
|
||||||
if(isLocked)
|
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
|
||||||
pa_threaded_mainloop_stop(mainloop);
|
|
||||||
}
|
|
||||||
if(stream){
|
if(stream){
|
||||||
pa_stream_disconnect(stream);
|
pa_stream_disconnect(stream);
|
||||||
pa_stream_unref(stream);
|
pa_stream_unref(stream);
|
||||||
}
|
}
|
||||||
if(context){
|
|
||||||
pa_context_disconnect(context);
|
|
||||||
pa_context_unref(context);
|
|
||||||
}
|
|
||||||
if(mainloop)
|
|
||||||
pa_threaded_mainloop_free(mainloop);
|
|
||||||
|
|
||||||
PulseAudioLoader::DecRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioInputPulse::IsAvailable(){
|
|
||||||
void* lib=dlopen("libpulse.so.0", RTLD_LAZY);
|
|
||||||
if(!lib)
|
|
||||||
lib=dlopen("libpulse.so", RTLD_LAZY);
|
|
||||||
if(lib){
|
|
||||||
dlclose(lib);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioInputPulse::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInputPulse::Start(){
|
void AudioInputPulse::Start(){
|
||||||
@ -152,7 +66,7 @@ void AudioInputPulse::Start(){
|
|||||||
|
|
||||||
pa_threaded_mainloop_lock(mainloop);
|
pa_threaded_mainloop_lock(mainloop);
|
||||||
isRecording=true;
|
isRecording=true;
|
||||||
pa_operation_unref(pa_stream_cork(stream, 0, AudioInputPulse::StreamSuccessCallback, NULL));
|
pa_operation_unref(pa_stream_cork(stream, 0, NULL, NULL));
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +76,7 @@ void AudioInputPulse::Stop(){
|
|||||||
|
|
||||||
isRecording=false;
|
isRecording=false;
|
||||||
pa_threaded_mainloop_lock(mainloop);
|
pa_threaded_mainloop_lock(mainloop);
|
||||||
pa_operation_unref(pa_stream_cork(stream, 1, AudioInputPulse::StreamSuccessCallback, NULL));
|
pa_operation_unref(pa_stream_cork(stream, 1, NULL, NULL));
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,60 +123,23 @@ void AudioInputPulse::SetCurrentDevice(std::string devID){
|
|||||||
isConnected=true;
|
isConnected=true;
|
||||||
|
|
||||||
if(isRecording){
|
if(isRecording){
|
||||||
pa_operation_unref(pa_stream_cork(stream, 0, AudioInputPulse::StreamSuccessCallback, mainloop));
|
pa_operation_unref(pa_stream_cork(stream, 0, NULL, NULL));
|
||||||
}
|
}
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioInputPulse::EnumerateDevices(std::vector<AudioInputDevice>& devs){
|
bool AudioInputPulse::EnumerateDevices(std::vector<AudioInputDevice>& devs){
|
||||||
if(!PulseAudioLoader::IncRef())
|
return AudioPulse::DoOneOperation([&](pa_context* ctx){
|
||||||
return false;
|
return pa_context_get_source_info_list(ctx, [](pa_context* ctx, const pa_source_info* info, int eol, void* userdata){
|
||||||
|
if(eol>0)
|
||||||
pa_mainloop* ml;
|
return;
|
||||||
pa_mainloop_api* mlAPI;
|
std::vector<AudioInputDevice>* devs=(std::vector<AudioInputDevice>*)userdata;
|
||||||
pa_context* ctx;
|
AudioInputDevice dev;
|
||||||
pa_operation* op=NULL;
|
dev.id=std::string(info->name);
|
||||||
int state=0;
|
dev.displayName=std::string(info->description);
|
||||||
int paReady=0;
|
devs->push_back(dev);
|
||||||
|
}, &devs);
|
||||||
ml=pa_mainloop_new();
|
});
|
||||||
mlAPI=pa_mainloop_get_api(ml);
|
|
||||||
ctx=pa_context_new(mlAPI, "libtgvoip");
|
|
||||||
|
|
||||||
pa_context_connect(ctx, NULL, PA_CONTEXT_NOFLAGS, NULL);
|
|
||||||
pa_context_set_state_callback(ctx, AudioInputPulse::ContextStateCallbackEnum, &paReady);
|
|
||||||
|
|
||||||
while(true){
|
|
||||||
if(paReady==0){
|
|
||||||
pa_mainloop_iterate(ml, 1, NULL);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(paReady==2){
|
|
||||||
pa_context_disconnect(ctx);
|
|
||||||
pa_context_unref(ctx);
|
|
||||||
pa_mainloop_free(ml);
|
|
||||||
PulseAudioLoader::DecRef();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!op){
|
|
||||||
op=pa_context_get_source_info_list(ctx, AudioInputPulse::DeviceEnumCallback, &devs);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(pa_operation_get_state(op)==PA_OPERATION_DONE){
|
|
||||||
pa_operation_unref(op);
|
|
||||||
pa_context_disconnect(ctx);
|
|
||||||
pa_context_unref(ctx);
|
|
||||||
pa_mainloop_free(ml);
|
|
||||||
PulseAudioLoader::DecRef();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
pa_mainloop_iterate(ml, 1, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioInputPulse::ContextStateCallback(pa_context* context, void* arg) {
|
|
||||||
AudioInputPulse* self=(AudioInputPulse*) arg;
|
|
||||||
pa_threaded_mainloop_signal(self->mainloop, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInputPulse::StreamStateCallback(pa_stream *s, void* arg) {
|
void AudioInputPulse::StreamStateCallback(pa_stream *s, void* arg) {
|
||||||
@ -275,11 +152,10 @@ void AudioInputPulse::StreamReadCallback(pa_stream *stream, size_t requestedByte
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AudioInputPulse::StreamReadCallback(pa_stream *stream, size_t requestedBytes) {
|
void AudioInputPulse::StreamReadCallback(pa_stream *stream, size_t requestedBytes) {
|
||||||
int bytesRemaining = requestedBytes;
|
size_t bytesRemaining = requestedBytes;
|
||||||
uint8_t *buffer = NULL;
|
uint8_t *buffer = NULL;
|
||||||
while (bytesRemaining > 0) {
|
while (bytesRemaining > 0) {
|
||||||
size_t bytesToFill = 102400;
|
size_t bytesToFill = 102400;
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (bytesToFill > bytesRemaining) bytesToFill = bytesRemaining;
|
if (bytesToFill > bytesRemaining) bytesToFill = bytesRemaining;
|
||||||
|
|
||||||
@ -305,39 +181,3 @@ void AudioInputPulse::StreamReadCallback(pa_stream *stream, size_t requestedByte
|
|||||||
bytesRemaining -= bytesToFill;
|
bytesRemaining -= bytesToFill;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInputPulse::StreamSuccessCallback(pa_stream *stream, int success, void *userdata) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioInputPulse::ContextStateCallbackEnum(pa_context* context, void* arg){
|
|
||||||
pa_context_state_t state;
|
|
||||||
int* pa_ready=(int*)arg;
|
|
||||||
|
|
||||||
state=pa_context_get_state(context);
|
|
||||||
switch(state){
|
|
||||||
case PA_CONTEXT_UNCONNECTED:
|
|
||||||
case PA_CONTEXT_CONNECTING:
|
|
||||||
case PA_CONTEXT_AUTHORIZING:
|
|
||||||
case PA_CONTEXT_SETTING_NAME:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
case PA_CONTEXT_FAILED:
|
|
||||||
case PA_CONTEXT_TERMINATED:
|
|
||||||
*pa_ready=2;
|
|
||||||
break;
|
|
||||||
case PA_CONTEXT_READY:
|
|
||||||
*pa_ready=1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioInputPulse::DeviceEnumCallback(pa_context* ctx, const pa_source_info* info, int eol, void* userdata){
|
|
||||||
if(eol>0)
|
|
||||||
return;
|
|
||||||
std::vector<AudioInputDevice>* devs=(std::vector<AudioInputDevice>*)userdata;
|
|
||||||
AudioInputDevice dev;
|
|
||||||
dev.id=std::string(info->name);
|
|
||||||
dev.displayName=std::string(info->description);
|
|
||||||
devs->push_back(dev);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -18,27 +18,20 @@ namespace audio{
|
|||||||
|
|
||||||
class AudioInputPulse : public AudioInput{
|
class AudioInputPulse : public AudioInput{
|
||||||
public:
|
public:
|
||||||
AudioInputPulse(std::string devID);
|
AudioInputPulse(pa_context* context, pa_threaded_mainloop* mainloop, std::string devID);
|
||||||
virtual ~AudioInputPulse();
|
virtual ~AudioInputPulse();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual bool IsRecording();
|
virtual bool IsRecording();
|
||||||
virtual void SetCurrentDevice(std::string devID);
|
virtual void SetCurrentDevice(std::string devID);
|
||||||
static bool EnumerateDevices(std::vector<AudioInputDevice>& devs);
|
static bool EnumerateDevices(std::vector<AudioInputDevice>& devs);
|
||||||
static bool IsAvailable();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void ContextStateCallback(pa_context* context, void* arg);
|
|
||||||
static void ContextStateCallbackEnum(pa_context* context, void* arg);
|
|
||||||
static void StreamStateCallback(pa_stream* s, void* arg);
|
static void StreamStateCallback(pa_stream* s, void* arg);
|
||||||
static void StreamSuccessCallback(pa_stream* stream, int success, void* userdata);
|
|
||||||
static void StreamReadCallback(pa_stream* stream, size_t requested_bytes, void* userdata);
|
static void StreamReadCallback(pa_stream* stream, size_t requested_bytes, void* userdata);
|
||||||
static void DeviceEnumCallback(pa_context* ctx, const pa_source_info* info, int eol, void* userdata);
|
|
||||||
void StreamReadCallback(pa_stream* stream, size_t requestedBytes);
|
void StreamReadCallback(pa_stream* stream, size_t requestedBytes);
|
||||||
|
|
||||||
pa_threaded_mainloop* mainloop;
|
pa_threaded_mainloop* mainloop;
|
||||||
pa_mainloop_api* mainloopApi;
|
|
||||||
pa_context* context;
|
pa_context* context;
|
||||||
pa_stream* stream;
|
pa_stream* stream;
|
||||||
|
|
||||||
|
|||||||
@ -48,10 +48,6 @@ AudioOutputALSA::~AudioOutputALSA(){
|
|||||||
dlclose(lib);
|
dlclose(lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutputALSA::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioOutputALSA::Start(){
|
void AudioOutputALSA::Start(){
|
||||||
if(failed || isPlaying)
|
if(failed || isPlaying)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -18,7 +18,6 @@ class AudioOutputALSA : public AudioOutput{
|
|||||||
public:
|
public:
|
||||||
AudioOutputALSA(std::string devID);
|
AudioOutputALSA(std::string devID);
|
||||||
virtual ~AudioOutputALSA();
|
virtual ~AudioOutputALSA();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual bool IsPlaying();
|
virtual bool IsPlaying();
|
||||||
|
|||||||
@ -11,9 +11,8 @@
|
|||||||
#include "AudioOutputPulse.h"
|
#include "AudioOutputPulse.h"
|
||||||
#include "../../logging.h"
|
#include "../../logging.h"
|
||||||
#include "../../VoIPController.h"
|
#include "../../VoIPController.h"
|
||||||
#define TGVOIP_IN_AUDIO_IO
|
#include "AudioPulse.h"
|
||||||
#include "PulseAudioLoader.h"
|
#include "PulseFunctions.h"
|
||||||
#undef TGVOIP_IN_AUDIO_IO
|
|
||||||
#if !defined(__GLIBC__)
|
#if !defined(__GLIBC__)
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#endif
|
#endif
|
||||||
@ -24,130 +23,43 @@
|
|||||||
using namespace tgvoip;
|
using namespace tgvoip;
|
||||||
using namespace tgvoip::audio;
|
using namespace tgvoip::audio;
|
||||||
|
|
||||||
using tgvoip::PulseAudioLoader;
|
AudioOutputPulse::AudioOutputPulse(pa_context* context, pa_threaded_mainloop* mainloop, std::string devID){
|
||||||
|
|
||||||
AudioOutputPulse::AudioOutputPulse(std::string devID){
|
|
||||||
isPlaying=false;
|
isPlaying=false;
|
||||||
isConnected=false;
|
isConnected=false;
|
||||||
didStart=false;
|
didStart=false;
|
||||||
isLocked=false;
|
isLocked=false;
|
||||||
|
|
||||||
mainloop=NULL;
|
this->mainloop=mainloop;
|
||||||
mainloopApi=NULL;
|
this->context=context;
|
||||||
context=NULL;
|
|
||||||
stream=NULL;
|
stream=NULL;
|
||||||
remainingDataSize=0;
|
remainingDataSize=0;
|
||||||
|
|
||||||
if(!PulseAudioLoader::IncRef()){
|
|
||||||
failed=true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mainloop=pa_threaded_mainloop_new();
|
|
||||||
if(!mainloop){
|
|
||||||
LOGE("Error initializing PulseAudio (pa_threaded_mainloop_new)");
|
|
||||||
failed=true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mainloopApi=pa_threaded_mainloop_get_api(mainloop);
|
|
||||||
#ifndef MAXPATHLEN
|
|
||||||
char exeName[20];
|
|
||||||
#else
|
|
||||||
char exePath[MAXPATHLEN];
|
|
||||||
char exeName[MAXPATHLEN];
|
|
||||||
ssize_t lres=readlink("/proc/self/exe", exePath, sizeof(exePath));
|
|
||||||
if(lres==-1)
|
|
||||||
lres=readlink("/proc/curproc/file", exePath, sizeof(exePath));
|
|
||||||
if(lres==-1)
|
|
||||||
lres=readlink("/proc/curproc/exe", exePath, sizeof(exePath));
|
|
||||||
if(lres>0){
|
|
||||||
strcpy(exeName, basename(exePath));
|
|
||||||
}else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
snprintf(exeName, sizeof(exeName), "Process %d", getpid());
|
|
||||||
}
|
|
||||||
context=pa_context_new(mainloopApi, exeName);
|
|
||||||
if(!context){
|
|
||||||
LOGE("Error initializing PulseAudio (pa_context_new)");
|
|
||||||
failed=true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pa_context_set_state_callback(context, AudioOutputPulse::ContextStateCallback, this);
|
|
||||||
pa_threaded_mainloop_lock(mainloop);
|
|
||||||
isLocked=true;
|
|
||||||
int err=pa_threaded_mainloop_start(mainloop);
|
|
||||||
CHECK_ERROR(err, "pa_threaded_mainloop_start");
|
|
||||||
didStart=true;
|
|
||||||
|
|
||||||
err=pa_context_connect(context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL);
|
|
||||||
CHECK_ERROR(err, "pa_context_connect");
|
|
||||||
|
|
||||||
while(true){
|
|
||||||
pa_context_state_t contextState=pa_context_get_state(context);
|
|
||||||
if(!PA_CONTEXT_IS_GOOD(contextState)){
|
|
||||||
LOGE("Error initializing PulseAudio (PA_CONTEXT_IS_GOOD)");
|
|
||||||
failed=true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(contextState==PA_CONTEXT_READY)
|
|
||||||
break;
|
|
||||||
pa_threaded_mainloop_wait(mainloop);
|
|
||||||
}
|
|
||||||
|
|
||||||
pa_sample_spec sample_specifications{
|
pa_sample_spec sample_specifications{
|
||||||
.format=PA_SAMPLE_S16LE,
|
.format=PA_SAMPLE_S16LE,
|
||||||
.rate=48000,
|
.rate=48000,
|
||||||
.channels=1
|
.channels=1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pa_threaded_mainloop_lock(mainloop);
|
||||||
stream=pa_stream_new(context, "libtgvoip playback", &sample_specifications, NULL);
|
stream=pa_stream_new(context, "libtgvoip playback", &sample_specifications, NULL);
|
||||||
if(!stream){
|
if(!stream){
|
||||||
LOGE("Error initializing PulseAudio (pa_stream_new)");
|
LOGE("Error initializing PulseAudio (pa_stream_new)");
|
||||||
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
failed=true;
|
failed=true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pa_stream_set_state_callback(stream, AudioOutputPulse::StreamStateCallback, this);
|
pa_stream_set_state_callback(stream, AudioOutputPulse::StreamStateCallback, this);
|
||||||
pa_stream_set_write_callback(stream, AudioOutputPulse::StreamWriteCallback, this);
|
pa_stream_set_write_callback(stream, AudioOutputPulse::StreamWriteCallback, this);
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
isLocked=false;
|
|
||||||
|
|
||||||
SetCurrentDevice(devID);
|
SetCurrentDevice(devID);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioOutputPulse::~AudioOutputPulse(){
|
AudioOutputPulse::~AudioOutputPulse(){
|
||||||
if(mainloop && didStart){
|
|
||||||
if(isLocked)
|
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
|
||||||
pa_threaded_mainloop_stop(mainloop);
|
|
||||||
}
|
|
||||||
if(stream){
|
if(stream){
|
||||||
pa_stream_disconnect(stream);
|
pa_stream_disconnect(stream);
|
||||||
pa_stream_unref(stream);
|
pa_stream_unref(stream);
|
||||||
}
|
}
|
||||||
if(context){
|
|
||||||
pa_context_disconnect(context);
|
|
||||||
pa_context_unref(context);
|
|
||||||
}
|
|
||||||
if(mainloop)
|
|
||||||
pa_threaded_mainloop_free(mainloop);
|
|
||||||
|
|
||||||
PulseAudioLoader::DecRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioOutputPulse::IsAvailable(){
|
|
||||||
void* lib=dlopen("libpulse.so.0", RTLD_LAZY);
|
|
||||||
if(!lib)
|
|
||||||
lib=dlopen("libpulse.so", RTLD_LAZY);
|
|
||||||
if(lib){
|
|
||||||
dlclose(lib);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioOutputPulse::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutputPulse::Start(){
|
void AudioOutputPulse::Start(){
|
||||||
@ -156,7 +68,7 @@ void AudioOutputPulse::Start(){
|
|||||||
|
|
||||||
isPlaying=true;
|
isPlaying=true;
|
||||||
pa_threaded_mainloop_lock(mainloop);
|
pa_threaded_mainloop_lock(mainloop);
|
||||||
pa_operation_unref(pa_stream_cork(stream, 0, AudioOutputPulse::StreamSuccessCallback, NULL));
|
pa_operation_unref(pa_stream_cork(stream, 0, NULL, NULL));
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +78,7 @@ void AudioOutputPulse::Stop(){
|
|||||||
|
|
||||||
isPlaying=false;
|
isPlaying=false;
|
||||||
pa_threaded_mainloop_lock(mainloop);
|
pa_threaded_mainloop_lock(mainloop);
|
||||||
pa_operation_unref(pa_stream_cork(stream, 1, AudioOutputPulse::StreamSuccessCallback, NULL));
|
pa_operation_unref(pa_stream_cork(stream, 1, NULL, NULL));
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,60 +125,23 @@ void AudioOutputPulse::SetCurrentDevice(std::string devID){
|
|||||||
isConnected=true;
|
isConnected=true;
|
||||||
|
|
||||||
if(isPlaying){
|
if(isPlaying){
|
||||||
pa_operation_unref(pa_stream_cork(stream, 0, AudioOutputPulse::StreamSuccessCallback, mainloop));
|
pa_operation_unref(pa_stream_cork(stream, 0, NULL, NULL));
|
||||||
}
|
}
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioOutputPulse::EnumerateDevices(std::vector<AudioOutputDevice>& devs){
|
bool AudioOutputPulse::EnumerateDevices(std::vector<AudioOutputDevice>& devs){
|
||||||
if(!PulseAudioLoader::IncRef())
|
return AudioPulse::DoOneOperation([&](pa_context* ctx){
|
||||||
return false;
|
return pa_context_get_sink_info_list(ctx, [](pa_context* ctx, const pa_sink_info* info, int eol, void* userdata){
|
||||||
|
if(eol>0)
|
||||||
pa_mainloop* ml;
|
return;
|
||||||
pa_mainloop_api* mlAPI;
|
std::vector<AudioOutputDevice>* devs=(std::vector<AudioOutputDevice>*)userdata;
|
||||||
pa_context* ctx;
|
AudioOutputDevice dev;
|
||||||
pa_operation* op=NULL;
|
dev.id=std::string(info->name);
|
||||||
int state=0;
|
dev.displayName=std::string(info->description);
|
||||||
int paReady=0;
|
devs->push_back(dev);
|
||||||
|
}, &devs);
|
||||||
ml=pa_mainloop_new();
|
});
|
||||||
mlAPI=pa_mainloop_get_api(ml);
|
|
||||||
ctx=pa_context_new(mlAPI, "libtgvoip");
|
|
||||||
|
|
||||||
pa_context_connect(ctx, NULL, PA_CONTEXT_NOFLAGS, NULL);
|
|
||||||
pa_context_set_state_callback(ctx, AudioOutputPulse::ContextStateCallbackEnum, &paReady);
|
|
||||||
|
|
||||||
while(true){
|
|
||||||
if(paReady==0){
|
|
||||||
pa_mainloop_iterate(ml, 1, NULL);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(paReady==2){
|
|
||||||
pa_context_disconnect(ctx);
|
|
||||||
pa_context_unref(ctx);
|
|
||||||
pa_mainloop_free(ml);
|
|
||||||
PulseAudioLoader::DecRef();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!op){
|
|
||||||
op=pa_context_get_sink_info_list(ctx, AudioOutputPulse::DeviceEnumCallback, &devs);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(pa_operation_get_state(op)==PA_OPERATION_DONE){
|
|
||||||
pa_operation_unref(op);
|
|
||||||
pa_context_disconnect(ctx);
|
|
||||||
pa_context_unref(ctx);
|
|
||||||
pa_mainloop_free(ml);
|
|
||||||
PulseAudioLoader::DecRef();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
pa_mainloop_iterate(ml, 1, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioOutputPulse::ContextStateCallback(pa_context* context, void* arg) {
|
|
||||||
AudioOutputPulse* self=(AudioOutputPulse*) arg;
|
|
||||||
pa_threaded_mainloop_signal(self->mainloop, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutputPulse::StreamStateCallback(pa_stream *s, void* arg) {
|
void AudioOutputPulse::StreamStateCallback(pa_stream *s, void* arg) {
|
||||||
@ -295,39 +170,3 @@ void AudioOutputPulse::StreamWriteCallback(pa_stream *stream, size_t requestedBy
|
|||||||
if(remainingDataSize>0)
|
if(remainingDataSize>0)
|
||||||
memmove(remainingData, remainingData+requestedBytes, remainingDataSize);
|
memmove(remainingData, remainingData+requestedBytes, remainingDataSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutputPulse::StreamSuccessCallback(pa_stream *stream, int success, void *userdata) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioOutputPulse::ContextStateCallbackEnum(pa_context* context, void* arg){
|
|
||||||
pa_context_state_t state;
|
|
||||||
int* pa_ready=(int*)arg;
|
|
||||||
|
|
||||||
state=pa_context_get_state(context);
|
|
||||||
switch(state){
|
|
||||||
case PA_CONTEXT_UNCONNECTED:
|
|
||||||
case PA_CONTEXT_CONNECTING:
|
|
||||||
case PA_CONTEXT_AUTHORIZING:
|
|
||||||
case PA_CONTEXT_SETTING_NAME:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
case PA_CONTEXT_FAILED:
|
|
||||||
case PA_CONTEXT_TERMINATED:
|
|
||||||
*pa_ready=2;
|
|
||||||
break;
|
|
||||||
case PA_CONTEXT_READY:
|
|
||||||
*pa_ready=1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioOutputPulse::DeviceEnumCallback(pa_context* ctx, const pa_sink_info* info, int eol, void* userdata){
|
|
||||||
if(eol>0)
|
|
||||||
return;
|
|
||||||
std::vector<AudioOutputDevice>* devs=(std::vector<AudioOutputDevice>*)userdata;
|
|
||||||
AudioOutputDevice dev;
|
|
||||||
dev.id=std::string(info->name);
|
|
||||||
dev.displayName=std::string(info->description);
|
|
||||||
devs->push_back(dev);
|
|
||||||
}
|
|
||||||
|
|||||||
@ -16,27 +16,20 @@ namespace audio{
|
|||||||
|
|
||||||
class AudioOutputPulse : public AudioOutput{
|
class AudioOutputPulse : public AudioOutput{
|
||||||
public:
|
public:
|
||||||
AudioOutputPulse(std::string devID);
|
AudioOutputPulse(pa_context* context, pa_threaded_mainloop* mainloop, std::string devID);
|
||||||
virtual ~AudioOutputPulse();
|
virtual ~AudioOutputPulse();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual bool IsPlaying();
|
virtual bool IsPlaying();
|
||||||
virtual void SetCurrentDevice(std::string devID);
|
virtual void SetCurrentDevice(std::string devID);
|
||||||
static bool EnumerateDevices(std::vector<AudioOutputDevice>& devs);
|
static bool EnumerateDevices(std::vector<AudioOutputDevice>& devs);
|
||||||
static bool IsAvailable();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void ContextStateCallback(pa_context* context, void* arg);
|
|
||||||
static void ContextStateCallbackEnum(pa_context* context, void* arg);
|
|
||||||
static void StreamStateCallback(pa_stream* s, void* arg);
|
static void StreamStateCallback(pa_stream* s, void* arg);
|
||||||
static void StreamSuccessCallback(pa_stream* stream, int success, void* userdata);
|
|
||||||
static void StreamWriteCallback(pa_stream* stream, size_t requested_bytes, void* userdata);
|
static void StreamWriteCallback(pa_stream* stream, size_t requested_bytes, void* userdata);
|
||||||
static void DeviceEnumCallback(pa_context* ctx, const pa_sink_info* info, int eol, void* userdata);
|
|
||||||
void StreamWriteCallback(pa_stream* stream, size_t requestedBytes);
|
void StreamWriteCallback(pa_stream* stream, size_t requestedBytes);
|
||||||
|
|
||||||
pa_threaded_mainloop* mainloop;
|
pa_threaded_mainloop* mainloop;
|
||||||
pa_mainloop_api* mainloopApi;
|
|
||||||
pa_context* context;
|
pa_context* context;
|
||||||
pa_stream* stream;
|
pa_stream* stream;
|
||||||
|
|
||||||
|
|||||||
275
os/linux/AudioPulse.cpp
Normal file
275
os/linux/AudioPulse.cpp
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
//
|
||||||
|
// libtgvoip is free and unencumbered public domain software.
|
||||||
|
// For more information, see http://unlicense.org or the UNLICENSE file
|
||||||
|
// you should have received with this source code distribution.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "AudioPulse.h"
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include "../../logging.h"
|
||||||
|
|
||||||
|
#define DECLARE_DL_FUNCTION(name) typeof(name)* AudioPulse::_import_##name=NULL
|
||||||
|
#define CHECK_DL_ERROR(res, msg) if(!res){LOGE(msg ": %s", dlerror()); return false;}
|
||||||
|
#define LOAD_DL_FUNCTION(name) {_import_##name=(typeof(_import_##name))dlsym(lib, #name); CHECK_DL_ERROR(_import_##name, "Error getting entry point for " #name);}
|
||||||
|
#define CHECK_ERROR(res, msg) if(res!=0){LOGE(msg " failed: %s", pa_strerror(res)); failed=true; return;}
|
||||||
|
|
||||||
|
using namespace tgvoip;
|
||||||
|
using namespace tgvoip::audio;
|
||||||
|
|
||||||
|
bool AudioPulse::loaded=false;
|
||||||
|
void* AudioPulse::lib=NULL;
|
||||||
|
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_new);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_get_api);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_new);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_set_state_callback);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_lock);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_unlock);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_start);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_connect);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_get_state);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_wait);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_new);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_set_state_callback);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_set_write_callback);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_connect_playback);
|
||||||
|
DECLARE_DL_FUNCTION(pa_operation_unref);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_cork);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_stop);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_disconnect);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_unref);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_disconnect);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_unref);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_free);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_signal);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_begin_write);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_write);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_get_state);
|
||||||
|
DECLARE_DL_FUNCTION(pa_strerror);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_set_read_callback);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_connect_record);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_peek);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_drop);
|
||||||
|
DECLARE_DL_FUNCTION(pa_mainloop_new);
|
||||||
|
DECLARE_DL_FUNCTION(pa_mainloop_get_api);
|
||||||
|
DECLARE_DL_FUNCTION(pa_mainloop_iterate);
|
||||||
|
DECLARE_DL_FUNCTION(pa_mainloop_free);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_get_sink_info_list);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_get_source_info_list);
|
||||||
|
DECLARE_DL_FUNCTION(pa_operation_get_state);
|
||||||
|
|
||||||
|
#include "PulseFunctions.h"
|
||||||
|
|
||||||
|
bool AudioPulse::Load(){
|
||||||
|
if(loaded)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
lib=dlopen("libpulse.so.0", RTLD_LAZY);
|
||||||
|
if(!lib)
|
||||||
|
lib=dlopen("libpulse.so", RTLD_LAZY);
|
||||||
|
if(!lib){
|
||||||
|
LOGE("Error loading libpulse: %s", dlerror());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOAD_DL_FUNCTION(pa_threaded_mainloop_new);
|
||||||
|
LOAD_DL_FUNCTION(pa_threaded_mainloop_get_api);
|
||||||
|
LOAD_DL_FUNCTION(pa_context_new);
|
||||||
|
LOAD_DL_FUNCTION(pa_context_set_state_callback);
|
||||||
|
LOAD_DL_FUNCTION(pa_threaded_mainloop_lock);
|
||||||
|
LOAD_DL_FUNCTION(pa_threaded_mainloop_unlock);
|
||||||
|
LOAD_DL_FUNCTION(pa_threaded_mainloop_start);
|
||||||
|
LOAD_DL_FUNCTION(pa_context_connect);
|
||||||
|
LOAD_DL_FUNCTION(pa_context_get_state);
|
||||||
|
LOAD_DL_FUNCTION(pa_threaded_mainloop_wait);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_new);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_set_state_callback);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_set_write_callback);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_connect_playback);
|
||||||
|
LOAD_DL_FUNCTION(pa_operation_unref);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_cork);
|
||||||
|
LOAD_DL_FUNCTION(pa_threaded_mainloop_stop);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_disconnect);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_unref);
|
||||||
|
LOAD_DL_FUNCTION(pa_context_disconnect);
|
||||||
|
LOAD_DL_FUNCTION(pa_context_unref);
|
||||||
|
LOAD_DL_FUNCTION(pa_threaded_mainloop_free);
|
||||||
|
LOAD_DL_FUNCTION(pa_threaded_mainloop_signal);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_begin_write);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_write);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_get_state);
|
||||||
|
LOAD_DL_FUNCTION(pa_strerror);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_set_read_callback);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_connect_record);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_peek);
|
||||||
|
LOAD_DL_FUNCTION(pa_stream_drop);
|
||||||
|
LOAD_DL_FUNCTION(pa_mainloop_new);
|
||||||
|
LOAD_DL_FUNCTION(pa_mainloop_get_api);
|
||||||
|
LOAD_DL_FUNCTION(pa_mainloop_iterate);
|
||||||
|
LOAD_DL_FUNCTION(pa_mainloop_free);
|
||||||
|
LOAD_DL_FUNCTION(pa_context_get_sink_info_list);
|
||||||
|
LOAD_DL_FUNCTION(pa_context_get_source_info_list);
|
||||||
|
LOAD_DL_FUNCTION(pa_operation_get_state);
|
||||||
|
|
||||||
|
loaded=true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioPulse::AudioPulse(std::string inputDevice, std::string outputDevice){
|
||||||
|
if(!Load()){
|
||||||
|
failed=true;
|
||||||
|
LOGE("Failed to load libpulse");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mainloop=pa_threaded_mainloop_new();
|
||||||
|
if(!mainloop){
|
||||||
|
LOGE("Error initializing PulseAudio (pa_threaded_mainloop_new)");
|
||||||
|
failed=true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mainloopApi=pa_threaded_mainloop_get_api(mainloop);
|
||||||
|
#ifndef MAXPATHLEN
|
||||||
|
char exeName[20];
|
||||||
|
#else
|
||||||
|
char exePath[MAXPATHLEN];
|
||||||
|
char exeName[MAXPATHLEN];
|
||||||
|
ssize_t lres=readlink("/proc/self/exe", exePath, sizeof(exePath));
|
||||||
|
if(lres==-1)
|
||||||
|
lres=readlink("/proc/curproc/file", exePath, sizeof(exePath));
|
||||||
|
if(lres==-1)
|
||||||
|
lres=readlink("/proc/curproc/exe", exePath, sizeof(exePath));
|
||||||
|
if(lres>0){
|
||||||
|
strcpy(exeName, basename(exePath));
|
||||||
|
}else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
snprintf(exeName, sizeof(exeName), "Process %d", getpid());
|
||||||
|
}
|
||||||
|
context=pa_context_new(mainloopApi, exeName);
|
||||||
|
if(!context){
|
||||||
|
LOGE("Error initializing PulseAudio (pa_context_new)");
|
||||||
|
failed=true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pa_context_set_state_callback(context, [](pa_context* context, void* arg){
|
||||||
|
AudioPulse* self=reinterpret_cast<AudioPulse*>(arg);
|
||||||
|
pa_threaded_mainloop_signal(self->mainloop, 0);
|
||||||
|
}, this);
|
||||||
|
pa_threaded_mainloop_lock(mainloop);
|
||||||
|
isLocked=true;
|
||||||
|
int err=pa_threaded_mainloop_start(mainloop);
|
||||||
|
CHECK_ERROR(err, "pa_threaded_mainloop_start");
|
||||||
|
didStart=true;
|
||||||
|
|
||||||
|
err=pa_context_connect(context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL);
|
||||||
|
CHECK_ERROR(err, "pa_context_connect");
|
||||||
|
|
||||||
|
while(true){
|
||||||
|
pa_context_state_t contextState=pa_context_get_state(context);
|
||||||
|
if(!PA_CONTEXT_IS_GOOD(contextState)){
|
||||||
|
LOGE("Error initializing PulseAudio (PA_CONTEXT_IS_GOOD)");
|
||||||
|
failed=true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(contextState==PA_CONTEXT_READY)
|
||||||
|
break;
|
||||||
|
pa_threaded_mainloop_wait(mainloop);
|
||||||
|
}
|
||||||
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
|
isLocked=false;
|
||||||
|
|
||||||
|
output=new AudioOutputPulse(context, mainloop, outputDevice);
|
||||||
|
input=new AudioInputPulse(context, mainloop, outputDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioPulse::~AudioPulse(){
|
||||||
|
if(mainloop && didStart){
|
||||||
|
if(isLocked)
|
||||||
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
|
pa_threaded_mainloop_stop(mainloop);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(input)
|
||||||
|
delete input;
|
||||||
|
if(output)
|
||||||
|
delete output;
|
||||||
|
|
||||||
|
if(context){
|
||||||
|
pa_context_disconnect(context);
|
||||||
|
pa_context_unref(context);
|
||||||
|
}
|
||||||
|
if(mainloop)
|
||||||
|
pa_threaded_mainloop_free(mainloop);
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioOutput* AudioPulse::GetOutput(){
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioInput* AudioPulse::GetInput(){
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioPulse::DoOneOperation(std::function<pa_operation*(pa_context*)> f){
|
||||||
|
if(!Load())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pa_mainloop* ml;
|
||||||
|
pa_mainloop_api* mlAPI;
|
||||||
|
pa_context* ctx;
|
||||||
|
pa_operation* op=NULL;
|
||||||
|
int paReady=0;
|
||||||
|
|
||||||
|
ml=pa_mainloop_new();
|
||||||
|
mlAPI=pa_mainloop_get_api(ml);
|
||||||
|
ctx=pa_context_new(mlAPI, "libtgvoip");
|
||||||
|
|
||||||
|
pa_context_connect(ctx, NULL, PA_CONTEXT_NOFLAGS, NULL);
|
||||||
|
pa_context_set_state_callback(ctx, [](pa_context* context, void* arg){
|
||||||
|
pa_context_state_t state;
|
||||||
|
int* pa_ready=(int*)arg;
|
||||||
|
|
||||||
|
state=pa_context_get_state(context);
|
||||||
|
switch(state){
|
||||||
|
case PA_CONTEXT_UNCONNECTED:
|
||||||
|
case PA_CONTEXT_CONNECTING:
|
||||||
|
case PA_CONTEXT_AUTHORIZING:
|
||||||
|
case PA_CONTEXT_SETTING_NAME:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case PA_CONTEXT_FAILED:
|
||||||
|
case PA_CONTEXT_TERMINATED:
|
||||||
|
*pa_ready=2;
|
||||||
|
break;
|
||||||
|
case PA_CONTEXT_READY:
|
||||||
|
*pa_ready=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, &paReady);
|
||||||
|
|
||||||
|
while(true){
|
||||||
|
if(paReady==0){
|
||||||
|
pa_mainloop_iterate(ml, 1, NULL);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(paReady==2){
|
||||||
|
pa_context_disconnect(ctx);
|
||||||
|
pa_context_unref(ctx);
|
||||||
|
pa_mainloop_free(ml);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(!op){
|
||||||
|
op=f(ctx);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(pa_operation_get_state(op)==PA_OPERATION_DONE){
|
||||||
|
pa_operation_unref(op);
|
||||||
|
pa_context_disconnect(ctx);
|
||||||
|
pa_context_unref(ctx);
|
||||||
|
pa_mainloop_free(ml);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
pa_mainloop_iterate(ml, 1, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
88
os/linux/AudioPulse.h
Normal file
88
os/linux/AudioPulse.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
//
|
||||||
|
// libtgvoip is free and unencumbered public domain software.
|
||||||
|
// For more information, see http://unlicense.org or the UNLICENSE file
|
||||||
|
// you should have received with this source code distribution.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef LIBTGVOIP_PULSEAUDIOLOADER_H
|
||||||
|
#define LIBTGVOIP_PULSEAUDIOLOADER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <functional>
|
||||||
|
#include <pulse/pulseaudio.h>
|
||||||
|
#include "../../audio/AudioIO.h"
|
||||||
|
#include "AudioInputPulse.h"
|
||||||
|
#include "AudioOutputPulse.h"
|
||||||
|
|
||||||
|
#define DECLARE_DL_FUNCTION(name) static typeof(name)* _import_##name
|
||||||
|
|
||||||
|
namespace tgvoip{
|
||||||
|
namespace audio{
|
||||||
|
class AudioPulse : public AudioIO{
|
||||||
|
public:
|
||||||
|
AudioPulse(std::string inputDevice, std::string outputDevice);
|
||||||
|
virtual ~AudioPulse();
|
||||||
|
virtual AudioInput* GetInput();
|
||||||
|
virtual AudioOutput* GetOutput();
|
||||||
|
|
||||||
|
static bool Load();
|
||||||
|
static bool DoOneOperation(std::function<pa_operation*(pa_context*)> f);
|
||||||
|
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_new);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_get_api);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_new);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_set_state_callback);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_lock);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_unlock);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_start);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_connect);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_get_state);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_wait);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_new);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_set_state_callback);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_set_write_callback);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_connect_playback);
|
||||||
|
DECLARE_DL_FUNCTION(pa_operation_unref);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_cork);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_stop);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_disconnect);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_unref);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_disconnect);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_unref);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_free);
|
||||||
|
DECLARE_DL_FUNCTION(pa_threaded_mainloop_signal);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_begin_write);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_write);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_get_state);
|
||||||
|
DECLARE_DL_FUNCTION(pa_strerror);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_set_read_callback);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_connect_record);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_peek);
|
||||||
|
DECLARE_DL_FUNCTION(pa_stream_drop);
|
||||||
|
|
||||||
|
DECLARE_DL_FUNCTION(pa_mainloop_new);
|
||||||
|
DECLARE_DL_FUNCTION(pa_mainloop_get_api);
|
||||||
|
DECLARE_DL_FUNCTION(pa_mainloop_iterate);
|
||||||
|
DECLARE_DL_FUNCTION(pa_mainloop_free);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_get_sink_info_list);
|
||||||
|
DECLARE_DL_FUNCTION(pa_context_get_source_info_list);
|
||||||
|
DECLARE_DL_FUNCTION(pa_operation_get_state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void* lib;
|
||||||
|
static bool loaded;
|
||||||
|
AudioInputPulse* input=NULL;
|
||||||
|
AudioOutputPulse* output=NULL;
|
||||||
|
|
||||||
|
pa_threaded_mainloop* mainloop;
|
||||||
|
pa_mainloop_api* mainloopApi;
|
||||||
|
pa_context* context;
|
||||||
|
bool isLocked=false;
|
||||||
|
bool didStart=false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef DECLARE_DL_FUNCTION
|
||||||
|
|
||||||
|
#endif // LIBTGVOIP_PULSEAUDIOLOADER_H
|
||||||
43
os/linux/PulseFunctions.h
Normal file
43
os/linux/PulseFunctions.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#ifndef LIBTGVOIP_PULSE_FUNCTIONS_H
|
||||||
|
#define LIBTGVOIP_PULSE_FUNCTIONS_H
|
||||||
|
|
||||||
|
#define pa_threaded_mainloop_new AudioPulse::_import_pa_threaded_mainloop_new
|
||||||
|
#define pa_threaded_mainloop_get_api AudioPulse::_import_pa_threaded_mainloop_get_api
|
||||||
|
#define pa_context_new AudioPulse::_import_pa_context_new
|
||||||
|
#define pa_context_set_state_callback AudioPulse::_import_pa_context_set_state_callback
|
||||||
|
#define pa_threaded_mainloop_lock AudioPulse::_import_pa_threaded_mainloop_lock
|
||||||
|
#define pa_threaded_mainloop_unlock AudioPulse::_import_pa_threaded_mainloop_unlock
|
||||||
|
#define pa_threaded_mainloop_start AudioPulse::_import_pa_threaded_mainloop_start
|
||||||
|
#define pa_context_connect AudioPulse::_import_pa_context_connect
|
||||||
|
#define pa_context_get_state AudioPulse::_import_pa_context_get_state
|
||||||
|
#define pa_threaded_mainloop_wait AudioPulse::_import_pa_threaded_mainloop_wait
|
||||||
|
#define pa_stream_new AudioPulse::_import_pa_stream_new
|
||||||
|
#define pa_stream_set_state_callback AudioPulse::_import_pa_stream_set_state_callback
|
||||||
|
#define pa_stream_set_write_callback AudioPulse::_import_pa_stream_set_write_callback
|
||||||
|
#define pa_stream_connect_playback AudioPulse::_import_pa_stream_connect_playback
|
||||||
|
#define pa_operation_unref AudioPulse::_import_pa_operation_unref
|
||||||
|
#define pa_stream_cork AudioPulse::_import_pa_stream_cork
|
||||||
|
#define pa_threaded_mainloop_stop AudioPulse::_import_pa_threaded_mainloop_stop
|
||||||
|
#define pa_stream_disconnect AudioPulse::_import_pa_stream_disconnect
|
||||||
|
#define pa_stream_unref AudioPulse::_import_pa_stream_unref
|
||||||
|
#define pa_context_disconnect AudioPulse::_import_pa_context_disconnect
|
||||||
|
#define pa_context_unref AudioPulse::_import_pa_context_unref
|
||||||
|
#define pa_threaded_mainloop_free AudioPulse::_import_pa_threaded_mainloop_free
|
||||||
|
#define pa_threaded_mainloop_signal AudioPulse::_import_pa_threaded_mainloop_signal
|
||||||
|
#define pa_stream_begin_write AudioPulse::_import_pa_stream_begin_write
|
||||||
|
#define pa_stream_write AudioPulse::_import_pa_stream_write
|
||||||
|
#define pa_strerror AudioPulse::_import_pa_strerror
|
||||||
|
#define pa_stream_get_state AudioPulse::_import_pa_stream_get_state
|
||||||
|
#define pa_stream_set_read_callback AudioPulse::_import_pa_stream_set_read_callback
|
||||||
|
#define pa_stream_connect_record AudioPulse::_import_pa_stream_connect_record
|
||||||
|
#define pa_stream_peek AudioPulse::_import_pa_stream_peek
|
||||||
|
#define pa_stream_drop AudioPulse::_import_pa_stream_drop
|
||||||
|
#define pa_mainloop_new AudioPulse::_import_pa_mainloop_new
|
||||||
|
#define pa_mainloop_get_api AudioPulse::_import_pa_mainloop_get_api
|
||||||
|
#define pa_mainloop_iterate AudioPulse::_import_pa_mainloop_iterate
|
||||||
|
#define pa_mainloop_free AudioPulse::_import_pa_mainloop_free
|
||||||
|
#define pa_context_get_sink_info_list AudioPulse::_import_pa_context_get_sink_info_list
|
||||||
|
#define pa_context_get_source_info_list AudioPulse::_import_pa_context_get_source_info_list
|
||||||
|
#define pa_operation_get_state AudioPulse::_import_pa_operation_get_state
|
||||||
|
|
||||||
|
#endif //LIBTGVOIP_PULSE_FUNCTIONS_H
|
||||||
@ -490,7 +490,7 @@ bool NetworkSocketPosix::Select(std::vector<NetworkSocket *> &readFds, std::vect
|
|||||||
|
|
||||||
if(canceller && FD_ISSET(canceller->pipeRead, &readSet) && !anyFailed){
|
if(canceller && FD_ISSET(canceller->pipeRead, &readSet) && !anyFailed){
|
||||||
char c;
|
char c;
|
||||||
read(canceller->pipeRead, &c, 1);
|
(void) read(canceller->pipeRead, &c, 1);
|
||||||
return false;
|
return false;
|
||||||
}else if(anyFailed){
|
}else if(anyFailed){
|
||||||
FD_ZERO(&readSet);
|
FD_ZERO(&readSet);
|
||||||
@ -539,7 +539,7 @@ SocketSelectCancellerPosix::~SocketSelectCancellerPosix(){
|
|||||||
|
|
||||||
void SocketSelectCancellerPosix::CancelSelect(){
|
void SocketSelectCancellerPosix::CancelSelect(){
|
||||||
char c=1;
|
char c=1;
|
||||||
write(pipeWrite, &c, 1);
|
(void) write(pipeWrite, &c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int NetworkSocketPosix::GetDescriptorFromSocket(NetworkSocket *socket){
|
int NetworkSocketPosix::GetDescriptorFromSocket(NetworkSocket *socket){
|
||||||
|
|||||||
@ -99,11 +99,6 @@ AudioInputWASAPI::~AudioInputWASAPI(){
|
|||||||
SafeRelease(&enumerator);
|
SafeRelease(&enumerator);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInputWASAPI::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioInputWASAPI::Start(){
|
void AudioInputWASAPI::Start(){
|
||||||
isRecording=true;
|
isRecording=true;
|
||||||
if(!thread){
|
if(!thread){
|
||||||
|
|||||||
@ -44,7 +44,6 @@ class AudioInputWASAPI : public AudioInput{
|
|||||||
public:
|
public:
|
||||||
AudioInputWASAPI(std::string deviceID);
|
AudioInputWASAPI(std::string deviceID);
|
||||||
virtual ~AudioInputWASAPI();
|
virtual ~AudioInputWASAPI();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual bool IsRecording();
|
virtual bool IsRecording();
|
||||||
|
|||||||
@ -37,10 +37,6 @@ AudioInputWave::~AudioInputWave(){
|
|||||||
waveInClose(hWaveIn);
|
waveInClose(hWaveIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInputWave::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioInputWave::Start(){
|
void AudioInputWave::Start(){
|
||||||
if(!isRecording){
|
if(!isRecording){
|
||||||
isRecording=true;
|
isRecording=true;
|
||||||
|
|||||||
@ -20,7 +20,6 @@ class AudioInputWave : public AudioInput{
|
|||||||
public:
|
public:
|
||||||
AudioInputWave(std::string deviceID);
|
AudioInputWave(std::string deviceID);
|
||||||
virtual ~AudioInputWave();
|
virtual ~AudioInputWave();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual void SetCurrentDevice(std::string deviceID);
|
virtual void SetCurrentDevice(std::string deviceID);
|
||||||
|
|||||||
@ -101,10 +101,6 @@ AudioOutputWASAPI::~AudioOutputWASAPI(){
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutputWASAPI::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioOutputWASAPI::Start(){
|
void AudioOutputWASAPI::Start(){
|
||||||
isPlaying=true;
|
isPlaying=true;
|
||||||
if(!thread){
|
if(!thread){
|
||||||
|
|||||||
@ -43,7 +43,6 @@ class AudioOutputWASAPI : public AudioOutput{
|
|||||||
public:
|
public:
|
||||||
AudioOutputWASAPI(std::string deviceID);
|
AudioOutputWASAPI(std::string deviceID);
|
||||||
virtual ~AudioOutputWASAPI();
|
virtual ~AudioOutputWASAPI();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual bool IsPlaying();
|
virtual bool IsPlaying();
|
||||||
|
|||||||
@ -35,10 +35,6 @@ AudioOutputWave::~AudioOutputWave(){
|
|||||||
waveOutClose(hWaveOut);
|
waveOutClose(hWaveOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioOutputWave::Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioOutputWave::Start(){
|
void AudioOutputWave::Start(){
|
||||||
if(!isPlaying){
|
if(!isPlaying){
|
||||||
isPlaying=true;
|
isPlaying=true;
|
||||||
|
|||||||
@ -19,7 +19,6 @@ class AudioOutputWave : public AudioOutput{
|
|||||||
public:
|
public:
|
||||||
AudioOutputWave(std::string deviceID);
|
AudioOutputWave(std::string deviceID);
|
||||||
virtual ~AudioOutputWave();
|
virtual ~AudioOutputWave();
|
||||||
virtual void Configure(uint32_t sampleRate, uint32_t bitsPerSample, uint32_t channels);
|
|
||||||
virtual void Start();
|
virtual void Start();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual bool IsPlaying();
|
virtual bool IsPlaying();
|
||||||
|
|||||||
35
threading.h
35
threading.h
@ -38,6 +38,10 @@ namespace tgvoip{
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include "os/darwin/DarwinSpecific.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace tgvoip{
|
namespace tgvoip{
|
||||||
class Mutex{
|
class Mutex{
|
||||||
@ -58,6 +62,10 @@ namespace tgvoip{
|
|||||||
pthread_mutex_unlock(&mtx);
|
pthread_mutex_unlock(&mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_t* NativeHandle(){
|
||||||
|
return &mtx;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mutex(const Mutex& other);
|
Mutex(const Mutex& other);
|
||||||
pthread_mutex_t mtx;
|
pthread_mutex_t mtx;
|
||||||
@ -69,7 +77,7 @@ namespace tgvoip{
|
|||||||
name=NULL;
|
name=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Thread(){
|
virtual ~Thread(){
|
||||||
delete entry;
|
delete entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +95,17 @@ namespace tgvoip{
|
|||||||
|
|
||||||
|
|
||||||
void SetMaxPriority(){
|
void SetMaxPriority(){
|
||||||
|
#ifdef __APPLE__
|
||||||
|
maxPriority=true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Sleep(double seconds){
|
||||||
|
usleep((useconds_t)(seconds*1000000000));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsCurrent(){
|
||||||
|
return thread==pthread_self();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -98,6 +116,9 @@ namespace tgvoip{
|
|||||||
pthread_setname_np(self->thread, self->name);
|
pthread_setname_np(self->thread, self->name);
|
||||||
#elif !defined(__gnu_hurd__)
|
#elif !defined(__gnu_hurd__)
|
||||||
pthread_setname_np(self->name);
|
pthread_setname_np(self->name);
|
||||||
|
if(self->maxPriority){
|
||||||
|
DarwinSpecific::SetCurrentThreadPriority(DarwinSpecific::THREAD_PRIO_USER_INTERACTIVE);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
self->entry->Invoke(self->arg);
|
self->entry->Invoke(self->arg);
|
||||||
@ -107,6 +128,7 @@ namespace tgvoip{
|
|||||||
void* arg;
|
void* arg;
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
const char* name;
|
const char* name;
|
||||||
|
bool maxPriority=false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +249,7 @@ namespace tgvoip{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Start(){
|
void Start(){
|
||||||
thread=CreateThread(NULL, 0, Thread::ActualEntryPoint, this, 0, NULL);
|
thread=CreateThread(NULL, 0, Thread::ActualEntryPoint, this, 0, &id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Join(){
|
void Join(){
|
||||||
@ -247,6 +269,14 @@ namespace tgvoip{
|
|||||||
SetThreadPriority(thread, THREAD_PRIORITY_HIGHEST);
|
SetThreadPriority(thread, THREAD_PRIORITY_HIGHEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Sleep(double seconds){
|
||||||
|
::Sleep((DWORD)(seconds*1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsCurrent(){
|
||||||
|
return id==GetCurrentThreadId();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const DWORD MS_VC_EXCEPTION=0x406D1388;
|
static const DWORD MS_VC_EXCEPTION=0x406D1388;
|
||||||
|
|
||||||
@ -278,6 +308,7 @@ namespace tgvoip{
|
|||||||
MethodPointerBase* entry;
|
MethodPointerBase* entry;
|
||||||
void* arg;
|
void* arg;
|
||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
|
DWORD id;
|
||||||
const char* name;
|
const char* name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user