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

Side by Side Diff: media/audio/pulse/pulse_output.cc

Issue 2582703003: Audio output debug recording. (Closed)
Patch Set: Code review (dalecurtis@ and maxmorin@). Created 3 years, 11 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 #include "media/audio/pulse/pulse_output.h" 5 #include "media/audio/pulse/pulse_output.h"
6 6
7 #include <pulse/pulseaudio.h> 7 #include <pulse/pulseaudio.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include "base/bind.h"
11 #include "base/memory/ptr_util.h"
10 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
11 #include "base/time/time.h" 13 #include "base/time/time.h"
14 #include "media/audio/audio_debug_recording_helper.h"
12 #include "media/audio/audio_device_description.h" 15 #include "media/audio/audio_device_description.h"
16 #include "media/audio/audio_file_writer.h"
13 #include "media/audio/audio_manager_base.h" 17 #include "media/audio/audio_manager_base.h"
14 #include "media/audio/pulse/pulse_util.h" 18 #include "media/audio/pulse/pulse_util.h"
15 #include "media/base/audio_sample_types.h" 19 #include "media/base/audio_sample_types.h"
16 20
17 namespace media { 21 namespace media {
18 22
19 using pulse::AutoPulseLock; 23 using pulse::AutoPulseLock;
20 using pulse::WaitForOperationCompletion; 24 using pulse::WaitForOperationCompletion;
21 25
22 // static, pa_stream_notify_cb 26 // static, pa_stream_notify_cb
(...skipping 28 matching lines...) Expand all
51 // want 32 because we're outputting 55 // want 32 because we're outputting
52 // floats. 56 // floats.
53 32, 57 32,
54 params.frames_per_buffer())), 58 params.frames_per_buffer())),
55 device_id_(device_id), 59 device_id_(device_id),
56 manager_(manager), 60 manager_(manager),
57 pa_context_(NULL), 61 pa_context_(NULL),
58 pa_mainloop_(NULL), 62 pa_mainloop_(NULL),
59 pa_stream_(NULL), 63 pa_stream_(NULL),
60 volume_(1.0f), 64 volume_(1.0f),
61 source_callback_(NULL) { 65 source_callback_(NULL),
66 debug_recording_helper_(base::MakeUnique<AudioDebugRecordingHelper>(
o1ka 2017/01/20 11:36:26 Set it to nullptr for non-webrtc-enabled builds?
Henrik Grunell 2017/01/26 10:25:09 Good point. That should be the right things to do.
67 manager,
68 manager_->GetTaskRunner())) {
62 CHECK(params_.IsValid()); 69 CHECK(params_.IsValid());
63 audio_bus_ = AudioBus::Create(params_); 70 audio_bus_ = AudioBus::Create(params_);
64 } 71 }
65 72
66 PulseAudioOutputStream::~PulseAudioOutputStream() { 73 PulseAudioOutputStream::~PulseAudioOutputStream() {
67 // All internal structures should already have been freed in Close(), which 74 // All internal structures should already have been freed in Close(), which
68 // calls AudioManagerBase::ReleaseOutputStream() which deletes this object. 75 // calls AudioManagerBase::ReleaseOutputStream() which deletes this object.
69 DCHECK(!pa_stream_); 76 DCHECK(!pa_stream_);
70 DCHECK(!pa_context_); 77 DCHECK(!pa_context_);
71 DCHECK(!pa_mainloop_); 78 DCHECK(!pa_mainloop_);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 if (frames_filled < audio_bus_->frames()) { 156 if (frames_filled < audio_bus_->frames()) {
150 audio_bus_->ZeroFramesPartial( 157 audio_bus_->ZeroFramesPartial(
151 frames_filled, audio_bus_->frames() - frames_filled); 158 frames_filled, audio_bus_->frames() - frames_filled);
152 } 159 }
153 160
154 audio_bus_->Scale(volume_); 161 audio_bus_->Scale(volume_);
155 audio_bus_->ToInterleaved<Float32SampleTypeTraits>( 162 audio_bus_->ToInterleaved<Float32SampleTypeTraits>(
156 audio_bus_->frames(), reinterpret_cast<float*>(buffer)); 163 audio_bus_->frames(), reinterpret_cast<float*>(buffer));
157 } else { 164 } else {
158 memset(buffer, 0, bytes_to_fill); 165 memset(buffer, 0, bytes_to_fill);
166
167 // If we'll write the data to a debug file, also zero out the |audio_bus_|
168 // as it will be copied.
169 if (debug_recording_helper_->WillWrite())
170 audio_bus_->Zero();
159 } 171 }
160 172
161 if (pa_stream_write(pa_stream_, buffer, bytes_to_fill, NULL, 0LL, 173 if (pa_stream_write(pa_stream_, buffer, bytes_to_fill, NULL, 0LL,
162 PA_SEEK_RELATIVE) < 0) { 174 PA_SEEK_RELATIVE) < 0) {
163 if (source_callback_) { 175 if (source_callback_) {
164 source_callback_->OnError(this); 176 source_callback_->OnError(this);
165 } 177 }
166 } 178 }
167 179
168 // NOTE: As mentioned above, |bytes_remaining| may be negative after this. 180 // NOTE: As mentioned above, |bytes_remaining| may be negative after this.
169 bytes_remaining -= bytes_to_fill; 181 bytes_remaining -= bytes_to_fill;
170 182
183 debug_recording_helper_->MaybeWrite(audio_bus_.get());
184
171 // Despite telling Pulse to only request certain buffer sizes, it will not 185 // Despite telling Pulse to only request certain buffer sizes, it will not
172 // always obey. In these cases we need to avoid back to back reads from 186 // always obey. In these cases we need to avoid back to back reads from
173 // the renderer as it won't have time to complete the request. 187 // the renderer as it won't have time to complete the request.
174 // 188 //
175 // We can't defer the callback as Pulse will never call us again until we've 189 // We can't defer the callback as Pulse will never call us again until we've
176 // satisfied writing the requested number of bytes. 190 // satisfied writing the requested number of bytes.
177 // 191 //
178 // TODO(dalecurtis): It might be worth choosing the sleep duration based on 192 // TODO(dalecurtis): It might be worth choosing the sleep duration based on
179 // the hardware latency return above. Watch http://crbug.com/366433 to see 193 // the hardware latency return above. Watch http://crbug.com/366433 to see
180 // if a more complicated wait process is necessary. We may also need to see 194 // if a more complicated wait process is necessary. We may also need to see
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 AutoPulseLock auto_lock(pa_mainloop_); 252 AutoPulseLock auto_lock(pa_mainloop_);
239 volume_ = static_cast<float>(volume); 253 volume_ = static_cast<float>(volume);
240 } 254 }
241 255
242 void PulseAudioOutputStream::GetVolume(double* volume) { 256 void PulseAudioOutputStream::GetVolume(double* volume) {
243 DCHECK(thread_checker_.CalledOnValidThread()); 257 DCHECK(thread_checker_.CalledOnValidThread());
244 258
245 *volume = volume_; 259 *volume = volume_;
246 } 260 }
247 261
262 void PulseAudioOutputStream::EnableDebugRecording(
263 const base::FilePath& file_name) {
264 debug_recording_helper_->EnableDebugRecording(params_, file_name);
265 }
266
267 void PulseAudioOutputStream::DisableDebugRecording() {
268 debug_recording_helper_->DisableDebugRecording();
269 }
270
248 } // namespace media 271 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698