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