1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_COPRESENCE_HANDLERS_AUDIO_AUDIO_DIRECTIVE_HANDLER_H_ 6 #define COMPONENTS_COPRESENCE_HANDLERS_AUDIO_AUDIO_DIRECTIVE_HANDLER_H_ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/macros.h" 12 #include "base/memory/ref_counted.h" 13 #include "base/time/time.h" 14 #include "base/timer/timer.h" 15 #include "components/copresence/handlers/audio/audio_directive_list.h" 16 #include "components/copresence/mediums/audio/audio_recorder.h" 17 #include "components/copresence/proto/data.pb.h" 18 #include "components/copresence/timed_map.h" 19 20 namespace media { 21 class AudioBusRefCounted; 22 } 23 24 namespace copresence { 25 26 class AudioPlayer; 27 28 // The AudioDirectiveHandler handles audio transmit and receive instructions. 29 // TODO(rkc): Currently since WhispernetClient can only have one token encoded 30 // callback at a time, we need to have both the audible and inaudible in this 31 // class. Investigate a better way to do this; a few options are abstracting 32 // out token encoding to a separate class, or allowing whispernet to have 33 // multiple callbacks for encoded tokens being sent back and have two versions 34 // of this class. 35 class AudioDirectiveHandler { 36 public: 37 typedef base::Callback<void(const std::string&, 38 bool, 39 const scoped_refptr<media::AudioBusRefCounted>&)> 40 SamplesCallback; 41 typedef base::Callback<void(const std::string&, bool, const SamplesCallback&)> 42 EncodeTokenCallback; 43 44 AudioDirectiveHandler( 45 const AudioRecorder::DecodeSamplesCallback& decode_cb, 46 const AudioDirectiveHandler::EncodeTokenCallback& encode_cb); 47 virtual ~AudioDirectiveHandler(); 48 49 // Do not use this class before calling this. 50 void Initialize(); 51 52 // Adds an instruction to our handler. The instruction will execute and be 53 // removed after the ttl expires. 54 void AddInstruction(const copresence::TokenInstruction& instruction, 55 const std::string& op_id, 56 base::TimeDelta ttl_ms); 57 58 // Removes all instructions associated with this operation id. 59 void RemoveInstructions(const std::string& op_id); 60 61 // Returns the currently playing DTMF token. 62 const std::string& PlayingAudibleToken() const { 63 return current_token_audible_; 64 } 65 66 // Returns the currently playing DSSS token. 67 const std::string& PlayingInaudibleToken() const { 68 return current_token_inaudible_; 69 } 70 71 void set_player_audible_for_testing(AudioPlayer* player) { 72 player_audible_ = player; 73 } 74 75 void set_player_inaudible_for_testing(AudioPlayer* player) { 76 player_inaudible_ = player; 77 } 78 79 void set_recorder_for_testing(AudioRecorder* recorder) { 80 recorder_ = recorder; 81 } 82 83 private: 84 FRIEND_TEST_ALL_PREFIXES(AudioDirectiveHandlerTest, Basic); 85 86 typedef TimedMap<std::string, scoped_refptr<media::AudioBusRefCounted>> 87 SamplesMap; 88 89 // Processes the next active transmit instruction. 90 void ProcessNextTransmit(); 91 // Processes the next active receive instruction. 92 void ProcessNextReceive(); 93 94 void PlayToken(const std::string token, bool audible); 95 96 // This is the method that the whispernet client needs to call to return 97 // samples to us. 98 void PlayEncodedToken( 99 const std::string& token, 100 bool audible, 101 const scoped_refptr<media::AudioBusRefCounted>& samples); 102 103 AudioDirectiveList transmits_list_audible_; 104 AudioDirectiveList transmits_list_inaudible_; 105 AudioDirectiveList receives_list_; 106 107 // Currently playing tokens. 108 std::string current_token_audible_; 109 std::string current_token_inaudible_; 110 111 // AudioPlayer and AudioRecorder objects are self-deleting. When we call 112 // Finalize on them, they clean themselves up on the Audio thread. 113 AudioPlayer* player_audible_; 114 AudioPlayer* player_inaudible_; 115 AudioRecorder* recorder_; 116 117 AudioRecorder::DecodeSamplesCallback decode_cb_; 118 EncodeTokenCallback encode_cb_; 119 120 base::OneShotTimer<AudioDirectiveHandler> stop_audible_playback_timer_; 121 base::OneShotTimer<AudioDirectiveHandler> stop_inaudible_playback_timer_; 122 base::OneShotTimer<AudioDirectiveHandler> stop_recording_timer_; 123 124 // Cache that holds the encoded samples. After reaching its limit, the cache 125 // expires the oldest samples first. 126 SamplesMap samples_cache_audible_; 127 SamplesMap samples_cache_inaudible_; 128 129 DISALLOW_COPY_AND_ASSIGN(AudioDirectiveHandler); 130 }; 131 132 } // namespace copresence 133 134 #endif // COMPONENTS_COPRESENCE_HANDLERS_AUDIO_AUDIO_DIRECTIVE_HANDLER_H_ 135