diff --git a/audio/AudioIOCallback.cpp b/audio/AudioIOCallback.cpp index 2879aa3..f57fda2 100644 --- a/audio/AudioIOCallback.cpp +++ b/audio/AudioIOCallback.cpp @@ -129,7 +129,14 @@ void AudioOutputCallback::RunThread() while (running) { double t = VoIPController::GetCurrentTime(); - InvokeCallback(reinterpret_cast(buf), 960 * 2); + if (playing) + { + InvokeCallback(reinterpret_cast(buf), 960 * 2); + } + else + { + memset(buf, 0, sizeof(buf)); + } dataCallback(buf, 960); double sl = 0.02 - (VoIPController::GetCurrentTime() - t); if (sl > 0) diff --git a/controller/audio/AudioPacketSender.cpp b/controller/audio/AudioPacketSender.cpp index 7b97303..0333055 100644 --- a/controller/audio/AudioPacketSender.cpp +++ b/controller/audio/AudioPacketSender.cpp @@ -58,9 +58,10 @@ void AudioPacketSender::SendFrame(unsigned char *data, size_t len, unsigned char BufferOutputStream pkt(1500); bool hasExtraFEC = PeerVersion() >= 7 && secondaryLen && shittyInternetMode; - unsigned char flags = (unsigned char)(len > 255 || hasExtraFEC ? STREAM_DATA_FLAG_LEN16 : 0); - pkt.WriteByte((unsigned char)(1 | flags)); // streamID + flags - if (len > 255 || hasExtraFEC) + uint8_t flags = static_cast(len > 255 || hasExtraFEC ? STREAM_DATA_FLAG_LEN16 : 0); + pkt.WriteByte(flags | 1); // flags + streamID + + if (flags & STREAM_DATA_FLAG_LEN16) { int16_t lenAndFlags = static_cast(len); if (hasExtraFEC) @@ -69,8 +70,9 @@ void AudioPacketSender::SendFrame(unsigned char *data, size_t len, unsigned char } else { - pkt.WriteByte((unsigned char)len); + pkt.WriteByte(static_cast(len)); } + pkt.WriteInt32(audioTimestampOut); pkt.WriteBytes(*dataBufPtr, 0, len); @@ -78,6 +80,14 @@ void AudioPacketSender::SendFrame(unsigned char *data, size_t len, unsigned char if (hasExtraFEC) { + Buffer ecBuf(secondaryLen); + ecBuf.CopyFromOtherBuffer(*secondaryDataBufPtr, secondaryLen); + ecAudioPackets.push_back(move(ecBuf)); + if (ecAudioPackets.size() > 4) + { + ecAudioPackets.pop_front(); + } + uint8_t fecCount = std::min(static_cast(ecAudioPackets.size()), extraEcLevel); pkt.WriteByte(fecCount); for (auto ecData = ecAudioPackets.end() - fecCount; ecData != ecAudioPackets.end(); ++ecData) @@ -85,13 +95,6 @@ void AudioPacketSender::SendFrame(unsigned char *data, size_t len, unsigned char pkt.WriteByte(static_cast(ecData->Length())); pkt.WriteBytes(*ecData); } - Buffer ecBuf(secondaryLen); - ecBuf.CopyFromOtherBuffer(*secondaryDataBufPtr, secondaryLen); - ecAudioPackets.push_back(move(ecBuf)); - while (ecAudioPackets.size() > 4) - { - ecAudioPackets.pop_front(); - } } //unsentStreamPackets++; diff --git a/controller/audio/OpusEncoder.cpp b/controller/audio/OpusEncoder.cpp index d5712d4..05fd563 100755 --- a/controller/audio/OpusEncoder.cpp +++ b/controller/audio/OpusEncoder.cpp @@ -40,6 +40,7 @@ tgvoip::OpusEncoder::OpusEncoder(const std::shared_ptr &source, { this->source = source; source->SetCallback(tgvoip::OpusEncoder::Callback, this); + enc = opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, NULL); opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(1)); @@ -59,12 +60,13 @@ tgvoip::OpusEncoder::OpusEncoder(const std::shared_ptr &source, secondaryEnabledBandwidth = serverConfigValueToBandwidth(ServerConfig::GetSharedInstance()->GetInt("audio_extra_ec_bandwidth", 2)); secondaryEncoderEnabled = false; + currentSecondaryBitrate = 8000; if (needSecondary) { secondaryEncoder = opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, NULL); opus_encoder_ctl(secondaryEncoder, OPUS_SET_COMPLEXITY(10)); opus_encoder_ctl(secondaryEncoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); - opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(8000)); + opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentSecondaryBitrate)); } else { @@ -185,7 +187,7 @@ void tgvoip::OpusEncoder::RunThread() LOGV("starting encoder, packets per frame=%d", packetsPerFrame); int16_t *frame; if (packetsPerFrame > 1) - frame = (int16_t *)malloc(960 * 2 * packetsPerFrame); + frame = reinterpret_cast(std::malloc(960 * 2 * packetsPerFrame)); else frame = NULL; bool frameHasVoice = false; @@ -195,7 +197,7 @@ void tgvoip::OpusEncoder::RunThread() Buffer _packet = queue.GetBlocking(); if (!_packet.IsEmpty()) { - int16_t *packet = (int16_t *)*_packet; + int16_t *packet = reinterpret_cast(*_packet); bool hasVoice = true; if (echoCanceller) echoCanceller->ProcessInput(packet, 960, hasVoice); @@ -212,7 +214,7 @@ void tgvoip::OpusEncoder::RunThread() } else { - memcpy(frame + (960 * bufferedCount), packet, 960 * 2); + memcpy(frame + (960 * bufferedCount), packet, 960 * 2); // Accumulate raw frames frameHasVoice = frameHasVoice || hasVoice; bufferedCount++; if (bufferedCount == packetsPerFrame) @@ -224,7 +226,7 @@ void tgvoip::OpusEncoder::RunThread() opus_encoder_ctl(enc, OPUS_SET_BITRATE(currentBitrate)); if (secondaryEncoder) { - opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentBitrate)); + opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentSecondaryBitrate)); } } else @@ -243,7 +245,7 @@ void tgvoip::OpusEncoder::RunThread() opus_encoder_ctl(enc, OPUS_SET_BITRATE(currentBitrate)); if (secondaryEncoder) { - opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentBitrate)); + opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentSecondaryBitrate)); } } Encode(frame, 960 * packetsPerFrame); @@ -307,6 +309,9 @@ void tgvoip::OpusEncoder::SetVadMode(bool vad) { vadMode = vad; } + + + void tgvoip::OpusEncoder::AddAudioEffect(const std::shared_ptr &effect) { postProcEffects.push_back(effect); diff --git a/controller/audio/OpusEncoder.h b/controller/audio/OpusEncoder.h index 50e382b..45ac982 100755 --- a/controller/audio/OpusEncoder.h +++ b/controller/audio/OpusEncoder.h @@ -58,6 +58,9 @@ private: unsigned char buffer[4096]; std::atomic requestedBitrate; uint32_t currentBitrate; + + uint32_t currentSecondaryBitrate; + Thread *thread; BlockingQueue queue; BufferPool<960 * 2, 10> bufferPool; diff --git a/controller/media/Audio.cpp b/controller/media/Audio.cpp index 350c118..b33e1f9 100644 --- a/controller/media/Audio.cpp +++ b/controller/media/Audio.cpp @@ -43,6 +43,8 @@ void VoIPController::InitializeAudio() encoder->AddAudioEffect(inputVolume); } + dynamic_cast(outgoingAudioStream->packetSender.get())->SetSource(encoder); + #if defined(TGVOIP_USE_CALLBACK_AUDIO_IO) dynamic_cast(audioInput.get())->SetDataCallback(audioInputDataCallback); dynamic_cast(audioOutput.get())->SetDataCallback(audioOutputDataCallback); @@ -57,8 +59,6 @@ void VoIPController::InitializeAudio() return; } - dynamic_cast(outgoingAudioStream->packetSender.get())->SetSource(encoder); - UpdateAudioBitrateLimit(); LOGI("Audio initialization took %f seconds", GetCurrentTime() - t); }