mirror of
https://github.com/danog/libtgvoip.git
synced 2025-01-22 13:01:21 +01:00
Save more data in data saving mode
This commit is contained in:
parent
f4c4f792d1
commit
f85ce99894
@ -49,6 +49,7 @@ EchoCanceller::EchoCanceller(bool enableAEC, bool enableNS, bool enableAGC){
|
||||
apm->gain_control()->set_mode(webrtc::GainControl::Mode::kAdaptiveDigital);
|
||||
apm->gain_control()->set_target_level_dbfs(9);
|
||||
}
|
||||
apm->voice_detection()->set_likelihood(webrtc::VoiceDetection::Likelihood::kVeryLowLikelihood);
|
||||
|
||||
audioFrame=new webrtc::AudioFrame();
|
||||
audioFrame->samples_per_channel_=480;
|
||||
@ -119,7 +120,7 @@ void EchoCanceller::Enable(bool enabled){
|
||||
isOn=enabled;
|
||||
}
|
||||
|
||||
void EchoCanceller::ProcessInput(int16_t* inOut, size_t numSamples){
|
||||
void EchoCanceller::ProcessInput(int16_t* inOut, size_t numSamples, bool& hasVoice){
|
||||
if(!isOn || (!enableAEC && !enableAGC && !enableNS)){
|
||||
return;
|
||||
}
|
||||
@ -127,12 +128,19 @@ void EchoCanceller::ProcessInput(int16_t* inOut, size_t numSamples){
|
||||
assert(numSamples==960);
|
||||
|
||||
memcpy(audioFrame->mutable_data(), inOut, 480*2);
|
||||
apm->set_stream_delay_ms(delay);
|
||||
if(enableAEC)
|
||||
apm->set_stream_delay_ms(delay);
|
||||
apm->ProcessStream(audioFrame);
|
||||
if(enableVAD)
|
||||
hasVoice=apm->voice_detection()->stream_has_voice();
|
||||
memcpy(inOut, audioFrame->data(), 480*2);
|
||||
memcpy(audioFrame->mutable_data(), inOut+480, 480*2);
|
||||
apm->set_stream_delay_ms(delay);
|
||||
if(enableAEC)
|
||||
apm->set_stream_delay_ms(delay);
|
||||
apm->ProcessStream(audioFrame);
|
||||
if(enableVAD){
|
||||
hasVoice=hasVoice || apm->voice_detection()->stream_has_voice();
|
||||
}
|
||||
memcpy(inOut+480, audioFrame->data(), 480*2);
|
||||
}
|
||||
|
||||
@ -149,6 +157,11 @@ void EchoCanceller::SetAECStrength(int strength){
|
||||
#endif
|
||||
}
|
||||
|
||||
void EchoCanceller::SetVoiceDetectionEnabled(bool enabled){
|
||||
enableVAD=enabled;
|
||||
apm->voice_detection()->Enable(enabled);
|
||||
}
|
||||
|
||||
AudioEffect::~AudioEffect(){
|
||||
|
||||
}
|
||||
|
@ -29,13 +29,15 @@ public:
|
||||
virtual void Stop();
|
||||
void SpeakerOutCallback(unsigned char* data, size_t len);
|
||||
void Enable(bool enabled);
|
||||
void ProcessInput(int16_t* inOut, size_t numSamples);
|
||||
void ProcessInput(int16_t* inOut, size_t numSamples, bool& hasVoice);
|
||||
void SetAECStrength(int strength);
|
||||
void SetVoiceDetectionEnabled(bool enabled);
|
||||
|
||||
private:
|
||||
bool enableAEC;
|
||||
bool enableAGC;
|
||||
bool enableNS;
|
||||
bool enableVAD=false;
|
||||
bool isOn;
|
||||
#ifndef TGVOIP_NO_DSP
|
||||
webrtc::AudioProcessing* apm=NULL;
|
||||
|
@ -23,7 +23,7 @@ tgvoip::OpusEncoder::OpusEncoder(MediaStreamItf *source, bool needSecondary):que
|
||||
opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1));
|
||||
opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
|
||||
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
|
||||
requestedBitrate=32000;
|
||||
requestedBitrate=20000;
|
||||
currentBitrate=0;
|
||||
running=false;
|
||||
echoCanceller=NULL;
|
||||
@ -32,8 +32,9 @@ tgvoip::OpusEncoder::OpusEncoder(MediaStreamItf *source, bool needSecondary):que
|
||||
levelMeter=NULL;
|
||||
mediumCorrectionBitrate=static_cast<uint32_t>(ServerConfig::GetSharedInstance()->GetInt("audio_medium_fec_bitrate", 10000));
|
||||
strongCorrectionBitrate=static_cast<uint32_t>(ServerConfig::GetSharedInstance()->GetInt("audio_strong_fec_bitrate", 8000));
|
||||
mediumCorrectionMultiplier=ServerConfig::GetSharedInstance()->GetDouble("audio_medium_fec_multiplier", 1.5);
|
||||
strongCorrectionMultiplier=ServerConfig::GetSharedInstance()->GetDouble("audio_strong_fec_multiplier", 2.0);
|
||||
mediumCorrectionMultiplier=ServerConfig::GetSharedInstance()->GetDouble("audio_medium_fec_multiplier", 0.8);
|
||||
strongCorrectionMultiplier=ServerConfig::GetSharedInstance()->GetDouble("audio_strong_fec_multiplier", 0.5);
|
||||
vadNoVoiceBitrate=static_cast<uint32_t>(ServerConfig::GetSharedInstance()->GetInt("audio_vad_no_voice_bitrate", 6000));
|
||||
secondaryEncoderEnabled=false;
|
||||
|
||||
if(needSecondary){
|
||||
@ -44,7 +45,7 @@ tgvoip::OpusEncoder::OpusEncoder(MediaStreamItf *source, bool needSecondary):que
|
||||
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(8000));
|
||||
opus_encoder_ctl(secondaryEncoder, OPUS_SET_INBAND_FEC(1));
|
||||
opus_encoder_ctl(secondaryEncoder, OPUS_SET_PACKET_LOSS_PERC(15));
|
||||
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
|
||||
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
|
||||
}else{
|
||||
secondaryEncoder=NULL;
|
||||
}
|
||||
@ -140,19 +141,50 @@ void tgvoip::OpusEncoder::RunThread(){
|
||||
frame=(int16_t*) malloc(960*2*packetsPerFrame);
|
||||
else
|
||||
frame=NULL;
|
||||
bool frameHasVoice=false;
|
||||
bool wasVadMode=false;
|
||||
while(running){
|
||||
int16_t* packet=(int16_t*)queue.GetBlocking();
|
||||
if(packet){
|
||||
bool hasVoice=true;
|
||||
if(echoCanceller)
|
||||
echoCanceller->ProcessInput(packet, 960);
|
||||
echoCanceller->ProcessInput(packet, 960, hasVoice);
|
||||
if(packetsPerFrame==1){
|
||||
Encode(packet, 960);
|
||||
}else{
|
||||
memcpy(frame+(960*bufferedCount), packet, 960*2);
|
||||
frameHasVoice=frameHasVoice || hasVoice;
|
||||
bufferedCount++;
|
||||
if(bufferedCount==packetsPerFrame){
|
||||
if(vadMode){
|
||||
if(frameHasVoice){
|
||||
opus_encoder_ctl(enc, OPUS_SET_BITRATE(currentBitrate));
|
||||
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
|
||||
if(secondaryEncoder){
|
||||
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentBitrate));
|
||||
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
|
||||
}
|
||||
}else{
|
||||
opus_encoder_ctl(enc, OPUS_SET_BITRATE(vadNoVoiceBitrate));
|
||||
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
|
||||
if(secondaryEncoder){
|
||||
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(vadNoVoiceBitrate));
|
||||
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
|
||||
}
|
||||
}
|
||||
wasVadMode=true;
|
||||
}else if(wasVadMode){
|
||||
wasVadMode=false;
|
||||
opus_encoder_ctl(enc, OPUS_SET_BITRATE(currentBitrate));
|
||||
opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
|
||||
if(secondaryEncoder){
|
||||
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentBitrate));
|
||||
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
|
||||
}
|
||||
}
|
||||
Encode(frame, 960*packetsPerFrame);
|
||||
bufferedCount=0;
|
||||
frameHasVoice=false;
|
||||
}
|
||||
}
|
||||
bufferPool.Reuse(reinterpret_cast<unsigned char *>(packet));
|
||||
@ -169,7 +201,7 @@ void tgvoip::OpusEncoder::SetOutputFrameDuration(uint32_t duration){
|
||||
|
||||
|
||||
void tgvoip::OpusEncoder::SetPacketLoss(int percent){
|
||||
packetLossPercent=percent;
|
||||
packetLossPercent=std::min(20, percent);
|
||||
double multiplier=1;
|
||||
if(currentBitrate<=strongCorrectionBitrate)
|
||||
multiplier=strongCorrectionMultiplier;
|
||||
@ -202,3 +234,7 @@ void tgvoip::OpusEncoder::InvokeCallback(unsigned char *data, size_t length, uns
|
||||
void tgvoip::OpusEncoder::SetSecondaryEncoderEnabled(bool enabled){
|
||||
secondaryEncoderEnabled=enabled;
|
||||
}
|
||||
|
||||
void tgvoip::OpusEncoder::SetVadMode(bool vad){
|
||||
vadMode=vad;
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
void SetLevelMeter(AudioLevelMeter* levelMeter);
|
||||
void SetCallback(void (*f)(unsigned char*, size_t, unsigned char*, size_t, void*), void* param);
|
||||
void SetSecondaryEncoderEnabled(bool enabled);
|
||||
void SetVadMode(bool vad);
|
||||
|
||||
private:
|
||||
static size_t Callback(unsigned char* data, size_t len, void* param);
|
||||
@ -63,6 +64,8 @@ private:
|
||||
double strongCorrectionMultiplier;
|
||||
AudioLevelMeter* levelMeter;
|
||||
bool secondaryEncoderEnabled;
|
||||
bool vadMode=false;
|
||||
uint32_t vadNoVoiceBitrate;
|
||||
|
||||
void (*callback)(unsigned char*, size_t, unsigned char*, size_t, void*);
|
||||
void* callbackParam;
|
||||
|
@ -1159,6 +1159,9 @@ void VoIPController::UpdateAudioBitrateLimit(){
|
||||
maxBitrate=maxAudioBitrate;
|
||||
encoder->SetBitrate(initAudioBitrate);
|
||||
}
|
||||
encoder->SetVadMode(dataSavingMode || dataSavingRequestedByPeer);
|
||||
if(echoCanceller)
|
||||
echoCanceller->SetVoiceDetectionEnabled(dataSavingMode || dataSavingRequestedByPeer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1978,7 +1981,7 @@ simpleAudioBlock random_id:long random_bytes:string raw_data:string = DecryptedA
|
||||
DebugLoggedPacket dpkt={
|
||||
static_cast<int32_t>(pseq),
|
||||
GetCurrentTime()-connectionInitTime,
|
||||
static_cast<int32_t>(packetInnerLen)
|
||||
static_cast<int32_t>(packet.length)
|
||||
};
|
||||
debugLoggedPackets.push_back(dpkt);
|
||||
if(debugLoggedPackets.size()>=2500){
|
||||
|
@ -41,14 +41,13 @@ void AudioInputAudioUnit::Stop(){
|
||||
|
||||
void AudioInputAudioUnit::HandleBufferCallback(AudioBufferList *ioData){
|
||||
int i;
|
||||
int j;
|
||||
for(i=0;i<ioData->mNumberBuffers;i++){
|
||||
AudioBuffer buf=ioData->mBuffers[i];
|
||||
#if TARGET_OS_OSX
|
||||
assert(remainingDataSize+buf.mDataByteSize/2<10240);
|
||||
float* src=reinterpret_cast<float*>(buf.mData);
|
||||
int16_t* dst=reinterpret_cast<int16_t*>(remainingData+remainingDataSize);
|
||||
for(j=0;j<buf.mDataByteSize/4;j++){
|
||||
for(int j=0;j<buf.mDataByteSize/4;j++){
|
||||
dst[j]=(int16_t)(src[j]*INT16_MAX);
|
||||
}
|
||||
remainingDataSize+=buf.mDataByteSize/2;
|
||||
|
Loading…
x
Reference in New Issue
Block a user