Minor updates to AudioEncoderCng

Removing sample_rate_hz_ from AudioEncoderCng and from the config
struct. The sample rate will now be read from the underlying speech
codec.

BUG=3926
COAUTHOR:kwiberg@webrtc.org

R=tina.legrand@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/40559004

Cr-Commit-Position: refs/heads/master@{#8173}
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8173 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
henrik.lundin@webrtc.org 2015-01-27 20:53:56 +00:00
parent db1ebf6c0c
commit 8bb32d600b
3 changed files with 19 additions and 41 deletions

View File

@ -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<size_t>(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],

View File

@ -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");

View File

@ -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<int16_t> speech_buffer_;