Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(455)

Side by Side Diff: components/copresence/mediums/audio/audio_manager.cc

Issue 637223011: Redesign the copresence audio handlers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git/+/master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/mediums/audio/audio_manager.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/logging.h"
13 #include "base/run_loop.h"
14 #include "base/strings/string_util.h"
15 #include "base/synchronization/waitable_event.h"
16 #include "components/copresence/mediums/audio/audio_player.h"
17 #include "components/copresence/mediums/audio/audio_recorder.h"
18 #include "components/copresence/public/copresence_constants.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "media/audio/audio_manager.h"
21 #include "media/audio/audio_manager_base.h"
22 #include "media/base/audio_bus.h"
23
24 namespace copresence {
25
26 namespace {
27
28 // UrlSafe is defined as:
29 // '/' represented by a '_' and '+' represented by a '-'
30 // TODO(rkc): Move this processing to the whispernet wrapper.
31 std::string FromUrlSafe(std::string token) {
32 base::ReplaceChars(token, "-", "+", &token);
33 base::ReplaceChars(token, "_", "/", &token);
34 return token;
35 }
36
37 const int kSampleExpiryTimeMs = 60 * 60 * 1000; // 60 minutes.
38 const int kMaxSamples = 10000;
39
40 } // namespace
41
42 // Public methods.
43
44 AudioManager::AudioManager()
45 : playing_{false, false}, recording_{false, false}, recorder_(NULL) {
46 player_.resize(2);
47 player_[AUDIBLE] = NULL;
48 player_[INAUDIBLE] = NULL;
49
50 samples_cache_.resize(2);
51 samples_cache_[AUDIBLE] = new SamplesMap(
52 base::TimeDelta::FromMilliseconds(kSampleExpiryTimeMs), kMaxSamples);
53 samples_cache_[INAUDIBLE] = new SamplesMap(
54 base::TimeDelta::FromMilliseconds(kSampleExpiryTimeMs), kMaxSamples);
55 }
56
57 void AudioManager::Initialize(const DecodeSamplesCallback& decode_cb,
58 const EncodeTokenCallback& encode_cb) {
59 decode_cb_ = decode_cb;
60 encode_cb_ = encode_cb;
61
62 if (!player_[AUDIBLE])
63 player_[AUDIBLE] = new AudioPlayer();
64 player_[AUDIBLE]->Initialize();
65
66 if (!player_[INAUDIBLE])
67 player_[INAUDIBLE] = new AudioPlayer();
68 player_[INAUDIBLE]->Initialize();
69
70 decode_cancelable_cb_.Reset(base::Bind(&AudioManager::DecodeSamplesConnector,
71 base::Unretained(this)));
72 if (!recorder_)
73 recorder_ = new AudioRecorder();
74 recorder_->Initialize(decode_cancelable_cb_.callback());
75 }
76
77 AudioManager::~AudioManager() {
78 if (player_[AUDIBLE])
79 player_[AUDIBLE]->Finalize();
80 if (player_[INAUDIBLE])
81 player_[INAUDIBLE]->Finalize();
82 if (recorder_)
83 recorder_->Finalize();
84 }
85
86 void AudioManager::StartPlaying(AudioType type) {
87 DCHECK_LT(type, BOTH);
88 playing_[type] = true;
89 if (samples_cache_[type]->HasKey(token_[type]) &&
90 !player_[type]->IsPlaying()) {
91 DCHECK_GT(token_[type].size(), 0u);
92 player_[type]->Play(samples_cache_[type]->GetValue(token_[type]));
93 }
94 }
95
96 void AudioManager::StopPlaying(AudioType type) {
97 DCHECK_LT(type, BOTH);
98 playing_[type] = false;
99 if (player_[type]->IsPlaying())
100 player_[type]->Stop();
101 }
102
103 void AudioManager::StartRecording(AudioType type) {
104 DCHECK_LT(type, BOTH);
105 recording_[type] = true;
106 if (!recorder_->IsRecording())
107 recorder_->Record();
108 }
109
110 void AudioManager::StopRecording(AudioType type) {
111 DCHECK_LT(type, BOTH);
112 recording_[type] = false;
113 if (recorder_->IsRecording())
114 recorder_->Stop();
115 }
116
117 void AudioManager::SetToken(AudioType type,
118 const std::string& url_unsafe_token) {
119 DCHECK_LT(type, BOTH);
120 std::string token = FromUrlSafe(url_unsafe_token);
121 if (!samples_cache_[type]->HasKey(token)) {
122 encode_cb_.Run(
123 token,
124 type,
125 base::Bind(&AudioManager::OnTokenEncoded, base::Unretained(this)));
126 } else {
127 UpdateToken(type, token);
128 }
129 }
130
131 // Private methods.
132
133 void AudioManager::OnTokenEncoded(
134 const std::string& token,
135 AudioType type,
136 const scoped_refptr<media::AudioBusRefCounted>& samples) {
137 samples_cache_[type]->Add(token, samples);
138 UpdateToken(type, token);
139 }
140
141 void AudioManager::UpdateToken(AudioType type, const std::string& token) {
142 DCHECK_LT(type, BOTH);
143 if (token_[type] == token)
144 return;
145
146 // Update token.
147 token_[type] = token;
148
149 // If we are supposed to be playing this token type at this moment, switch
150 // out playback with the new samples.
151 if (playing_[type]) {
152 if (player_[type]->IsPlaying())
153 player_[type]->Stop();
154 StartPlaying(type);
155 }
156 }
157
158 void AudioManager::DecodeSamplesConnector(const std::string& samples) {
159 AudioType decode_type = UNKNOWN;
160
161 if (recording_[AUDIBLE])
162 decode_type = AUDIBLE;
163 if (recording_[INAUDIBLE])
164 decode_type = INAUDIBLE;
165 if (recording_[AUDIBLE] && recording_[INAUDIBLE])
166 decode_type = BOTH;
167
168 decode_cb_.Run(decode_type, samples);
169 }
170
171 } // namespace copresence
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698