diff options
author | Mikkel Krautz <mikkel@krautz.dk> | 2015-12-20 17:50:24 +0300 |
---|---|---|
committer | Mikkel Krautz <mikkel@krautz.dk> | 2015-12-20 17:50:24 +0300 |
commit | 443d0d294ce4aaf8109d897b9b990541cb079901 (patch) | |
tree | 64b6892ddd16928d5a6e26395be31fc9e2179275 | |
parent | 1e4e1e12fb095c49f99e2448066dea704c4116e0 (diff) |
AudioInput: ensure our encoders are reset correctly when using > 1 frame per packet.
When AudioInput is configured to use more than a single frame per
packet, the "!bPreviousVoice"-check in encodeOpusFrame() and
encodeCELTFrame() is not sufficient in determining when to reset
the encoder.
This is because bPreviousVoice refers to the previous *frame*.
But when AudioInput is configured to use multiple frames per
packet, we won't enter encodeOpusFrame() at the initial frame
where bPreviousVoice would be false.
The result is that we *never* reset the current encoder
when using more than one frame per packet.
This change adds a flag, bResetEncoder, to the AudioInput class.
Now, When AudioInput encounters a frame that is speech, and the
previous frame was not (bIsSpeech && !bPreviousVoice), it will
set the bResetEncoder flag.
The encoder is now reset correctly when a new voice stream begins,
just like it is for the single frame-per-packet case.
[Backported from 23fa9b3979c244f1bcdbc80972a88ef7144f8f4a]
-rw-r--r-- | src/mumble/AudioInput.cpp | 16 | ||||
-rw-r--r-- | src/mumble/AudioInput.h | 5 |
2 files changed, 19 insertions, 2 deletions
diff --git a/src/mumble/AudioInput.cpp b/src/mumble/AudioInput.cpp index eb6bb59be..9fb2a068b 100644 --- a/src/mumble/AudioInput.cpp +++ b/src/mumble/AudioInput.cpp @@ -144,6 +144,8 @@ AudioInput::AudioInput() : opusBuffer(g.s.iFramesPerPacket * (SAMPLE_RATE / 100) bPreviousVoice = false; + bResetEncoder = true; + pfMicInput = pfEchoInput = pfOutput = NULL; iBitrate = 0; @@ -594,6 +596,8 @@ void AudioInput::resetAudioProcessor() { sesEcho = NULL; } + bResetEncoder = true; + bResetProcessor = false; } @@ -675,8 +679,10 @@ bool AudioInput::selectCodec() { int AudioInput::encodeOpusFrame(short *source, int size, unsigned char *buffer) { int len = 0; #ifdef USE_OPUS - if (!bPreviousVoice) + if (bResetEncoder) { opus_encoder_ctl(opusState, OPUS_RESET_STATE, NULL); + bResetEncoder = false; + } opus_encoder_ctl(opusState, OPUS_SET_BITRATE(iAudioQuality)); @@ -692,8 +698,10 @@ int AudioInput::encodeCELTFrame(short *psSource, unsigned char *buffer) { if (!cCodec) return len; - if (!bPreviousVoice) + if (bResetEncoder) { cCodec->celt_encoder_ctl(ceEncoder, CELT_RESET_STATE); + bResetEncoder = false; + } cCodec->celt_encoder_ctl(ceEncoder, CELT_SET_PREDICTION(0)); @@ -841,6 +849,10 @@ void AudioInput::encodeAudioFrame() { speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_SET_AGC_INCREMENT, &increment); } + if (bIsSpeech && !bPreviousVoice) { + bResetEncoder = true; + } + tIdle.restart(); unsigned char buffer[512]; diff --git a/src/mumble/AudioInput.h b/src/mumble/AudioInput.h index b6cce4169..80cb60374 100644 --- a/src/mumble/AudioInput.h +++ b/src/mumble/AudioInput.h @@ -122,6 +122,11 @@ class AudioInput : public QThread { CELTCodec *cCodec; CELTEncoder *ceEncoder; + /// bResetEncoder is a flag that notifies + /// our encoder functions that the encoder + /// needs to be reset. + bool bResetEncoder; + int iAudioQuality; int iAudioFrames; |