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

Side by Side Diff: media/audio/virtual_audio_input_stream.cc

Issue 11298006: Browser-wide audio mirroring for TabCapture API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix TabCapture API test Created 8 years, 1 month 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "media/audio/virtual_audio_input_stream.h"
6
7 #include <algorithm>
8
9 #include "base/bind.h"
10 #include "base/message_loop.h"
11 #include "media/audio/virtual_audio_output_stream.h"
12
13 namespace media {
14
15 class MEDIA_EXPORT LoopbackAudioConverter
DaleCurtis 2012/11/21 23:45:43 Class comment.
miu 2012/11/22 00:53:50 I don't think you want to export this. Or, does t
justinlin 2012/11/26 20:19:20 Done.
justinlin 2012/11/26 20:19:20 Done.
16 : public AudioConverter,
17 public AudioConverter::InputCallback {
18 public:
19 LoopbackAudioConverter(const AudioParameters& input_params,
20 const AudioParameters& output_params);
21 virtual ~LoopbackAudioConverter() {}
22
23 private:
24 virtual double ProvideInput(
25 AudioBus* audio_bus, base::TimeDelta buffer_delay) OVERRIDE;
26
27 DISALLOW_COPY_AND_ASSIGN(LoopbackAudioConverter);
28 };
29
30 VirtualAudioInputStream* VirtualAudioInputStream::MakeStream(
31 AudioManagerBase* manager, const AudioParameters& params) {
32 return new VirtualAudioInputStream(manager, params);
33 }
34
35 VirtualAudioInputStream::VirtualAudioInputStream(AudioManagerBase* manager,
36 const AudioParameters& params)
37 : audio_manager_(manager),
38 callback_(NULL),
39 buffer_(new uint8[params.GetBytesPerBuffer()]),
40 buffer_size_(params.GetBytesPerBuffer()),
DaleCurtis 2012/11/21 23:45:43 Class variable necessary if you're storing params_
justinlin 2012/11/26 20:19:20 Done.
41 params_(params),
42 audio_bus_(AudioBus::Create(params_)),
43 mixer_(params_, params_, false) {
44 }
45
46 VirtualAudioInputStream::~VirtualAudioInputStream() {
47 for (AudioConvertersMap::iterator it = converters_.begin();
48 it != converters_.end(); ++it) {
49 delete it->second;
50 }
51 }
52
53 bool VirtualAudioInputStream::Open() {
54 memset(buffer_.get(), 0, buffer_size_);
55 return true;
56 }
57
58 void VirtualAudioInputStream::Start(AudioInputCallback* callback) {
DaleCurtis 2012/11/21 23:45:43 Methods need DCHECK(manager->GetMessageLoop()->Bel
justinlin 2012/11/26 20:19:20 Done.
59 callback_ = callback;
60 on_more_data_cb_.Reset(base::Bind(
61 &VirtualAudioInputStream::DoCallback, base::Unretained(this)));
62 audio_manager_->GetMessageLoop()->PostTask(
63 FROM_HERE, on_more_data_cb_.callback());
64 }
65
66 void VirtualAudioInputStream::Stop() {
67 on_more_data_cb_.Cancel();
68 }
69
70 void VirtualAudioInputStream::AddOutputStream(
71 VirtualAudioOutputStream* stream, const AudioParameters& params) {
72 output_params_.insert(
73 std::make_pair(stream, params));
miu 2012/11/22 00:53:50 Fits on one line.
justinlin 2012/11/26 20:19:20 Done.
74
75 LoopbackAudioConverter* converter =
DaleCurtis 2012/11/21 23:45:43 You should check if the converter exists first bef
miu 2012/11/22 00:53:50 This code could be simplified as: LoopbackAudio
justinlin 2012/11/26 20:19:20 Done. Thanks, that looks good.
justinlin 2012/11/26 20:19:20 Done.
76 new LoopbackAudioConverter(params, params_);
77 std::pair<AudioConvertersMap::iterator, bool> result =
78 converters_.insert(std::make_pair(params, converter));
79
80 // Add to main mixer if we just added a new AudioTransform, otherwise just
81 // use the existing one for these audio params.
82 if (result.second) {
83 mixer_.AddInput(result.first->second);
84 } else {
85 delete converter;
86 converter = result.first->second;
87 }
88
89 converter->AddInput(stream);
90 }
91
92 void VirtualAudioInputStream::RemoveOutputStream(
93 VirtualAudioOutputStream* stream) {
94 if (output_params_.find(stream) == output_params_.end())
DaleCurtis 2012/11/21 23:45:43 DCHECK() this instead for sanity, seems crazy that
justinlin 2012/11/26 20:19:20 Done.
95 return;
96 const AudioParameters& params = output_params_[stream];
97
98 DCHECK(converters_.find(params) != converters_.end());
99 converters_[params]->RemoveInput(stream);
100 // TODO(justinlin): Do we need to delete the AudioConverter and remove it from
DaleCurtis 2012/11/21 23:45:43 Probably okay since virtual input is a temporary t
justinlin 2012/11/26 20:19:20 OK, maybe I'll just leave the TODO For now? Doing
101 // the mixer when there's no more input streams?
102
103 output_params_.erase(stream);
104 }
105
106 void VirtualAudioInputStream::DoCallback() {
107 DCHECK(callback_);
108 DCHECK(audio_manager_->GetMessageLoop()->BelongsToCurrentThread());
109
110 int frames_received = params_.frames_per_buffer();
DaleCurtis 2012/11/21 23:45:43 Seems like this is a constant that could be calcul
justinlin 2012/11/26 20:19:20 Done.
111 float frames_per_millisecond = params_.sample_rate() / static_cast<float>(
112 base::Time::kMillisecondsPerSecond);
113
114 mixer_.Convert(audio_bus_.get());
115 audio_bus_->ToInterleaved(params_.frames_per_buffer(),
116 params_.bits_per_sample() / 8,
117 buffer_.get());
118
119 callback_->OnData(this, buffer_.get(), buffer_size_, buffer_size_, 1.0);
120
121 MessageLoop::current()->PostDelayedTask(
DaleCurtis 2012/11/21 23:45:43 Hmm this seems to indicate that you're driving Aud
justinlin 2012/11/26 20:19:20 Yup, I either use an extension that uses the TabCa
122 FROM_HERE, on_more_data_cb_.callback(),
123 base::TimeDelta::FromMilliseconds(
miu 2012/11/22 00:53:50 Don't you have to subtract the amount of time that
justinlin 2012/11/26 20:19:20 Added a DO_NOT_SUBMIT, will look at this in a bit.
124 frames_received / frames_per_millisecond));
125 }
126
127 void VirtualAudioInputStream::Close() {
128 if (callback_) {
129 callback_->OnClose(this);
DaleCurtis 2012/11/21 23:45:43 DCHECK(on_more_data_cb_.Cancelled()) ?
justinlin 2012/11/26 20:19:20 Done.
130 callback_ = NULL;
131 }
132 audio_manager_->ReleaseInputStream(this);
133 }
134
135 double VirtualAudioInputStream::GetMaxVolume() {
136 return 1.0;
137 }
138
139 void VirtualAudioInputStream::SetVolume(double volume) {}
140
141 double VirtualAudioInputStream::GetVolume() {
142 return 1.0;
143 }
144
145 void VirtualAudioInputStream::SetAutomaticGainControl(bool enabled) {}
146
147 bool VirtualAudioInputStream::GetAutomaticGainControl() {
148 return false;
149 }
150
151 LoopbackAudioConverter::LoopbackAudioConverter(
152 const AudioParameters& input_params, const AudioParameters& output_params)
153 : AudioConverter(input_params, output_params, false) {
154 }
155
156 double LoopbackAudioConverter::ProvideInput(
157 AudioBus* audio_bus, base::TimeDelta buffer_delay) {
158 Convert(audio_bus);
159 return 1.0;
160 }
161
162 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698