OLD | NEW |
| (Empty) |
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 #include "components/copresence/handlers/audio/audio_directive_handler.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/logging.h" | |
9 #include "base/memory/scoped_ptr.h" | |
10 #include "base/time/default_tick_clock.h" | |
11 #include "base/time/time.h" | |
12 #include "base/timer/timer.h" | |
13 #include "components/copresence/handlers/audio/tick_clock_ref_counted.h" | |
14 #include "components/copresence/mediums/audio/audio_manager_impl.h" | |
15 #include "components/copresence/proto/data.pb.h" | |
16 #include "components/copresence/public/copresence_constants.h" | |
17 #include "media/base/audio_bus.h" | |
18 | |
19 namespace copresence { | |
20 | |
21 namespace { | |
22 | |
23 base::TimeTicks GetEarliestEventTime(AudioDirectiveList* list, | |
24 base::TimeTicks event_time) { | |
25 if (!list->GetActiveDirective()) | |
26 return event_time; | |
27 | |
28 if (event_time.is_null()) | |
29 return list->GetActiveDirective()->end_time; | |
30 else | |
31 return std::min(list->GetActiveDirective()->end_time, event_time); | |
32 } | |
33 | |
34 } // namespace | |
35 | |
36 // Public methods. | |
37 | |
38 AudioDirectiveHandler::AudioDirectiveHandler() | |
39 : audio_event_timer_(new base::OneShotTimer<AudioDirectiveHandler>), | |
40 clock_(new TickClockRefCounted( | |
41 make_scoped_ptr(new base::DefaultTickClock))) { | |
42 } | |
43 | |
44 AudioDirectiveHandler::~AudioDirectiveHandler() { | |
45 } | |
46 | |
47 void AudioDirectiveHandler::Initialize( | |
48 const AudioManager::DecodeSamplesCallback& decode_cb, | |
49 const AudioManager::EncodeTokenCallback& encode_cb) { | |
50 if (!audio_manager_) | |
51 audio_manager_.reset(new AudioManagerImpl()); | |
52 audio_manager_->Initialize(decode_cb, encode_cb); | |
53 } | |
54 | |
55 void AudioDirectiveHandler::AddInstruction(const TokenInstruction& instruction, | |
56 const std::string& op_id, | |
57 base::TimeDelta ttl) { | |
58 switch (instruction.token_instruction_type()) { | |
59 case TRANSMIT: | |
60 DVLOG(2) << "Audio Transmit Directive received. Token: " | |
61 << instruction.token_id() | |
62 << " with medium=" << instruction.medium() | |
63 << " with TTL=" << ttl.InMilliseconds(); | |
64 switch (instruction.medium()) { | |
65 case AUDIO_ULTRASOUND_PASSBAND: | |
66 transmits_list_[INAUDIBLE].AddDirective(op_id, ttl); | |
67 audio_manager_->SetToken(INAUDIBLE, instruction.token_id()); | |
68 break; | |
69 case AUDIO_AUDIBLE_DTMF: | |
70 transmits_list_[AUDIBLE].AddDirective(op_id, ttl); | |
71 audio_manager_->SetToken(AUDIBLE, instruction.token_id()); | |
72 break; | |
73 default: | |
74 NOTREACHED(); | |
75 } | |
76 break; | |
77 case RECEIVE: | |
78 DVLOG(2) << "Audio Receive Directive received." | |
79 << " with medium=" << instruction.medium() | |
80 << " with TTL=" << ttl.InMilliseconds(); | |
81 switch (instruction.medium()) { | |
82 case AUDIO_ULTRASOUND_PASSBAND: | |
83 receives_list_[INAUDIBLE].AddDirective(op_id, ttl); | |
84 break; | |
85 case AUDIO_AUDIBLE_DTMF: | |
86 receives_list_[AUDIBLE].AddDirective(op_id, ttl); | |
87 break; | |
88 default: | |
89 NOTREACHED(); | |
90 } | |
91 break; | |
92 case UNKNOWN_TOKEN_INSTRUCTION_TYPE: | |
93 default: | |
94 LOG(WARNING) << "Unknown Audio Transmit Directive received. type = " | |
95 << instruction.token_instruction_type(); | |
96 } | |
97 ProcessNextInstruction(); | |
98 } | |
99 | |
100 void AudioDirectiveHandler::RemoveInstructions(const std::string& op_id) { | |
101 transmits_list_[AUDIBLE].RemoveDirective(op_id); | |
102 transmits_list_[INAUDIBLE].RemoveDirective(op_id); | |
103 receives_list_[AUDIBLE].RemoveDirective(op_id); | |
104 receives_list_[INAUDIBLE].RemoveDirective(op_id); | |
105 | |
106 ProcessNextInstruction(); | |
107 } | |
108 | |
109 const std::string AudioDirectiveHandler::PlayingToken(AudioType type) const { | |
110 return audio_manager_->GetToken(type); | |
111 } | |
112 | |
113 void AudioDirectiveHandler::set_clock_for_testing( | |
114 const scoped_refptr<TickClockRefCounted>& clock) { | |
115 clock_ = clock; | |
116 | |
117 transmits_list_[AUDIBLE].set_clock_for_testing(clock); | |
118 transmits_list_[INAUDIBLE].set_clock_for_testing(clock); | |
119 receives_list_[AUDIBLE].set_clock_for_testing(clock); | |
120 receives_list_[INAUDIBLE].set_clock_for_testing(clock); | |
121 } | |
122 | |
123 void AudioDirectiveHandler::set_timer_for_testing( | |
124 scoped_ptr<base::Timer> timer) { | |
125 audio_event_timer_.swap(timer); | |
126 } | |
127 | |
128 // Private methods. | |
129 | |
130 void AudioDirectiveHandler::ProcessNextInstruction() { | |
131 DCHECK(audio_event_timer_); | |
132 audio_event_timer_->Stop(); | |
133 | |
134 // Change |audio_manager_| state for audible transmits. | |
135 if (transmits_list_[AUDIBLE].GetActiveDirective()) | |
136 audio_manager_->StartPlaying(AUDIBLE); | |
137 else | |
138 audio_manager_->StopPlaying(AUDIBLE); | |
139 | |
140 // Change audio_manager_ state for inaudible transmits. | |
141 if (transmits_list_[INAUDIBLE].GetActiveDirective()) | |
142 audio_manager_->StartPlaying(INAUDIBLE); | |
143 else | |
144 audio_manager_->StopPlaying(INAUDIBLE); | |
145 | |
146 // Change audio_manager_ state for audible receives. | |
147 if (receives_list_[AUDIBLE].GetActiveDirective()) | |
148 audio_manager_->StartRecording(AUDIBLE); | |
149 else | |
150 audio_manager_->StopRecording(AUDIBLE); | |
151 | |
152 // Change audio_manager_ state for inaudible receives. | |
153 if (receives_list_[INAUDIBLE].GetActiveDirective()) | |
154 audio_manager_->StartRecording(INAUDIBLE); | |
155 else | |
156 audio_manager_->StopRecording(INAUDIBLE); | |
157 | |
158 base::TimeTicks next_event_time; | |
159 if (GetNextInstructionExpiry(&next_event_time)) { | |
160 audio_event_timer_->Start( | |
161 FROM_HERE, | |
162 next_event_time - clock_->NowTicks(), | |
163 base::Bind(&AudioDirectiveHandler::ProcessNextInstruction, | |
164 base::Unretained(this))); | |
165 } | |
166 } | |
167 | |
168 bool AudioDirectiveHandler::GetNextInstructionExpiry(base::TimeTicks* expiry) { | |
169 DCHECK(expiry); | |
170 | |
171 *expiry = GetEarliestEventTime(&transmits_list_[AUDIBLE], base::TimeTicks()); | |
172 *expiry = GetEarliestEventTime(&transmits_list_[INAUDIBLE], *expiry); | |
173 *expiry = GetEarliestEventTime(&receives_list_[AUDIBLE], *expiry); | |
174 *expiry = GetEarliestEventTime(&receives_list_[INAUDIBLE], *expiry); | |
175 | |
176 return !expiry->is_null(); | |
177 } | |
178 | |
179 } // namespace copresence | |
OLD | NEW |