diff --git a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc index bf5cb58ee..82ca9eeb8 100644 --- a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc +++ b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.cc @@ -15,8 +15,7 @@ namespace webrtc { AudioEncoderCng::Config::Config() - : sample_rate_hz(8000), - num_channels(1), + : num_channels(1), payload_type(13), speech_encoder(NULL), vad_mode(Vad::kVadNormal), @@ -26,8 +25,6 @@ AudioEncoderCng::Config::Config() } bool AudioEncoderCng::Config::IsOk() const { - if (sample_rate_hz != 8000 && sample_rate_hz != 16000) - return false; if (num_channels != 1) return false; if (!speech_encoder) @@ -44,8 +41,6 @@ bool AudioEncoderCng::Config::IsOk() const { AudioEncoderCng::AudioEncoderCng(const Config& config) : speech_encoder_(config.speech_encoder), - sample_rate_hz_(config.sample_rate_hz), - num_channels_(config.num_channels), cng_payload_type_(config.payload_type), num_cng_coefficients_(config.num_cng_coefficients), first_timestamp_in_buffer_(0), @@ -60,7 +55,7 @@ AudioEncoderCng::AudioEncoderCng(const Config& config) CNG_enc_inst* cng_inst; CHECK_EQ(WebRtcCng_CreateEnc(&cng_inst), 0) << "WebRtcCng_CreateEnc failed."; cng_inst_.reset(cng_inst); // Transfer ownership to scoped_ptr. - CHECK_EQ(WebRtcCng_InitEnc(cng_inst_.get(), sample_rate_hz_, + CHECK_EQ(WebRtcCng_InitEnc(cng_inst_.get(), sample_rate_hz(), config.sid_frame_interval_ms, config.num_cng_coefficients), 0) @@ -71,7 +66,7 @@ AudioEncoderCng::~AudioEncoderCng() { } int AudioEncoderCng::sample_rate_hz() const { - return sample_rate_hz_; + return speech_encoder_->sample_rate_hz(); } int AudioEncoderCng::rtp_timestamp_rate_hz() const { @@ -79,7 +74,7 @@ int AudioEncoderCng::rtp_timestamp_rate_hz() const { } int AudioEncoderCng::num_channels() const { - return num_channels_; + return 1; } int AudioEncoderCng::Num10MsFramesInNextPacket() const { @@ -124,7 +119,7 @@ bool AudioEncoderCng::EncodeInternal(uint32_t rtp_timestamp, } CHECK_LE(frames_in_buffer_, 6) << "Frame size cannot be larger than 60 ms when using VAD/CNG."; - const size_t samples_per_10ms_frame = 10 * sample_rate_hz_ / 1000; + const size_t samples_per_10ms_frame = 10 * sample_rate_hz() / 1000; CHECK_EQ(speech_buffer_.size(), static_cast(frames_in_buffer_) * samples_per_10ms_frame); @@ -144,12 +139,12 @@ bool AudioEncoderCng::EncodeInternal(uint32_t rtp_timestamp, // block. Vad::Activity activity = vad_->VoiceActivity( &speech_buffer_[0], samples_per_10ms_frame * blocks_in_first_vad_call, - sample_rate_hz_); + sample_rate_hz()); if (activity == Vad::kPassive && blocks_in_second_vad_call > 0) { // Only check the second block if the first was passive. activity = vad_->VoiceActivity( &speech_buffer_[samples_per_10ms_frame * blocks_in_first_vad_call], - samples_per_10ms_frame * blocks_in_second_vad_call, sample_rate_hz_); + samples_per_10ms_frame * blocks_in_second_vad_call, sample_rate_hz()); } DCHECK_NE(activity, Vad::kError); @@ -181,7 +176,7 @@ bool AudioEncoderCng::EncodeInternal(uint32_t rtp_timestamp, bool AudioEncoderCng::EncodePassive(uint8_t* encoded, size_t* encoded_bytes) { bool force_sid = last_frame_active_; bool output_produced = false; - const size_t samples_per_10ms_frame = 10 * sample_rate_hz_ / 1000; + const size_t samples_per_10ms_frame = 10 * sample_rate_hz() / 1000; for (int i = 0; i < frames_in_buffer_; ++i) { int16_t encoded_bytes_tmp = 0; if (WebRtcCng_Encode(cng_inst_.get(), @@ -195,7 +190,6 @@ bool AudioEncoderCng::EncodePassive(uint8_t* encoded, size_t* encoded_bytes) { output_produced = true; force_sid = false; } - CHECK(!force_sid) << "SID frame not produced despite being forced."; } return true; } @@ -203,7 +197,7 @@ bool AudioEncoderCng::EncodePassive(uint8_t* encoded, size_t* encoded_bytes) { bool AudioEncoderCng::EncodeActive(size_t max_encoded_bytes, uint8_t* encoded, EncodedInfo* info) { - const size_t samples_per_10ms_frame = 10 * sample_rate_hz_ / 1000; + const size_t samples_per_10ms_frame = 10 * sample_rate_hz() / 1000; for (int i = 0; i < frames_in_buffer_; ++i) { if (!speech_encoder_->Encode(first_timestamp_in_buffer_, &speech_buffer_[i * samples_per_10ms_frame], diff --git a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc index 69c97d1c5..4338c56e5 100644 --- a/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc +++ b/webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng_unittest.cc @@ -34,7 +34,8 @@ class AudioEncoderCngTest : public ::testing::Test { AudioEncoderCngTest() : mock_vad_(new MockVad(Vad::kVadNormal)), timestamp_(4711), - num_audio_samples_10ms_(0) { + num_audio_samples_10ms_(0), + sample_rate_hz_(8000) { memset(encoded_, 0, kMaxEncodedBytes); memset(audio_, 0, kMaxNumSamples * 2); config_.speech_encoder = &mock_encoder_; @@ -57,10 +58,10 @@ class AudioEncoderCngTest : public ::testing::Test { void CreateCng() { // The config_ parameters may be changed by the TEST_Fs up until CreateCng() // is called, thus we cannot use the values until now. - num_audio_samples_10ms_ = 10 * config_.sample_rate_hz / 1000; + num_audio_samples_10ms_ = 10 * sample_rate_hz_ / 1000; ASSERT_LE(num_audio_samples_10ms_, kMaxNumSamples); EXPECT_CALL(mock_encoder_, sample_rate_hz()) - .WillRepeatedly(Return(config_.sample_rate_hz)); + .WillRepeatedly(Return(sample_rate_hz_)); // Max10MsFramesInAPacket() is just used to verify that the SID frame period // is not too small. The return value does not matter that much, as long as // it is smaller than 10. @@ -133,17 +134,16 @@ class AudioEncoderCngTest : public ::testing::Test { // Let the VAD decision be passive, since an active decision may lead to // early termination of the decision loop. - const int sample_rate_hz = config_.sample_rate_hz; InSequence s; EXPECT_CALL( *mock_vad_, - VoiceActivity(_, expected_first_block_size_ms * sample_rate_hz / 1000, - sample_rate_hz)).WillOnce(Return(Vad::kPassive)); + VoiceActivity(_, expected_first_block_size_ms * sample_rate_hz_ / 1000, + sample_rate_hz_)).WillOnce(Return(Vad::kPassive)); if (expected_second_block_size_ms > 0) { EXPECT_CALL(*mock_vad_, VoiceActivity( - _, expected_second_block_size_ms * sample_rate_hz / 1000, - sample_rate_hz)).WillOnce(Return(Vad::kPassive)); + _, expected_second_block_size_ms * sample_rate_hz_ / 1000, + sample_rate_hz_)).WillOnce(Return(Vad::kPassive)); } // With this call to Encode(), |mock_vad_| should be called according to the @@ -184,6 +184,7 @@ class AudioEncoderCngTest : public ::testing::Test { size_t num_audio_samples_10ms_; uint8_t encoded_[kMaxEncodedBytes]; AudioEncoder::EncodedInfo encoded_info_; + int sample_rate_hz_; }; TEST_F(AudioEncoderCngTest, CreateAndDestroy) { @@ -427,20 +428,6 @@ TEST_F(AudioEncoderCngDeathTest, WrongFrameSize) { EXPECT_DEATH(Encode(), ""); } -TEST_F(AudioEncoderCngDeathTest, WrongSampleRates) { - config_.sample_rate_hz = 32000; - EXPECT_DEATH(CreateCng(), "Invalid configuration"); - config_.sample_rate_hz = 48000; - EXPECT_DEATH(CreateCng(), "Invalid configuration"); - config_.sample_rate_hz = 0; - EXPECT_DEATH(CreateCng(), "Invalid configuration"); - config_.sample_rate_hz = -8000; - // Don't use CreateCng() here, since the built-in sanity checks will prevent - // the test from reaching the expected point-of-death. - EXPECT_DEATH(cng_.reset(new AudioEncoderCng(config_)), - "Invalid configuration"); -} - TEST_F(AudioEncoderCngDeathTest, WrongNumCoefficients) { config_.num_cng_coefficients = -1; EXPECT_DEATH(CreateCng(), "Invalid configuration"); diff --git a/webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h b/webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h index cdfa90d88..a9600044a 100644 --- a/webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h +++ b/webrtc/modules/audio_coding/codecs/cng/include/audio_encoder_cng.h @@ -22,13 +22,12 @@ namespace webrtc { class Vad; -class AudioEncoderCng : public AudioEncoder { +class AudioEncoderCng final : public AudioEncoder { public: struct Config { Config(); bool IsOk() const; - int sample_rate_hz; int num_channels; int payload_type; // Caller keeps ownership of the AudioEncoder object. @@ -76,8 +75,6 @@ class AudioEncoderCng : public AudioEncoder { EncodedInfo* info); AudioEncoder* speech_encoder_; - const int sample_rate_hz_; - const int num_channels_; const int cng_payload_type_; const int num_cng_coefficients_; std::vector speech_buffer_;