1ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org/* 2ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org * 4ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org * Use of this source code is governed by a BSD-style license 5ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org * that can be found in the LICENSE file in the root of the source 6ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org * tree. An additional intellectual property rights grant can be found 7ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org * in the file PATENTS. All contributing project authors may 8ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org */ 10ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 1151ccf376387266225cd8c78e63238b725860f0afjmarusic@webrtc.org#include <vector> 1251ccf376387266225cd8c78e63238b725860f0afjmarusic@webrtc.org 13ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org#include "testing/gtest/include/gtest/gtest.h" 1400b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org#include "webrtc/base/scoped_ptr.h" 15ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org#include "webrtc/common_audio/vad/mock/mock_vad.h" 163c652b67468d182bd36aee4c31557621be50cc92kjellander@webrtc.org#include "webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h" 17ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h" 18ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 19ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgusing ::testing::Return; 20ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgusing ::testing::_; 21ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgusing ::testing::SetArgPointee; 22ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgusing ::testing::InSequence; 233b79daff14127f3adb19b16d94336d44ff49e841henrik.lundin@webrtc.orgusing ::testing::Invoke; 24ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 25ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgnamespace webrtc { 26ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 27ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgnamespace { 2851ccf376387266225cd8c78e63238b725860f0afjmarusic@webrtc.orgstatic const size_t kMockMaxEncodedBytes = 1000; 29ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgstatic const size_t kMaxNumSamples = 48 * 10 * 2; // 10 ms @ 48 kHz stereo. 30ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgstatic const size_t kMockReturnEncodedBytes = 17; 31ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgstatic const int kCngPayloadType = 18; 32ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 33ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 34ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgclass AudioEncoderCngTest : public ::testing::Test { 35ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org protected: 36ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org AudioEncoderCngTest() 37e9e7896293747b2084e7f018675276f5096cdafckwiberg : mock_vad_(new MockVad), 38ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org timestamp_(4711), 398bb32d600b85b2d3b85598f43f009f82faad6006henrik.lundin@webrtc.org num_audio_samples_10ms_(0), 408bb32d600b85b2d3b85598f43f009f82faad6006henrik.lundin@webrtc.org sample_rate_hz_(8000) { 41ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org memset(audio_, 0, kMaxNumSamples * 2); 42ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org config_.speech_encoder = &mock_encoder_; 4305211277798ca4791fbdc508e24d7fd06d5ee6ffkwiberg@webrtc.org EXPECT_CALL(mock_encoder_, NumChannels()).WillRepeatedly(Return(1)); 44ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Let the AudioEncoderCng object use a MockVad instead of its internally 45ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // created Vad object. 46ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org config_.vad = mock_vad_; 47ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org config_.payload_type = kCngPayloadType; 48ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 49ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 5014665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void TearDown() override { 51ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, Die()).Times(1); 52ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org cng_.reset(); 53ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Don't expect the cng_ object to delete the AudioEncoder object. But it 54ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // will be deleted with the test fixture. This is why we explicitly delete 55ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // the cng_ object above, and set expectations on mock_encoder_ afterwards. 56ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(mock_encoder_, Die()).Times(1); 57ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 58ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 59ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org void CreateCng() { 60ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // The config_ parameters may be changed by the TEST_Fs up until CreateCng() 61ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // is called, thus we cannot use the values until now. 62dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting num_audio_samples_10ms_ = static_cast<size_t>(10 * sample_rate_hz_ / 1000); 63ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org ASSERT_LE(num_audio_samples_10ms_, kMaxNumSamples); 6405211277798ca4791fbdc508e24d7fd06d5ee6ffkwiberg@webrtc.org EXPECT_CALL(mock_encoder_, SampleRateHz()) 658bb32d600b85b2d3b85598f43f009f82faad6006henrik.lundin@webrtc.org .WillRepeatedly(Return(sample_rate_hz_)); 66ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Max10MsFramesInAPacket() is just used to verify that the SID frame period 67ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // is not too small. The return value does not matter that much, as long as 68ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // it is smaller than 10. 69dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting EXPECT_CALL(mock_encoder_, Max10MsFramesInAPacket()).WillOnce(Return(1u)); 7051ccf376387266225cd8c78e63238b725860f0afjmarusic@webrtc.org EXPECT_CALL(mock_encoder_, MaxEncodedBytes()) 7151ccf376387266225cd8c78e63238b725860f0afjmarusic@webrtc.org .WillRepeatedly(Return(kMockMaxEncodedBytes)); 72ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org cng_.reset(new AudioEncoderCng(config_)); 7351ccf376387266225cd8c78e63238b725860f0afjmarusic@webrtc.org encoded_.resize(cng_->MaxEncodedBytes(), 0); 74ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 75ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 76ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org void Encode() { 77ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org ASSERT_TRUE(cng_) << "Must call CreateCng() first."; 78288886b2ec9a2dac730f115e9c3079d8439efe60kwiberg encoded_info_ = cng_->Encode( 79288886b2ec9a2dac730f115e9c3079d8439efe60kwiberg timestamp_, 80288886b2ec9a2dac730f115e9c3079d8439efe60kwiberg rtc::ArrayView<const int16_t>(audio_, num_audio_samples_10ms_), 81288886b2ec9a2dac730f115e9c3079d8439efe60kwiberg encoded_.size(), &encoded_[0]); 82b7e5054414ff524f9db81dab7917729b8c4c8bcbPeter Kasting timestamp_ += static_cast<uint32_t>(num_audio_samples_10ms_); 83ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 84ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 85367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin // Expect |num_calls| calls to the encoder, all successful. The last call 86367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin // claims to have encoded |kMockMaxEncodedBytes| bytes, and all the preceding 87367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin // ones 0 bytes. 88dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting void ExpectEncodeCalls(size_t num_calls) { 89367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin InSequence s; 90367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin AudioEncoder::EncodedInfo info; 91dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting for (size_t j = 0; j < num_calls - 1; ++j) { 92367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _)) 93367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin .WillOnce(Return(info)); 94367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin } 95367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin info.encoded_bytes = kMockReturnEncodedBytes; 96367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _)) 97367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin .WillOnce(Return(info)); 98367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin } 99367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin 100ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Verifies that the cng_ object waits until it has collected 101ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // |blocks_per_frame| blocks of audio, and then dispatches all of them to 102ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // the underlying codec (speech or cng). 103dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting void CheckBlockGrouping(size_t blocks_per_frame, bool active_speech) { 104ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 105ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillRepeatedly(Return(blocks_per_frame)); 106ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 107ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 108ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillRepeatedly(Return(active_speech ? Vad::kActive : Vad::kPassive)); 109ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 110ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Don't expect any calls to the encoder yet. 1119afaee74ab1ef36c8b4ea4c22f4c5aebf2359da2jmarusic@webrtc.org EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _)).Times(0); 112dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting for (size_t i = 0; i < blocks_per_frame - 1; ++i) { 113ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 1143b79daff14127f3adb19b16d94336d44ff49e841henrik.lundin@webrtc.org EXPECT_EQ(0u, encoded_info_.encoded_bytes); 115ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 116367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin if (active_speech) 117367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin ExpectEncodeCalls(blocks_per_frame); 118ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 119ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org if (active_speech) { 1203b79daff14127f3adb19b16d94336d44ff49e841henrik.lundin@webrtc.org EXPECT_EQ(kMockReturnEncodedBytes, encoded_info_.encoded_bytes); 121ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } else { 122ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_EQ(static_cast<size_t>(config_.num_cng_coefficients + 1), 1233b79daff14127f3adb19b16d94336d44ff49e841henrik.lundin@webrtc.org encoded_info_.encoded_bytes); 124ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 125ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 126ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 127ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Verifies that the audio is partitioned into larger blocks before calling 128ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // the VAD. 129ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org void CheckVadInputSize(int input_frame_size_ms, 130ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org int expected_first_block_size_ms, 131ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org int expected_second_block_size_ms) { 132dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t blocks_per_frame = 133dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting static_cast<size_t>(input_frame_size_ms / 10); 134ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 135ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 136ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillRepeatedly(Return(blocks_per_frame)); 137ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 138ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Expect nothing to happen before the last block is sent to cng_. 139ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)).Times(0); 140dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting for (size_t i = 0; i < blocks_per_frame - 1; ++i) { 141ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 142ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 143ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 144ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Let the VAD decision be passive, since an active decision may lead to 145ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // early termination of the decision loop. 146ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org InSequence s; 147ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL( 148ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org *mock_vad_, 1498bb32d600b85b2d3b85598f43f009f82faad6006henrik.lundin@webrtc.org VoiceActivity(_, expected_first_block_size_ms * sample_rate_hz_ / 1000, 1508bb32d600b85b2d3b85598f43f009f82faad6006henrik.lundin@webrtc.org sample_rate_hz_)).WillOnce(Return(Vad::kPassive)); 151ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org if (expected_second_block_size_ms > 0) { 152ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, 153ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org VoiceActivity( 1548bb32d600b85b2d3b85598f43f009f82faad6006henrik.lundin@webrtc.org _, expected_second_block_size_ms * sample_rate_hz_ / 1000, 1558bb32d600b85b2d3b85598f43f009f82faad6006henrik.lundin@webrtc.org sample_rate_hz_)).WillOnce(Return(Vad::kPassive)); 156ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 157ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 158ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // With this call to Encode(), |mock_vad_| should be called according to the 159ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // above expectations. 160ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 161ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 162ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 163ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Tests a frame with both active and passive speech. Returns true if the 164ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // decision was active speech, false if it was passive. 165ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org bool CheckMixedActivePassive(Vad::Activity first_type, 166ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Vad::Activity second_type) { 167ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Set the speech encoder frame size to 60 ms, to ensure that the VAD will 168ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // be called twice. 169dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t blocks_per_frame = 6; 170ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 171ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillRepeatedly(Return(blocks_per_frame)); 172ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org InSequence s; 173ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 174ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillOnce(Return(first_type)); 175ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org if (first_type == Vad::kPassive) { 176ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Expect a second call to the VAD only if the first frame was passive. 177ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 178ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillOnce(Return(second_type)); 179ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 180ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org encoded_info_.payload_type = 0; 181dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting for (size_t i = 0; i < blocks_per_frame; ++i) { 182ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 183ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 184ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org return encoded_info_.payload_type != kCngPayloadType; 185ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 186ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 187ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org AudioEncoderCng::Config config_; 18800b8f6b3643332cce1ee711715f7fbb824d793cakwiberg@webrtc.org rtc::scoped_ptr<AudioEncoderCng> cng_; 189ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org MockAudioEncoder mock_encoder_; 190ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org MockVad* mock_vad_; // Ownership is transferred to |cng_|. 191ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org uint32_t timestamp_; 192ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org int16_t audio_[kMaxNumSamples]; 193ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org size_t num_audio_samples_10ms_; 19451ccf376387266225cd8c78e63238b725860f0afjmarusic@webrtc.org std::vector<uint8_t> encoded_; 195ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org AudioEncoder::EncodedInfo encoded_info_; 1968bb32d600b85b2d3b85598f43f009f82faad6006henrik.lundin@webrtc.org int sample_rate_hz_; 197ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org}; 198ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 199ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, CreateAndDestroy) { 200ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 201ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 202ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 203ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, CheckFrameSizePropagation) { 204ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 205dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()).WillOnce(Return(17U)); 206dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting EXPECT_EQ(17U, cng_->Num10MsFramesInNextPacket()); 207ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 208ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 209478cedc055f95bd160b53a4d7b69d8b3dd023ec7henrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, CheckChangeBitratePropagation) { 210478cedc055f95bd160b53a4d7b69d8b3dd023ec7henrik.lundin@webrtc.org CreateCng(); 211478cedc055f95bd160b53a4d7b69d8b3dd023ec7henrik.lundin@webrtc.org EXPECT_CALL(mock_encoder_, SetTargetBitrate(4711)); 212478cedc055f95bd160b53a4d7b69d8b3dd023ec7henrik.lundin@webrtc.org cng_->SetTargetBitrate(4711); 213478cedc055f95bd160b53a4d7b69d8b3dd023ec7henrik.lundin@webrtc.org} 214478cedc055f95bd160b53a4d7b69d8b3dd023ec7henrik.lundin@webrtc.org 215478cedc055f95bd160b53a4d7b69d8b3dd023ec7henrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, CheckProjectedPacketLossRatePropagation) { 216478cedc055f95bd160b53a4d7b69d8b3dd023ec7henrik.lundin@webrtc.org CreateCng(); 217478cedc055f95bd160b53a4d7b69d8b3dd023ec7henrik.lundin@webrtc.org EXPECT_CALL(mock_encoder_, SetProjectedPacketLossRate(0.5)); 218478cedc055f95bd160b53a4d7b69d8b3dd023ec7henrik.lundin@webrtc.org cng_->SetProjectedPacketLossRate(0.5); 219478cedc055f95bd160b53a4d7b69d8b3dd023ec7henrik.lundin@webrtc.org} 220478cedc055f95bd160b53a4d7b69d8b3dd023ec7henrik.lundin@webrtc.org 221ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, EncodeCallsVad) { 222ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 223dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting .WillRepeatedly(Return(1U)); 224ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 225ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 226ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillOnce(Return(Vad::kPassive)); 227ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 228ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 229ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 230ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, EncodeCollects1BlockPassiveSpeech) { 231ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CheckBlockGrouping(1, false); 232ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 233ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 234ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, EncodeCollects2BlocksPassiveSpeech) { 235ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CheckBlockGrouping(2, false); 236ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 237ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 238ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, EncodeCollects3BlocksPassiveSpeech) { 239ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CheckBlockGrouping(3, false); 240ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 241ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 242ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, EncodeCollects1BlockActiveSpeech) { 243ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CheckBlockGrouping(1, true); 244ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 245ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 246ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, EncodeCollects2BlocksActiveSpeech) { 247ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CheckBlockGrouping(2, true); 248ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 249ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 250ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, EncodeCollects3BlocksActiveSpeech) { 251ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CheckBlockGrouping(3, true); 252ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 253ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 254ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, EncodePassive) { 255dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting const size_t kBlocksPerFrame = 3; 256ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 257ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillRepeatedly(Return(kBlocksPerFrame)); 258ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 259ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 260ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillRepeatedly(Return(Vad::kPassive)); 261ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Expect no calls at all to the speech encoder mock. 2629afaee74ab1ef36c8b4ea4c22f4c5aebf2359da2jmarusic@webrtc.org EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _)).Times(0); 263ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org uint32_t expected_timestamp = timestamp_; 264dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting for (size_t i = 0; i < 100; ++i) { 265ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 266ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Check if it was time to call the cng encoder. This is done once every 267ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // |kBlocksPerFrame| calls. 268ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org if ((i + 1) % kBlocksPerFrame == 0) { 269ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Now check if a SID interval has elapsed. 270ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org if ((i % (config_.sid_frame_interval_ms / 10)) < kBlocksPerFrame) { 271ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // If so, verify that we got a CNG encoding. 272ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_EQ(kCngPayloadType, encoded_info_.payload_type); 273c86bbbaa9348b868e94c021426abcc2f5e0144b0henrik.lundin@webrtc.org EXPECT_FALSE(encoded_info_.speech); 274ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_EQ(static_cast<size_t>(config_.num_cng_coefficients) + 1, 2753b79daff14127f3adb19b16d94336d44ff49e841henrik.lundin@webrtc.org encoded_info_.encoded_bytes); 276ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_EQ(expected_timestamp, encoded_info_.encoded_timestamp); 277ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 278ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org expected_timestamp += kBlocksPerFrame * num_audio_samples_10ms_; 279ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } else { 280ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Otherwise, expect no output. 2813b79daff14127f3adb19b16d94336d44ff49e841henrik.lundin@webrtc.org EXPECT_EQ(0u, encoded_info_.encoded_bytes); 282ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 283ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 284ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 285ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 286ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org// Verifies that the correct action is taken for frames with both active and 287ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org// passive speech. 288ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, MixedActivePassive) { 289ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 290ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 291ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // All of the frame is active speech. 292367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin ExpectEncodeCalls(6); 293ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_TRUE(CheckMixedActivePassive(Vad::kActive, Vad::kActive)); 294c86bbbaa9348b868e94c021426abcc2f5e0144b0henrik.lundin@webrtc.org EXPECT_TRUE(encoded_info_.speech); 295ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 296ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // First half of the frame is active speech. 297367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin ExpectEncodeCalls(6); 298ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_TRUE(CheckMixedActivePassive(Vad::kActive, Vad::kPassive)); 299c86bbbaa9348b868e94c021426abcc2f5e0144b0henrik.lundin@webrtc.org EXPECT_TRUE(encoded_info_.speech); 300ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 301ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Second half of the frame is active speech. 302367c868c998e96bc1aac41b607548d6125fa6b1eHenrik Lundin ExpectEncodeCalls(6); 303ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_TRUE(CheckMixedActivePassive(Vad::kPassive, Vad::kActive)); 304c86bbbaa9348b868e94c021426abcc2f5e0144b0henrik.lundin@webrtc.org EXPECT_TRUE(encoded_info_.speech); 305ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 306ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // All of the frame is passive speech. Expect no calls to |mock_encoder_|. 307ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_FALSE(CheckMixedActivePassive(Vad::kPassive, Vad::kPassive)); 308c86bbbaa9348b868e94c021426abcc2f5e0144b0henrik.lundin@webrtc.org EXPECT_FALSE(encoded_info_.speech); 309ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 310ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 311ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org// These tests verify that the audio is partitioned into larger blocks before 312ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org// calling the VAD. 313ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org// The parameters for CheckVadInputSize are: 314ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org// CheckVadInputSize(frame_size, expected_first_block_size, 315ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org// expected_second_block_size); 316ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, VadInputSize10Ms) { 317ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 318ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CheckVadInputSize(10, 10, 0); 319ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 320ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, VadInputSize20Ms) { 321ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 322ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CheckVadInputSize(20, 20, 0); 323ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 324ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, VadInputSize30Ms) { 325ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 326ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CheckVadInputSize(30, 30, 0); 327ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 328ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, VadInputSize40Ms) { 329ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 330ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CheckVadInputSize(40, 20, 20); 331ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 332ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, VadInputSize50Ms) { 333ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 334ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CheckVadInputSize(50, 30, 20); 335ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 336ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, VadInputSize60Ms) { 337ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 338ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CheckVadInputSize(60, 30, 30); 339ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 340ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 341ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org// Verifies that the correct payload type is set when CNG is encoded. 342ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, VerifyCngPayloadType) { 343ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 3449afaee74ab1ef36c8b4ea4c22f4c5aebf2359da2jmarusic@webrtc.org EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _)).Times(0); 345dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()).WillOnce(Return(1U)); 346ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 347ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillOnce(Return(Vad::kPassive)); 348ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org encoded_info_.payload_type = 0; 349ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 350ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_EQ(kCngPayloadType, encoded_info_.payload_type); 351ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 352ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 353ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org// Verifies that a SID frame is encoded immediately as the signal changes from 354ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org// active speech to passive. 355ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngTest, VerifySidFrameAfterSpeech) { 356ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 357ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 358dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting .WillRepeatedly(Return(1U)); 359ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Start with encoding noise. 360ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 361ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .Times(2) 362ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillRepeatedly(Return(Vad::kPassive)); 363ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 364ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_EQ(kCngPayloadType, encoded_info_.payload_type); 365ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_EQ(static_cast<size_t>(config_.num_cng_coefficients) + 1, 3663b79daff14127f3adb19b16d94336d44ff49e841henrik.lundin@webrtc.org encoded_info_.encoded_bytes); 367ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Encode again, and make sure we got no frame at all (since the SID frame 368ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // period is 100 ms by default). 369ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 3703b79daff14127f3adb19b16d94336d44ff49e841henrik.lundin@webrtc.org EXPECT_EQ(0u, encoded_info_.encoded_bytes); 371ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 372ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Now encode active speech. 373ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org encoded_info_.payload_type = 0; 374ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 375ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillOnce(Return(Vad::kActive)); 3763b79daff14127f3adb19b16d94336d44ff49e841henrik.lundin@webrtc.org AudioEncoder::EncodedInfo info; 3773b79daff14127f3adb19b16d94336d44ff49e841henrik.lundin@webrtc.org info.encoded_bytes = kMockReturnEncodedBytes; 3789afaee74ab1ef36c8b4ea4c22f4c5aebf2359da2jmarusic@webrtc.org EXPECT_CALL(mock_encoder_, EncodeInternal(_, _, _, _)).WillOnce(Return(info)); 379ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 3803b79daff14127f3adb19b16d94336d44ff49e841henrik.lundin@webrtc.org EXPECT_EQ(kMockReturnEncodedBytes, encoded_info_.encoded_bytes); 381ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 382ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Go back to noise again, and verify that a SID frame is emitted. 383ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, VoiceActivity(_, _, _)) 384ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org .WillOnce(Return(Vad::kPassive)); 385ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 386ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_EQ(kCngPayloadType, encoded_info_.payload_type); 387ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_EQ(static_cast<size_t>(config_.num_cng_coefficients) + 1, 3883b79daff14127f3adb19b16d94336d44ff49e841henrik.lundin@webrtc.org encoded_info_.encoded_bytes); 389ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 390ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 39112cfc9b4dacd6942377df1f29a64bdbec591920ekwiberg// Resetting the CNG should reset both the VAD and the encoder. 39212cfc9b4dacd6942377df1f29a64bdbec591920ekwibergTEST_F(AudioEncoderCngTest, Reset) { 39312cfc9b4dacd6942377df1f29a64bdbec591920ekwiberg CreateCng(); 39412cfc9b4dacd6942377df1f29a64bdbec591920ekwiberg EXPECT_CALL(mock_encoder_, Reset()).Times(1); 39512cfc9b4dacd6942377df1f29a64bdbec591920ekwiberg EXPECT_CALL(*mock_vad_, Reset()).Times(1); 39612cfc9b4dacd6942377df1f29a64bdbec591920ekwiberg cng_->Reset(); 39712cfc9b4dacd6942377df1f29a64bdbec591920ekwiberg} 39812cfc9b4dacd6942377df1f29a64bdbec591920ekwiberg 399ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) 400ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 401ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org// This test fixture tests various error conditions that makes the 402ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org// AudioEncoderCng die via CHECKs. 403ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgclass AudioEncoderCngDeathTest : public AudioEncoderCngTest { 404ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org protected: 405ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org AudioEncoderCngDeathTest() : AudioEncoderCngTest() { 406ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Don't provide a Vad mock object, since it will leak when the test dies. 407ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org config_.vad = NULL; 408ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(*mock_vad_, Die()).Times(1); 409ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org delete mock_vad_; 410ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org mock_vad_ = NULL; 411ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 412ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 413ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Override AudioEncoderCngTest::TearDown, since that one expects a call to 414ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // the destructor of |mock_vad_|. In this case, that object is already 415ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // deleted. 41614665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void TearDown() override { 417ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org cng_.reset(); 418ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // Don't expect the cng_ object to delete the AudioEncoder object. But it 419ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // will be deleted with the test fixture. This is why we explicitly delete 420ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org // the cng_ object above, and set expectations on mock_encoder_ afterwards. 421ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(mock_encoder_, Die()).Times(1); 422ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org } 423ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org}; 424ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 425ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngDeathTest, WrongFrameSize) { 426ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 427ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org num_audio_samples_10ms_ *= 2; // 20 ms frame. 428ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_DEATH(Encode(), ""); 429ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org num_audio_samples_10ms_ = 0; // Zero samples. 430ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_DEATH(Encode(), ""); 431ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 432ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 433ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngDeathTest, WrongNumCoefficients) { 434ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org config_.num_cng_coefficients = -1; 435ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_DEATH(CreateCng(), "Invalid configuration"); 436ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org config_.num_cng_coefficients = 0; 437ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_DEATH(CreateCng(), "Invalid configuration"); 438ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org config_.num_cng_coefficients = 13; 439ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_DEATH(CreateCng(), "Invalid configuration"); 440ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 441ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 442ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngDeathTest, NullSpeechEncoder) { 443ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org config_.speech_encoder = NULL; 444ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_DEATH(CreateCng(), "Invalid configuration"); 445ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 446ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 447ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngDeathTest, Stereo) { 44805211277798ca4791fbdc508e24d7fd06d5ee6ffkwiberg@webrtc.org EXPECT_CALL(mock_encoder_, NumChannels()).WillRepeatedly(Return(2)); 449ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_DEATH(CreateCng(), "Invalid configuration"); 450ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org config_.num_channels = 2; 451ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_DEATH(CreateCng(), "Invalid configuration"); 452ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 453ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 454ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.orgTEST_F(AudioEncoderCngDeathTest, EncoderFrameSizeTooLarge) { 455ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org CreateCng(); 456ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_CALL(mock_encoder_, Num10MsFramesInNextPacket()) 457dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting .WillRepeatedly(Return(7U)); 458ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org for (int i = 0; i < 6; ++i) 459ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org Encode(); 460ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org EXPECT_DEATH(Encode(), 461ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org "Frame size cannot be larger than 60 ms when using VAD/CNG."); 462ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} 463ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 464ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org#endif // GTEST_HAS_DEATH_TEST 465ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org 466ff1a3e36bdd023fc2d3bef9af6b161ce144ffd6bhenrik.lundin@webrtc.org} // namespace webrtc 467