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:
parent
db1ebf6c0c
commit
8bb32d600b
@ -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],
|
||||
|
@ -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");
|
||||
|
@ -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_;
|
||||
|
Loading…
Reference in New Issue
Block a user