From 1431e4dd1c0870971afde9456702d4b76aca3324 Mon Sep 17 00:00:00 2001 From: "turaj@webrtc.org" Date: Tue, 11 Nov 2014 01:44:13 +0000 Subject: [PATCH] Revert 7675 "Make an AudioEncoder subclass for iSAC" Above CL did not compile on Android. Followings are links to Android builds http://chromegw.corp.google.com/i/internal.client.webrtc/builders/Android%20Builder%20%28dbg%29/builds/2648 http://chromegw.corp.google.com/i/internal.client.webrtc/builders/Android%20Clang%20%28dbg%29/builds/2369 http://chromegw.corp.google.com/i/internal.client.webrtc/builders/Android%20ARM64%20%28dbg%29/builds/1320 > Make an AudioEncoder subclass for iSAC > > BUG=3926 > R=henrik.lundin@webrtc.org, kjellander@webrtc.org > > Review URL: https://webrtc-codereview.appspot.com/25019004 TBR=kwiberg@webrtc.org Review URL: https://webrtc-codereview.appspot.com/32439004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@7676 4adac7df-926f-26a2-2b94-8c16560cd09d --- webrtc/modules/audio_coding/BUILD.gn | 8 - .../isac/main/interface/audio_encoder_isac.h | 106 ---------- .../isac/main/source/audio_encoder_isac.cc | 188 ------------------ .../codecs/isac/main/source/isac.gypi | 2 - .../audio_coding/neteq/audio_decoder.cc | 15 +- .../audio_coding/neteq/audio_decoder_impl.cc | 61 ++++++ .../audio_coding/neteq/audio_decoder_impl.h | 25 +++ .../neteq/audio_decoder_unittest.cc | 78 ++++++-- 8 files changed, 149 insertions(+), 334 deletions(-) delete mode 100644 webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h delete mode 100644 webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc diff --git a/webrtc/modules/audio_coding/BUILD.gn b/webrtc/modules/audio_coding/BUILD.gn index cf5901acd7..547f15f0b1 100644 --- a/webrtc/modules/audio_coding/BUILD.gn +++ b/webrtc/modules/audio_coding/BUILD.gn @@ -356,13 +356,11 @@ config("isac_config") { source_set("isac") { sources = [ - "codecs/isac/main/interface/audio_encoder_isac.h", "codecs/isac/main/interface/isac.h", "codecs/isac/main/source/arith_routines.c", "codecs/isac/main/source/arith_routines.h", "codecs/isac/main/source/arith_routines_hist.c", "codecs/isac/main/source/arith_routines_logist.c", - "codecs/isac/main/source/audio_encoder_isac.cc", "codecs/isac/main/source/bandwidth_estimator.c", "codecs/isac/main/source/bandwidth_estimator.h", "codecs/isac/main/source/codec.h", @@ -409,12 +407,6 @@ source_set("isac") { "codecs/isac/main/source/transform.c", ] - if (is_clang) { - # Suppress warnings from Chrome's Clang plugins. - # See http://code.google.com/p/webrtc/issues/detail?id=163 for details. - configs -= [ "//build/config/clang:find_bad_constructs" ] - } - if (is_linux) { libs = [ "m" ] } diff --git a/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h b/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h deleted file mode 100644 index 11522c53cb..0000000000 --- a/webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_INTERFACE_AUDIO_ENCODER_ISAC_H_ -#define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_INTERFACE_AUDIO_ENCODER_ISAC_H_ - -#include - -#include "webrtc/base/thread_annotations.h" -#include "webrtc/modules/audio_coding/codecs/audio_encoder.h" -#include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h" -#include "webrtc/modules/audio_coding/neteq/interface/audio_decoder.h" -#include "webrtc/system_wrappers/interface/scoped_ptr.h" - -namespace webrtc { - -class CriticalSectionWrapper; - -class AudioEncoderDecoderIsac : public AudioEncoder, public AudioDecoder { - public: - // For constructing an encoder in instantaneous mode. Allowed combinations - // are - // - 16000 Hz, 30 ms, 10000-32000 bps - // - 16000 Hz, 60 ms, 10000-32000 bps - // - 32000 Hz, 30 ms, 10000-56000 bps - struct Config { - Config(); - bool IsOk() const; - int sample_rate_hz; - int frame_size_ms; - int bit_rate; // Limit on the short-term average bit rate, in bits/second. - }; - - // For constructing an encoder in channel-adaptive mode. The sample rate must - // be 16000 Hz; the initial frame size can be 30 or 60 ms; and the initial bit - // rate can be 10000-56000 bps. - struct ConfigAdaptive { - ConfigAdaptive(); - bool IsOk() const; - int sample_rate_hz; - int initial_frame_size_ms; - int initial_bit_rate; - bool enforce_frame_size; // Prevent adaptive changes to the frame size? - }; - - explicit AudioEncoderDecoderIsac(const Config& config); - explicit AudioEncoderDecoderIsac(const ConfigAdaptive& config); - virtual ~AudioEncoderDecoderIsac() OVERRIDE; - - // AudioEncoder public methods. - virtual int sample_rate_hz() const OVERRIDE; - virtual int num_channels() const OVERRIDE; - virtual int Num10MsFramesInNextPacket() const OVERRIDE; - - // AudioDecoder methods. - virtual int Decode(const uint8_t* encoded, - size_t encoded_len, - int16_t* decoded, - SpeechType* speech_type) OVERRIDE; - virtual int DecodeRedundant(const uint8_t* encoded, - size_t encoded_len, - int16_t* decoded, - SpeechType* speech_type) OVERRIDE; - virtual bool HasDecodePlc() const OVERRIDE; - virtual int DecodePlc(int num_frames, int16_t* decoded) OVERRIDE; - virtual int Init() OVERRIDE; - virtual int IncomingPacket(const uint8_t* payload, - size_t payload_len, - uint16_t rtp_sequence_number, - uint32_t rtp_timestamp, - uint32_t arrival_timestamp) OVERRIDE; - virtual int ErrorCode() OVERRIDE; - - protected: - // AudioEncoder protected method. - virtual bool Encode(uint32_t timestamp, - const int16_t* audio, - size_t max_encoded_bytes, - uint8_t* encoded, - size_t* encoded_bytes, - uint32_t* encoded_timestamp) OVERRIDE; - - private: - // iSAC encoder/decoder state, guarded by a mutex to ensure that encode calls - // from one thread won't clash with decode calls from another thread. - const scoped_ptr lock_; - ISACStruct* isac_state_ GUARDED_BY(lock_); - - // Have we accepted input but not yet emitted it in a packet? - bool packet_in_progress_; - - // Timestamp of the first input of the currently in-progress packet. - uint32_t packet_timestamp_; - - DISALLOW_COPY_AND_ASSIGN(AudioEncoderDecoderIsac); -}; - -} // namespace webrtc -#endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_MAIN_INTERFACE_AUDIO_ENCODER_ISAC_H_ diff --git a/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc b/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc deleted file mode 100644 index 3e2f8656ac..0000000000 --- a/webrtc/modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h" - -#include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h" -#include "webrtc/system_wrappers/interface/critical_section_wrapper.h" - -namespace webrtc { - -namespace { - -int DivExact(int a, int b) { - CHECK_EQ(a % b, 0); - return a / b; -} - -} // namespace - -AudioEncoderDecoderIsac::Config::Config() - : sample_rate_hz(16000), frame_size_ms(30), bit_rate(32000) {} - -bool AudioEncoderDecoderIsac::Config::IsOk() const { - switch (sample_rate_hz) { - case 16000: - return (frame_size_ms == 30 || frame_size_ms == 60) && - bit_rate >= 10000 && bit_rate <= 32000; - case 32000: - return frame_size_ms == 30 && bit_rate >= 10000 && bit_rate <= 56000; - default: - return false; - } -} - -AudioEncoderDecoderIsac::ConfigAdaptive::ConfigAdaptive() - : sample_rate_hz(16000), - initial_frame_size_ms(30), - initial_bit_rate(32000), - enforce_frame_size(false) {} - -bool AudioEncoderDecoderIsac::ConfigAdaptive::IsOk() const { - return sample_rate_hz == 16000 && - (initial_frame_size_ms == 30 || initial_frame_size_ms == 60) && - initial_bit_rate >= 10000 && initial_bit_rate <= 56000; -} - -AudioEncoderDecoderIsac::AudioEncoderDecoderIsac(const Config& config) - : lock_(CriticalSectionWrapper::CreateCriticalSection()), - packet_in_progress_(false) { - CHECK(config.IsOk()); - CHECK_EQ(0, WebRtcIsac_Create(&isac_state_)); - CHECK_EQ(0, WebRtcIsac_EncoderInit(isac_state_, 1)); - CHECK_EQ(0, WebRtcIsac_SetEncSampRate(isac_state_, config.sample_rate_hz)); - CHECK_EQ(0, WebRtcIsac_Control(isac_state_, config.bit_rate, - config.frame_size_ms)); - CHECK_EQ(0, WebRtcIsac_SetDecSampRate(isac_state_, config.sample_rate_hz)); -} - -AudioEncoderDecoderIsac::AudioEncoderDecoderIsac(const ConfigAdaptive& config) - : lock_(CriticalSectionWrapper::CreateCriticalSection()), - packet_in_progress_(false) { - CHECK(config.IsOk()); - CHECK_EQ(0, WebRtcIsac_Create(&isac_state_)); - CHECK_EQ(0, WebRtcIsac_EncoderInit(isac_state_, 0)); - CHECK_EQ(0, WebRtcIsac_SetEncSampRate(isac_state_, config.sample_rate_hz)); - CHECK_EQ(0, WebRtcIsac_ControlBwe(isac_state_, config.initial_bit_rate, - config.initial_frame_size_ms, - config.enforce_frame_size)); - CHECK_EQ(0, WebRtcIsac_SetDecSampRate(isac_state_, config.sample_rate_hz)); -} - -AudioEncoderDecoderIsac::~AudioEncoderDecoderIsac() { - CHECK_EQ(0, WebRtcIsac_Free(isac_state_)); -} - -int AudioEncoderDecoderIsac::sample_rate_hz() const { - CriticalSectionScoped cs(lock_.get()); - return WebRtcIsac_EncSampRate(isac_state_); -} - -int AudioEncoderDecoderIsac::num_channels() const { - return 1; -} - -int AudioEncoderDecoderIsac::Num10MsFramesInNextPacket() const { - CriticalSectionScoped cs(lock_.get()); - int samples_in_next_packet = WebRtcIsac_GetNewFrameLen(isac_state_); - return DivExact(samples_in_next_packet, DivExact(sample_rate_hz(), 100)); -} - -bool AudioEncoderDecoderIsac::Encode(uint32_t timestamp, - const int16_t* audio, - size_t max_encoded_bytes, - uint8_t* encoded, - size_t* encoded_bytes, - uint32_t* encoded_timestamp) { - if (!packet_in_progress_) { - // Starting a new packet; remember the timestamp for later. - packet_in_progress_ = true; - packet_timestamp_ = timestamp; - } - int r; - { - CriticalSectionScoped cs(lock_.get()); - r = WebRtcIsac_Encode(isac_state_, audio, encoded); - } - if (r < 0) { - // An error occurred; propagate it to the caller. - packet_in_progress_ = false; - return false; - } - - // WebRtcIsac_Encode doesn't allow us to tell it the size of the output - // buffer. All we can do is check for an overrun after the fact. - CHECK(static_cast(r) <= max_encoded_bytes); - - *encoded_bytes = r; - if (r > 0) { - // Got enough input to produce a packet. Return the saved timestamp from - // the first chunk of input that went into the packet. - packet_in_progress_ = false; - *encoded_timestamp = packet_timestamp_; - } - return true; -} - -int AudioEncoderDecoderIsac::Decode(const uint8_t* encoded, - size_t encoded_len, - int16_t* decoded, - SpeechType* speech_type) { - CriticalSectionScoped cs(lock_.get()); - int16_t temp_type = 1; // Default is speech. - int16_t ret = - WebRtcIsac_Decode(isac_state_, encoded, static_cast(encoded_len), - decoded, &temp_type); - *speech_type = ConvertSpeechType(temp_type); - return ret; -} - -int AudioEncoderDecoderIsac::DecodeRedundant(const uint8_t* encoded, - size_t encoded_len, - int16_t* decoded, - SpeechType* speech_type) { - CriticalSectionScoped cs(lock_.get()); - int16_t temp_type = 1; // Default is speech. - int16_t ret = WebRtcIsac_DecodeRcu(isac_state_, encoded, - static_cast(encoded_len), decoded, - &temp_type); - *speech_type = ConvertSpeechType(temp_type); - return ret; -} - -bool AudioEncoderDecoderIsac::HasDecodePlc() const { return true; } - -int AudioEncoderDecoderIsac::DecodePlc(int num_frames, int16_t* decoded) { - CriticalSectionScoped cs(lock_.get()); - return WebRtcIsac_DecodePlc(isac_state_, decoded, num_frames); -} - -int AudioEncoderDecoderIsac::Init() { - CriticalSectionScoped cs(lock_.get()); - return WebRtcIsac_DecoderInit(isac_state_); -} - -int AudioEncoderDecoderIsac::IncomingPacket(const uint8_t* payload, - size_t payload_len, - uint16_t rtp_sequence_number, - uint32_t rtp_timestamp, - uint32_t arrival_timestamp) { - CriticalSectionScoped cs(lock_.get()); - return WebRtcIsac_UpdateBwEstimate( - isac_state_, payload, static_cast(payload_len), - rtp_sequence_number, rtp_timestamp, arrival_timestamp); -} - -int AudioEncoderDecoderIsac::ErrorCode() { - CriticalSectionScoped cs(lock_.get()); - return WebRtcIsac_GetErrorCode(isac_state_); -} - -} // namespace webrtc diff --git a/webrtc/modules/audio_coding/codecs/isac/main/source/isac.gypi b/webrtc/modules/audio_coding/codecs/isac/main/source/isac.gypi index 282920f707..5ed6d448bb 100644 --- a/webrtc/modules/audio_coding/codecs/isac/main/source/isac.gypi +++ b/webrtc/modules/audio_coding/codecs/isac/main/source/isac.gypi @@ -25,12 +25,10 @@ ], }, 'sources': [ - '../interface/audio_encoder_isac.h', '../interface/isac.h', 'arith_routines.c', 'arith_routines_hist.c', 'arith_routines_logist.c', - 'audio_encoder_isac.cc', 'bandwidth_estimator.c', 'crc.c', 'decode.c', diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder.cc b/webrtc/modules/audio_coding/neteq/audio_decoder.cc index ac4dd523a5..d5a2762846 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder.cc +++ b/webrtc/modules/audio_coding/neteq/audio_decoder.cc @@ -13,7 +13,6 @@ #include #include "webrtc/base/checks.h" -#include "webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h" #include "webrtc/modules/audio_coding/neteq/audio_decoder_impl.h" namespace webrtc { @@ -201,17 +200,11 @@ AudioDecoder* AudioDecoder::CreateAudioDecoder(NetEqDecoder codec_type) { case kDecoderISAC: return new AudioDecoderIsacFix; #elif defined(WEBRTC_CODEC_ISAC) - case kDecoderISAC: { - AudioEncoderDecoderIsac::Config config; - config.sample_rate_hz = 16000; - return new AudioEncoderDecoderIsac(config); - } + case kDecoderISAC: + return new AudioDecoderIsac(16000); case kDecoderISACswb: - case kDecoderISACfb: { - AudioEncoderDecoderIsac::Config config; - config.sample_rate_hz = 32000; - return new AudioEncoderDecoderIsac(config); - } + case kDecoderISACfb: + return new AudioDecoderIsac(32000); #endif #ifdef WEBRTC_CODEC_PCM16 case kDecoderPCM16B: diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc index 76468e3efa..eb07823446 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.cc @@ -130,6 +130,67 @@ int AudioDecoderIlbc::Init() { } #endif +// iSAC float +#ifdef WEBRTC_CODEC_ISAC +AudioDecoderIsac::AudioDecoderIsac(int decode_sample_rate_hz) { + DCHECK(decode_sample_rate_hz == 16000 || decode_sample_rate_hz == 32000); + WebRtcIsac_Create(&isac_state_); + WebRtcIsac_SetDecSampRate(isac_state_, decode_sample_rate_hz); +} + +AudioDecoderIsac::~AudioDecoderIsac() { + WebRtcIsac_Free(isac_state_); +} + +int AudioDecoderIsac::Decode(const uint8_t* encoded, size_t encoded_len, + int16_t* decoded, SpeechType* speech_type) { + int16_t temp_type = 1; // Default is speech. + int16_t ret = WebRtcIsac_Decode(isac_state_, + encoded, + static_cast(encoded_len), decoded, + &temp_type); + *speech_type = ConvertSpeechType(temp_type); + return ret; +} + +int AudioDecoderIsac::DecodeRedundant(const uint8_t* encoded, + size_t encoded_len, int16_t* decoded, + SpeechType* speech_type) { + int16_t temp_type = 1; // Default is speech. + int16_t ret = WebRtcIsac_DecodeRcu(isac_state_, + encoded, + static_cast(encoded_len), decoded, + &temp_type); + *speech_type = ConvertSpeechType(temp_type); + return ret; +} + +int AudioDecoderIsac::DecodePlc(int num_frames, int16_t* decoded) { + return WebRtcIsac_DecodePlc(isac_state_, decoded, num_frames); +} + +int AudioDecoderIsac::Init() { + return WebRtcIsac_DecoderInit(isac_state_); +} + +int AudioDecoderIsac::IncomingPacket(const uint8_t* payload, + size_t payload_len, + uint16_t rtp_sequence_number, + uint32_t rtp_timestamp, + uint32_t arrival_timestamp) { + return WebRtcIsac_UpdateBwEstimate(isac_state_, + payload, + static_cast(payload_len), + rtp_sequence_number, + rtp_timestamp, + arrival_timestamp); +} + +int AudioDecoderIsac::ErrorCode() { + return WebRtcIsac_GetErrorCode(isac_state_); +} +#endif + // iSAC fix #ifdef WEBRTC_CODEC_ISACFX AudioDecoderIsacFix::AudioDecoderIsacFix() { diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h index 32c98f5bf9..b30331f3b9 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_impl.h @@ -130,6 +130,31 @@ class AudioDecoderIlbc : public AudioDecoder { }; #endif +#ifdef WEBRTC_CODEC_ISAC +class AudioDecoderIsac : public AudioDecoder { + public: + explicit AudioDecoderIsac(int decode_sample_rate_hz); + virtual ~AudioDecoderIsac(); + virtual int Decode(const uint8_t* encoded, size_t encoded_len, + int16_t* decoded, SpeechType* speech_type); + virtual int DecodeRedundant(const uint8_t* encoded, size_t encoded_len, + int16_t* decoded, SpeechType* speech_type); + virtual bool HasDecodePlc() const { return true; } + virtual int DecodePlc(int num_frames, int16_t* decoded); + virtual int Init(); + virtual int IncomingPacket(const uint8_t* payload, + size_t payload_len, + uint16_t rtp_sequence_number, + uint32_t rtp_timestamp, + uint32_t arrival_timestamp); + virtual int ErrorCode(); + + private: + ISACStruct* isac_state_; + DISALLOW_COPY_AND_ASSIGN(AudioDecoderIsac); +}; +#endif + #ifdef WEBRTC_CODEC_ISACFX class AudioDecoderIsacFix : public AudioDecoder { public: diff --git a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc index 02f383e449..c95214b260 100644 --- a/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc +++ b/webrtc/modules/audio_coding/neteq/audio_decoder_unittest.cc @@ -25,7 +25,7 @@ #include "webrtc/modules/audio_coding/codecs/g722/include/g722_interface.h" #include "webrtc/modules/audio_coding/codecs/ilbc/interface/ilbc.h" #include "webrtc/modules/audio_coding/codecs/isac/fix/interface/isacfix.h" -#include "webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_isac.h" +#include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h" #include "webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h" #include "webrtc/modules/audio_coding/codecs/pcm16b/include/pcm16b.h" #include "webrtc/modules/audio_coding/neteq/tools/resample_input_audio_file.h" @@ -366,36 +366,76 @@ class AudioDecoderIsacFloatTest : public AudioDecoderTest { protected: AudioDecoderIsacFloatTest() : AudioDecoderTest() { codec_input_rate_hz_ = 16000; + input_size_ = 160; frame_size_ = 480; data_length_ = 10 * frame_size_; - AudioEncoderDecoderIsac::Config config; - config.sample_rate_hz = codec_input_rate_hz_; - config.frame_size_ms = - 1000 * static_cast(frame_size_) / codec_input_rate_hz_; - - // We need to create separate AudioEncoderDecoderIsac objects for encoding - // and decoding, because the test class destructor destroys them both. - audio_encoder_.reset(new AudioEncoderDecoderIsac(config)); - decoder_ = new AudioEncoderDecoderIsac(config); + decoder_ = new AudioDecoderIsac(16000); + assert(decoder_); + WebRtcIsac_Create(&encoder_); + WebRtcIsac_SetEncSampRate(encoder_, 16000); } + + ~AudioDecoderIsacFloatTest() { + WebRtcIsac_Free(encoder_); + } + + virtual void InitEncoder() { + ASSERT_EQ(0, WebRtcIsac_EncoderInit(encoder_, 1)); // Fixed mode. + ASSERT_EQ(0, WebRtcIsac_Control(encoder_, 32000, 30)); // 32 kbps, 30 ms. + } + + virtual int EncodeFrame(const int16_t* input, size_t input_len_samples, + uint8_t* output) { + // Insert 3 * 10 ms. Expect non-zero output on third call. + EXPECT_EQ(0, WebRtcIsac_Encode(encoder_, input, output)); + input += input_size_; + EXPECT_EQ(0, WebRtcIsac_Encode(encoder_, input, output)); + input += input_size_; + int enc_len_bytes = WebRtcIsac_Encode(encoder_, input, output); + EXPECT_GT(enc_len_bytes, 0); + return enc_len_bytes; + } + + ISACStruct* encoder_; + int input_size_; }; class AudioDecoderIsacSwbTest : public AudioDecoderTest { protected: AudioDecoderIsacSwbTest() : AudioDecoderTest() { codec_input_rate_hz_ = 32000; + input_size_ = 320; frame_size_ = 960; data_length_ = 10 * frame_size_; - AudioEncoderDecoderIsac::Config config; - config.sample_rate_hz = codec_input_rate_hz_; - config.frame_size_ms = - 1000 * static_cast(frame_size_) / codec_input_rate_hz_; - - // We need to create separate AudioEncoderDecoderIsac objects for encoding - // and decoding, because the test class destructor destroys them both. - audio_encoder_.reset(new AudioEncoderDecoderIsac(config)); - decoder_ = new AudioEncoderDecoderIsac(config); + decoder_ = new AudioDecoderIsac(32000); + assert(decoder_); + WebRtcIsac_Create(&encoder_); + WebRtcIsac_SetEncSampRate(encoder_, 32000); } + + ~AudioDecoderIsacSwbTest() { + WebRtcIsac_Free(encoder_); + } + + virtual void InitEncoder() { + ASSERT_EQ(0, WebRtcIsac_EncoderInit(encoder_, 1)); // Fixed mode. + ASSERT_EQ(0, WebRtcIsac_Control(encoder_, 32000, 30)); // 32 kbps, 30 ms. + } + + virtual int EncodeFrame(const int16_t* input, size_t input_len_samples, + uint8_t* output) { + // Insert 3 * 10 ms. Expect non-zero output on third call. + EXPECT_EQ(0, WebRtcIsac_Encode(encoder_, input, output)); + input += input_size_; + EXPECT_EQ(0, WebRtcIsac_Encode(encoder_, input, output)); + input += input_size_; + int enc_len_bytes = WebRtcIsac_Encode(encoder_, input, output); + EXPECT_GT(enc_len_bytes, 0); + return enc_len_bytes; + } + + ISACStruct* encoder_; + int input_size_; }; class AudioDecoderIsacFixTest : public AudioDecoderTest {