diff options
author | Charlie Kehoe <ckehoe@chromium.org> | 2015-02-19 16:44:34 -0800 |
---|---|---|
committer | Charlie Kehoe <ckehoe@chromium.org> | 2015-02-20 00:45:46 +0000 |
commit | d5f5d1157d418bb545df5621848a8f91e0b5c9f3 (patch) | |
tree | 9d2d834d83ea03b049d4c6bfa4dba42f55a53310 /components | |
parent | da3105a6d3301c557b20fbbee9c5b00ac48840f0 (diff) | |
download | chromium_src-d5f5d1157d418bb545df5621848a8f91e0b5c9f3.zip chromium_src-d5f5d1157d418bb545df5621848a8f91e0b5c9f3.tar.gz chromium_src-d5f5d1157d418bb545df5621848a8f91e0b5c9f3.tar.bz2 |
Adding the Audio Modem API. See design doc at go/chrome-modem.
BUG=455823
R=isherman@chromium.org, rkc@chromium.org, rockot@chromium.org, sky@chromium.org
Review URL: https://codereview.chromium.org/917523004
Cr-Commit-Position: refs/heads/master@{#317196}
Diffstat (limited to 'components')
-rw-r--r-- | components/audio_modem.gypi | 2 | ||||
-rw-r--r-- | components/audio_modem/BUILD.gn | 16 | ||||
-rw-r--r-- | components/audio_modem/modem_impl.cc | 24 | ||||
-rw-r--r-- | components/audio_modem/modem_impl.h | 8 | ||||
-rw-r--r-- | components/audio_modem/public/audio_modem_types.h | 16 | ||||
-rw-r--r-- | components/audio_modem/public/modem.h | 7 | ||||
-rw-r--r-- | components/audio_modem/public/whispernet_client.h | 11 | ||||
-rw-r--r-- | components/audio_modem/test/stub_modem.cc | 69 | ||||
-rw-r--r-- | components/audio_modem/test/stub_modem.h | 51 | ||||
-rw-r--r-- | components/audio_modem/test/stub_whispernet_client.cc | 14 | ||||
-rw-r--r-- | components/audio_modem/test/stub_whispernet_client.h | 10 | ||||
-rw-r--r-- | components/copresence/handlers/audio/audio_directive_handler_impl.cc | 11 | ||||
-rw-r--r-- | components/copresence/handlers/audio/audio_directive_handler_unittest.cc | 30 |
13 files changed, 198 insertions, 71 deletions
diff --git a/components/audio_modem.gypi b/components/audio_modem.gypi index 79d2dbe..7d2219b 100644 --- a/components/audio_modem.gypi +++ b/components/audio_modem.gypi @@ -43,6 +43,8 @@ 'sources': [ 'audio_modem/test/random_samples.cc', 'audio_modem/test/random_samples.h', + 'audio_modem/test/stub_modem.cc', + 'audio_modem/test/stub_modem.h', 'audio_modem/test/stub_whispernet_client.cc', 'audio_modem/test/stub_whispernet_client.h', ], diff --git a/components/audio_modem/BUILD.gn b/components/audio_modem/BUILD.gn index 6676e64..93c9fd6 100644 --- a/components/audio_modem/BUILD.gn +++ b/components/audio_modem/BUILD.gn @@ -27,3 +27,19 @@ static_library("audio_modem") { "//third_party/webrtc/common_audio", ] } + +static_library("audio_modem_test_support") { + sources = [ + "test/random_samples.cc", + "test/random_samples.h", + "test/stub_modem.cc", + "test/stub_modem.h", + "test/stub_whispernet_client.cc", + "test/stub_whispernet_client.h", + ] + + deps = [ + "//base", + "//media", + ] +} diff --git a/components/audio_modem/modem_impl.cc b/components/audio_modem/modem_impl.cc index 293b1f9..23d75d0 100644 --- a/components/audio_modem/modem_impl.cc +++ b/components/audio_modem/modem_impl.cc @@ -92,8 +92,6 @@ ModemImpl::ModemImpl() : client_(nullptr), recorder_(nullptr) { switches::kAudioModemEnableInaudibleBroadcast, true); player_[AUDIBLE] = nullptr; player_[INAUDIBLE] = nullptr; - token_length_[0] = 0; - token_length_[1] = 0; samples_caches_.resize(2); samples_caches_[AUDIBLE] = new SamplesMap(kMaxSamples); @@ -191,21 +189,21 @@ void ModemImpl::StopRecording(AudioType type) { } void ModemImpl::SetToken(AudioType type, - const std::string& url_safe_token) { + const std::string& url_safe_token) { DCHECK(type == AUDIBLE || type == INAUDIBLE); std::string token = FromUrlSafe(url_safe_token); if (samples_caches_[type]->Get(token) == samples_caches_[type]->end()) { - client_->EncodeToken(token, type); + client_->EncodeToken(token, type, token_params_); } else { UpdateToken(type, token); } } -const std::string ModemImpl::GetToken(AudioType type) { +const std::string ModemImpl::GetToken(AudioType type) const { return playing_token_[type]; } -bool ModemImpl::IsPlayingTokenHeard(AudioType type) { +bool ModemImpl::IsPlayingTokenHeard(AudioType type) const { base::TimeDelta tokenTimeout = base::TimeDelta::FromMilliseconds(kTokenTimeoutMs); @@ -217,8 +215,12 @@ bool ModemImpl::IsPlayingTokenHeard(AudioType type) { return base::Time::Now() - heard_own_token_[type] < tokenTimeout; } -void ModemImpl::SetTokenLength(AudioType type, size_t token_length) { - token_length_[type] = token_length; +void ModemImpl::SetTokenParams(AudioType type, const TokenParameters& params) { + DCHECK_GT(params.length, 0u); + token_params_[type] = params; + + // TODO(ckehoe): Make whispernet handle different token lengths + // simultaneously without reinitializing the decoder over and over. } // static @@ -294,11 +296,11 @@ void ModemImpl::DecodeSamplesConnector(const std::string& samples) { should_be_recording_[INAUDIBLE] || should_be_playing_[INAUDIBLE]; if (decode_audible && decode_inaudible) { - client_->DecodeSamples(BOTH, samples, token_length_); + client_->DecodeSamples(BOTH, samples, token_params_); } else if (decode_audible) { - client_->DecodeSamples(AUDIBLE, samples, token_length_); + client_->DecodeSamples(AUDIBLE, samples, token_params_); } else if (decode_inaudible) { - client_->DecodeSamples(INAUDIBLE, samples, token_length_); + client_->DecodeSamples(INAUDIBLE, samples, token_params_); } } diff --git a/components/audio_modem/modem_impl.h b/components/audio_modem/modem_impl.h index 108d4bb..ec6beb5 100644 --- a/components/audio_modem/modem_impl.h +++ b/components/audio_modem/modem_impl.h @@ -45,9 +45,9 @@ class ModemImpl final : public Modem { void StartRecording(AudioType type) override; void StopRecording(AudioType type) override; void SetToken(AudioType type, const std::string& url_safe_token) override; - const std::string GetToken(AudioType type) override; - bool IsPlayingTokenHeard(AudioType type) override; - void SetTokenLength(AudioType type, size_t token_length) override; + const std::string GetToken(AudioType type) const override; + bool IsPlayingTokenHeard(AudioType type) const override; + void SetTokenParams(AudioType type, const TokenParameters& params) override; void set_player_for_testing(AudioType type, AudioPlayer* player) { player_[type] = player; @@ -108,7 +108,7 @@ class ModemImpl final : public Modem { // Indexed using enum AudioType. std::string playing_token_[2]; - size_t token_length_[2]; + TokenParameters token_params_[2]; base::Time started_playing_[2]; base::Time heard_own_token_[2]; diff --git a/components/audio_modem/public/audio_modem_types.h b/components/audio_modem/public/audio_modem_types.h index 32c6757..036a6a1 100644 --- a/components/audio_modem/public/audio_modem_types.h +++ b/components/audio_modem/public/audio_modem_types.h @@ -50,6 +50,22 @@ struct AudioToken final { bool audible; }; +// Struct to hold the encoding parameters for tokens. +// Parity is on by default. +struct TokenParameters { + TokenParameters() : TokenParameters(0, false, true) {} + + explicit TokenParameters(size_t length) + : TokenParameters(length, false, true) {} + + TokenParameters(size_t length, bool crc, bool parity) + : length(length), crc(crc), parity(parity) {} + + size_t length; + bool crc; + bool parity; +}; + // Callback to pass around found tokens. using TokensCallback = base::Callback<void(const std::vector<AudioToken>&)>; diff --git a/components/audio_modem/public/modem.h b/components/audio_modem/public/modem.h index 304614c..09ab399 100644 --- a/components/audio_modem/public/modem.h +++ b/components/audio_modem/public/modem.h @@ -31,11 +31,12 @@ class Modem { virtual void SetToken(AudioType type, const std::string& url_safe_token) = 0; - virtual const std::string GetToken(AudioType type) = 0; + virtual const std::string GetToken(AudioType type) const = 0; - virtual bool IsPlayingTokenHeard(AudioType type) = 0; + virtual bool IsPlayingTokenHeard(AudioType type) const = 0; - virtual void SetTokenLength(AudioType type, size_t token_length) = 0; + virtual void SetTokenParams(AudioType type, + const TokenParameters& params) = 0; static scoped_ptr<Modem> Create(); }; diff --git a/components/audio_modem/public/whispernet_client.h b/components/audio_modem/public/whispernet_client.h index c7219c8..48d1efa 100644 --- a/components/audio_modem/public/whispernet_client.h +++ b/components/audio_modem/public/whispernet_client.h @@ -34,27 +34,24 @@ class WhispernetClient { virtual void Initialize(const SuccessCallback& init_callback) = 0; // Fires an event to request a token encode. - virtual void EncodeToken(const std::string& token, AudioType type) = 0; + virtual void EncodeToken(const std::string& token, + AudioType type, + const TokenParameters token_params[2]) = 0; // Fires an event to request a decode for the given samples. virtual void DecodeSamples(AudioType type, const std::string& samples, - const size_t token_length[2]) = 0; - // Fires an event to request detection of a whispernet broadcast. - virtual void DetectBroadcast() = 0; + const TokenParameters token_params[2]) = 0; // Callback registration methods. The modem will set these to receive data. virtual void RegisterTokensCallback( const TokensCallback& tokens_callback) = 0; virtual void RegisterSamplesCallback( const SamplesCallback& samples_callback) = 0; - virtual void RegisterDetectBroadcastCallback( - const SuccessCallback& db_callback) = 0; // Don't cache these callbacks, as they may become invalid at any time. // Always invoke callbacks directly through these accessors. virtual TokensCallback GetTokensCallback() = 0; virtual SamplesCallback GetSamplesCallback() = 0; - virtual SuccessCallback GetDetectBroadcastCallback() = 0; virtual SuccessCallback GetInitializedCallback() = 0; virtual ~WhispernetClient() {} diff --git a/components/audio_modem/test/stub_modem.cc b/components/audio_modem/test/stub_modem.cc new file mode 100644 index 0000000..ea0fb08 --- /dev/null +++ b/components/audio_modem/test/stub_modem.cc @@ -0,0 +1,69 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/audio_modem/test/stub_modem.h" + +#include "base/base64.h" +#include "base/logging.h" + +namespace audio_modem { + +StubModem::StubModem() { + playing_[AUDIBLE] = false; + playing_[INAUDIBLE] = false; + recording_[AUDIBLE] = false; + recording_[INAUDIBLE] = false; +} + +StubModem::~StubModem() {} + +void StubModem::Initialize(WhispernetClient* whispernet_client, + const TokensCallback& tokens_cb) { + tokens_callback_ = tokens_cb; +} + +void StubModem::StartPlaying(AudioType type) { + playing_[type] = true; +} + +void StubModem::StopPlaying(AudioType type) { + playing_[type] = false; +} + +void StubModem::StartRecording(AudioType type) { + recording_[type] = true; +} + +void StubModem::StopRecording(AudioType type) { + recording_[type] = false; +} + +const std::string StubModem::GetToken(AudioType type) const { + return std::string(); +} + +bool StubModem::IsPlayingTokenHeard(AudioType type) const { + return false; +} + +bool StubModem::IsRecording(AudioType type) const { + return recording_[type]; +} + +bool StubModem::IsPlaying(AudioType type) const { + return playing_[type]; +} + +void StubModem::DeliverTokens(const std::vector<AudioToken>& tokens) { + std::vector<AudioToken> encoded_tokens; + for (const AudioToken& token : tokens) { + std::string encoded_token; + base::Base64Encode(token.token, & encoded_token); + encoded_tokens.push_back(AudioToken(encoded_token, token.audible)); + } + DCHECK_EQ(tokens.size(), encoded_tokens.size()); + tokens_callback_.Run(encoded_tokens); +} + +} // namespace audio_modem diff --git a/components/audio_modem/test/stub_modem.h b/components/audio_modem/test/stub_modem.h new file mode 100644 index 0000000..e76f5e3 --- /dev/null +++ b/components/audio_modem/test/stub_modem.h @@ -0,0 +1,51 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_AUDIO_MODEM_TEST_STUB_MODEM_H_ +#define COMPONENTS_AUDIO_MODEM_TEST_STUB_MODEM_H_ + +#include <string> +#include <vector> + +#include "base/callback.h" +#include "components/audio_modem/public/modem.h" + +namespace audio_modem { + +class StubModem final : public Modem { + public: + StubModem(); + ~StubModem() override; + + // AudioManager overrides: + void Initialize(WhispernetClient* whispernet_client, + const TokensCallback& tokens_cb) override; + void StartPlaying(AudioType type) override; + void StopPlaying(AudioType type) override; + void StartRecording(AudioType type) override; + void StopRecording(AudioType type) override; + void SetToken(AudioType type, const std::string& url_unsafe_token) override {} + const std::string GetToken(AudioType type) const override; + bool IsPlayingTokenHeard(AudioType type) const override; + void SetTokenParams(AudioType type, const TokenParameters& params) override {} + + bool IsRecording(AudioType type) const; + bool IsPlaying(AudioType type) const; + + // Encodes tokens as base64 and then delivers them. + void DeliverTokens(const std::vector<AudioToken>& tokens); + + private: + // Indexed using enum AudioType. + bool playing_[2]; + bool recording_[2]; + + TokensCallback tokens_callback_; + + DISALLOW_COPY_AND_ASSIGN(StubModem); +}; + +} // namespace audio_modem + +#endif // COMPONENTS_AUDIO_MODEM_TEST_STUB_MODEM_H_ diff --git a/components/audio_modem/test/stub_whispernet_client.cc b/components/audio_modem/test/stub_whispernet_client.cc index 9b0a50c..e2763ce 100644 --- a/components/audio_modem/test/stub_whispernet_client.cc +++ b/components/audio_modem/test/stub_whispernet_client.cc @@ -18,14 +18,16 @@ StubWhispernetClient::~StubWhispernetClient() {} void StubWhispernetClient::Initialize(const SuccessCallback& init_callback) {} void StubWhispernetClient::EncodeToken(const std::string& token, - AudioType type) { + AudioType type, + const TokenParameters token_params[2]) { if (!samples_cb_.is_null()) samples_cb_.Run(type, token, samples_); } -void StubWhispernetClient::DecodeSamples(AudioType type, - const std::string& samples, - const size_t token_length[2]) { +void StubWhispernetClient::DecodeSamples( + AudioType type, + const std::string& samples, + const TokenParameters token_params[2]) { if (!tokens_cb_.is_null()) tokens_cb_.Run(tokens_); } @@ -48,10 +50,6 @@ SamplesCallback StubWhispernetClient::GetSamplesCallback() { return samples_cb_; } -SuccessCallback StubWhispernetClient::GetDetectBroadcastCallback() { - return SuccessCallback(); -} - SuccessCallback StubWhispernetClient::GetInitializedCallback() { return SuccessCallback(); } diff --git a/components/audio_modem/test/stub_whispernet_client.h b/components/audio_modem/test/stub_whispernet_client.h index 3225863c..9a0e8c6 100644 --- a/components/audio_modem/test/stub_whispernet_client.h +++ b/components/audio_modem/test/stub_whispernet_client.h @@ -30,20 +30,18 @@ class StubWhispernetClient final : public WhispernetClient { void Initialize(const SuccessCallback& init_callback) override; - void EncodeToken(const std::string& token, AudioType type) override; + void EncodeToken(const std::string& token, + AudioType type, + const TokenParameters token_params[2]) override; void DecodeSamples(AudioType type, const std::string& samples, - const size_t token_length[2]) override; - void DetectBroadcast() override {} + const TokenParameters token_params[2]) override; void RegisterTokensCallback(const TokensCallback& tokens_cb) override; void RegisterSamplesCallback(const SamplesCallback& samples_cb) override; - void RegisterDetectBroadcastCallback( - const SuccessCallback& /* db_cb */) override {} TokensCallback GetTokensCallback() override; SamplesCallback GetSamplesCallback() override; - SuccessCallback GetDetectBroadcastCallback() override; SuccessCallback GetInitializedCallback() override; private: diff --git a/components/copresence/handlers/audio/audio_directive_handler_impl.cc b/components/copresence/handlers/audio/audio_directive_handler_impl.cc index 16b0269..d91b4d8 100644 --- a/components/copresence/handlers/audio/audio_directive_handler_impl.cc +++ b/components/copresence/handlers/audio/audio_directive_handler_impl.cc @@ -22,6 +22,7 @@ using audio_modem::AUDIBLE; using audio_modem::INAUDIBLE; +using audio_modem::TokenParameters; namespace copresence { @@ -102,12 +103,13 @@ void AudioDirectiveHandlerImpl::AddInstruction( DCHECK_GT(token_length, 0u); switch (instruction.medium()) { case AUDIO_ULTRASOUND_PASSBAND: - audio_modem_->SetTokenLength(INAUDIBLE, token_length); + audio_modem_->SetTokenParams(INAUDIBLE, + TokenParameters(token_length)); transmits_lists_[INAUDIBLE]->AddDirective(op_id, directive); audio_modem_->SetToken(INAUDIBLE, instruction.token_id()); break; case AUDIO_AUDIBLE_DTMF: - audio_modem_->SetTokenLength(AUDIBLE, token_length); + audio_modem_->SetTokenParams(AUDIBLE, TokenParameters(token_length)); transmits_lists_[AUDIBLE]->AddDirective(op_id, directive); audio_modem_->SetToken(AUDIBLE, instruction.token_id()); break; @@ -123,11 +125,12 @@ void AudioDirectiveHandlerImpl::AddInstruction( DCHECK_GT(token_length, 0u); switch (instruction.medium()) { case AUDIO_ULTRASOUND_PASSBAND: - audio_modem_->SetTokenLength(INAUDIBLE, token_length); + audio_modem_->SetTokenParams(INAUDIBLE, + TokenParameters(token_length)); receives_lists_[INAUDIBLE]->AddDirective(op_id, directive); break; case AUDIO_AUDIBLE_DTMF: - audio_modem_->SetTokenLength(AUDIBLE, token_length); + audio_modem_->SetTokenParams(AUDIBLE, TokenParameters(token_length)); receives_lists_[AUDIBLE]->AddDirective(op_id, directive); break; default: diff --git a/components/copresence/handlers/audio/audio_directive_handler_unittest.cc b/components/copresence/handlers/audio/audio_directive_handler_unittest.cc index d414dd2..24da3ca 100644 --- a/components/copresence/handlers/audio/audio_directive_handler_unittest.cc +++ b/components/copresence/handlers/audio/audio_directive_handler_unittest.cc @@ -12,6 +12,7 @@ #include "base/timer/mock_timer.h" #include "components/audio_modem/public/modem.h" #include "components/audio_modem/test/random_samples.h" +#include "components/audio_modem/test/stub_modem.h" #include "components/copresence/handlers/audio/audio_directive_handler_impl.h" #include "components/copresence/handlers/audio/tick_clock_ref_counted.h" #include "components/copresence/proto/data.pb.h" @@ -20,6 +21,7 @@ using audio_modem::AUDIBLE; using audio_modem::AudioType; using audio_modem::INAUDIBLE; +using audio_modem::StubModem; namespace copresence { @@ -39,34 +41,6 @@ const Directive CreateDirective(TokenInstructionType type, } // namespace -class StubModem final : public audio_modem::Modem { - public: - StubModem() {} - ~StubModem() override {} - - // AudioManager overrides: - void Initialize(audio_modem::WhispernetClient* whispernet_client, - const audio_modem::TokensCallback& tokens_cb) override {} - void StartPlaying(AudioType type) override { playing_[type] = true; } - void StopPlaying(AudioType type) override { playing_[type] = false; } - void StartRecording(AudioType type) override { recording_[type] = true; } - void StopRecording(AudioType type) override { recording_[type] = false; } - void SetToken(AudioType type, const std::string& url_unsafe_token) override {} - const std::string GetToken(AudioType type) override { return std::string(); } - bool IsPlayingTokenHeard(AudioType type) override { return false; } - void SetTokenLength(AudioType type, size_t token_length) override {} - - bool IsRecording(AudioType type) { return recording_[type]; } - bool IsPlaying(AudioType type) { return playing_[type]; } - - private: - // Indexed using enum AudioType. - bool playing_[2]; - bool recording_[2]; - - DISALLOW_COPY_AND_ASSIGN(StubModem); -}; - class AudioDirectiveHandlerTest : public testing::Test { public: AudioDirectiveHandlerTest() { |