OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/renderer/media/webrtc_audio_device_impl.h" | 5 #include "content/renderer/media/webrtc_audio_device_impl.h" |
6 | 6 |
7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
8 #include "media/audio/audio_util.h" | 8 #include "media/audio/audio_util.h" |
9 | 9 |
10 // TODO(henrika): come up with suitable value(s) for all platforms. | 10 // TODO(henrika): come up with suitable value(s) for all platforms. |
11 // Max supported size for input and output buffers. | 11 // Max supported size for input and output buffers. |
12 // Unit is in #(audio frames), hence 1440 <=> 30ms @ 48kHz. | 12 // Unit is in #(audio frames), hence 1440 <=> 30ms @ 48kHz. |
13 static const size_t kMaxBufferSize = 1440; | 13 static const size_t kMaxBufferSize = 1440; |
14 static const int kMaxChannels = 2; | 14 static const int kMaxChannels = 2; |
15 static const int64 kMillisecondsBetweenProcessCalls = 5000; | 15 static const int64 kMillisecondsBetweenProcessCalls = 5000; |
16 static const char kVersion[] = "WebRTC AudioDevice 1.0.0.Chrome"; | 16 static const char kVersion[] = "WebRTC AudioDevice 1.0.0.Chrome"; |
17 | 17 |
18 WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl( | 18 WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl( |
19 size_t input_buffer_size, size_t output_buffer_size, | 19 size_t input_buffer_size, size_t output_buffer_size, |
20 int input_channels, int output_channels, | 20 int input_channels, int output_channels, |
21 double input_sample_rate, double output_sample_rate) | 21 double input_sample_rate, double output_sample_rate) |
22 : audio_transport_callback_(NULL), | 22 : audio_transport_callback_(NULL), |
23 last_error_(AudioDeviceModule::kAdmErrNone), | 23 last_error_(AudioDeviceModule::kAdmErrNone), |
24 input_buffer_size_(input_buffer_size), | 24 input_buffer_size_(input_buffer_size), |
25 output_buffer_size_(output_buffer_size), | 25 output_buffer_size_(output_buffer_size), |
26 input_channels_(input_channels), | 26 input_channels_(input_channels), |
27 output_channels_(output_channels), | 27 output_channels_(output_channels), |
28 input_sample_rate_(input_sample_rate), | 28 input_sample_rate_(input_sample_rate), |
29 output_sample_rate_(output_sample_rate), | 29 output_sample_rate_(output_sample_rate), |
30 adm_thread_("WebRtcAudioDeviceImpl"), | |
31 recording_stop_event_(false, false), | |
30 initialized_(false), | 32 initialized_(false), |
31 playing_(false), | 33 playing_(false), |
32 recording_(false), | 34 recording_state_(kStopped), |
33 input_delay_ms_(0), | 35 input_delay_ms_(0), |
34 output_delay_ms_(0), | 36 output_delay_ms_(0), |
35 last_process_time_(base::TimeTicks::Now()) { | 37 last_process_time_(base::TimeTicks::Now()) { |
36 VLOG(1) << "WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()"; | 38 VLOG(1) << "WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()"; |
37 | 39 |
40 adm_thread_.Start(); | |
41 adm_message_loop_ = adm_thread_.message_loop_proxy(); | |
42 | |
38 // Create an AudioInputDevice client if the requested buffer size | 43 // Create an AudioInputDevice client if the requested buffer size |
39 // is an even multiple of 10 milliseconds. | 44 // is an even multiple of 10 milliseconds. |
40 if (BufferSizeIsValid(input_buffer_size, input_sample_rate)) { | 45 if (BufferSizeIsValid(input_buffer_size, input_sample_rate)) { |
41 audio_input_device_ = new AudioInputDevice( | 46 audio_input_device_ = new AudioInputDevice( |
42 input_buffer_size, | 47 input_buffer_size, |
43 input_channels, | 48 input_channels, |
44 input_sample_rate, | 49 input_sample_rate, |
50 adm_message_loop_.get(), | |
henrika_dont_use
2011/08/07 16:52:27
Perhaps add a comment on what we want to achieve b
wjia(left Chromium)
2011/08/09 01:40:36
Added some comments in AudioInputDevice constructo
| |
51 this, | |
45 this); | 52 this); |
46 } | 53 } |
47 | 54 |
48 // Create an AudioDevice client if the requested buffer size | 55 // Create an AudioDevice client if the requested buffer size |
49 // is an even multiple of 10 milliseconds. | 56 // is an even multiple of 10 milliseconds. |
50 if (BufferSizeIsValid(output_buffer_size, output_sample_rate)) { | 57 if (BufferSizeIsValid(output_buffer_size, output_sample_rate)) { |
51 audio_output_device_ = new AudioDevice( | 58 audio_output_device_ = new AudioDevice( |
52 output_buffer_size, | 59 output_buffer_size, |
53 output_channels, | 60 output_channels, |
54 output_sample_rate, | 61 output_sample_rate, |
55 this); | 62 this); |
56 } | 63 } |
57 DCHECK(audio_input_device_); | 64 DCHECK(audio_input_device_); |
58 DCHECK(audio_output_device_); | 65 DCHECK(audio_output_device_); |
59 | 66 |
60 input_buffer_.reset(new int16[kMaxBufferSize * kMaxChannels]); | 67 input_buffer_.reset(new int16[kMaxBufferSize * kMaxChannels]); |
61 output_buffer_.reset(new int16[kMaxBufferSize * kMaxChannels]); | 68 output_buffer_.reset(new int16[kMaxBufferSize * kMaxChannels]); |
62 | 69 |
63 bytes_per_sample_ = sizeof(*input_buffer_.get()); | 70 bytes_per_sample_ = sizeof(*input_buffer_.get()); |
64 } | 71 } |
65 | 72 |
66 WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl() { | 73 WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl() { |
67 VLOG(1) << "WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl()"; | 74 VLOG(1) << "WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl()"; |
68 if (playing_) | 75 if (playing_) |
69 StopPlayout(); | 76 StopPlayout(); |
70 if (recording_) | 77 StopRecording(); |
71 StopRecording(); | |
72 if (initialized_) | 78 if (initialized_) |
73 Terminate(); | 79 Terminate(); |
80 adm_thread_.Stop(); | |
74 } | 81 } |
75 | 82 |
76 void WebRtcAudioDeviceImpl::Render( | 83 void WebRtcAudioDeviceImpl::Render( |
77 const std::vector<float*>& audio_data, | 84 const std::vector<float*>& audio_data, |
78 size_t number_of_frames, | 85 size_t number_of_frames, |
79 size_t audio_delay_milliseconds) { | 86 size_t audio_delay_milliseconds) { |
80 DCHECK_LE(number_of_frames, kMaxBufferSize); | 87 DCHECK_LE(number_of_frames, kMaxBufferSize); |
81 | 88 |
82 // Store the reported audio delay locally. | 89 // Store the reported audio delay locally. |
90 lock_.Acquire(); | |
83 output_delay_ms_ = audio_delay_milliseconds; | 91 output_delay_ms_ = audio_delay_milliseconds; |
92 lock_.Release(); | |
84 | 93 |
85 const int channels = audio_data.size(); | 94 const int channels = audio_data.size(); |
86 DCHECK_LE(channels, kMaxChannels); | 95 DCHECK_LE(channels, kMaxChannels); |
87 | 96 |
88 const int samples_per_sec = static_cast<int>(input_sample_rate_); | 97 const int samples_per_sec = static_cast<int>(input_sample_rate_); |
89 uint32_t samples_per_10_msec = (samples_per_sec / 100); | 98 uint32_t samples_per_10_msec = (samples_per_sec / 100); |
90 const int bytes_per_10_msec = | 99 const int bytes_per_10_msec = |
91 channels * samples_per_10_msec * bytes_per_sample_; | 100 channels * samples_per_10_msec * bytes_per_sample_; |
92 | 101 |
93 uint32_t num_audio_samples = 0; | 102 uint32_t num_audio_samples = 0; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
147 const int bytes_per_10_msec = | 156 const int bytes_per_10_msec = |
148 channels * samples_per_10_msec * bytes_per_sample_; | 157 channels * samples_per_10_msec * bytes_per_sample_; |
149 size_t accumulated_audio_samples = 0; | 158 size_t accumulated_audio_samples = 0; |
150 | 159 |
151 char* audio_byte_buffer = reinterpret_cast<char*>(input_buffer_.get()); | 160 char* audio_byte_buffer = reinterpret_cast<char*>(input_buffer_.get()); |
152 | 161 |
153 // Write audio samples in blocks of 10 milliseconds to the registered | 162 // Write audio samples in blocks of 10 milliseconds to the registered |
154 // webrtc::AudioTransport sink. Keep writing until our internal byte | 163 // webrtc::AudioTransport sink. Keep writing until our internal byte |
155 // buffer is empty. | 164 // buffer is empty. |
156 while (accumulated_audio_samples < number_of_frames) { | 165 while (accumulated_audio_samples < number_of_frames) { |
166 lock_.Acquire(); | |
167 int output_delay_ms = output_delay_ms_; | |
168 lock_.Release(); | |
157 // Deliver 10ms of recorded PCM audio. | 169 // Deliver 10ms of recorded PCM audio. |
158 // TODO(henrika): add support for analog AGC? | 170 // TODO(henrika): add support for analog AGC? |
159 audio_transport_callback_->RecordedDataIsAvailable( | 171 audio_transport_callback_->RecordedDataIsAvailable( |
160 audio_byte_buffer, | 172 audio_byte_buffer, |
161 samples_per_10_msec, | 173 samples_per_10_msec, |
162 bytes_per_sample_, | 174 bytes_per_sample_, |
163 channels, | 175 channels, |
164 samples_per_sec, | 176 samples_per_sec, |
165 input_delay_ms_ + output_delay_ms_, | 177 input_delay_ms_ + output_delay_ms, |
166 0, // clock_drift | 178 0, // clock_drift |
167 0, // current_mic_level | 179 0, // current_mic_level |
168 new_mic_level); // not used | 180 new_mic_level); // not used |
169 accumulated_audio_samples += samples_per_10_msec; | 181 accumulated_audio_samples += samples_per_10_msec; |
170 audio_byte_buffer += bytes_per_10_msec; | 182 audio_byte_buffer += bytes_per_10_msec; |
171 } | 183 } |
172 } | 184 } |
173 | 185 |
174 int32_t WebRtcAudioDeviceImpl::Version(char* version, | 186 int32_t WebRtcAudioDeviceImpl::Version(char* version, |
175 uint32_t& remaining_buffer_in_bytes, | 187 uint32_t& remaining_buffer_in_bytes, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
225 int32_t WebRtcAudioDeviceImpl::RegisterEventObserver( | 237 int32_t WebRtcAudioDeviceImpl::RegisterEventObserver( |
226 webrtc::AudioDeviceObserver* event_callback) { | 238 webrtc::AudioDeviceObserver* event_callback) { |
227 VLOG(1) << "RegisterEventObserver()"; | 239 VLOG(1) << "RegisterEventObserver()"; |
228 NOTIMPLEMENTED(); | 240 NOTIMPLEMENTED(); |
229 return -1; | 241 return -1; |
230 } | 242 } |
231 | 243 |
232 int32_t WebRtcAudioDeviceImpl::RegisterAudioCallback( | 244 int32_t WebRtcAudioDeviceImpl::RegisterAudioCallback( |
233 webrtc::AudioTransport* audio_callback) { | 245 webrtc::AudioTransport* audio_callback) { |
234 VLOG(1) << "RegisterAudioCallback()"; | 246 VLOG(1) << "RegisterAudioCallback()"; |
235 if (playing_ || recording_) { | 247 int32_t error = 0; |
248 base::WaitableEvent event(false, false); | |
249 adm_message_loop_->PostTask(FROM_HERE, | |
250 NewRunnableMethod( | |
251 this, | |
252 &WebRtcAudioDeviceImpl::RegisterAudioCallbackOnAdmThread, | |
253 audio_callback, &error, &event)); | |
254 event.Wait(); | |
255 return error; | |
256 } | |
257 | |
258 void WebRtcAudioDeviceImpl::RegisterAudioCallbackOnAdmThread( | |
259 webrtc::AudioTransport* audio_callback, | |
260 int32_t* error, | |
261 base::WaitableEvent* event) { | |
262 VLOG(1) << "RegisterAudioCallbackOnAdmThread()"; | |
263 if (playing_ || recording_state_ != kStopped) { | |
236 LOG(ERROR) << "Unable to (de)register transport during active media"; | 264 LOG(ERROR) << "Unable to (de)register transport during active media"; |
237 return -1; | 265 *error = -1; |
266 return; | |
238 } | 267 } |
239 audio_transport_callback_ = audio_callback; | 268 audio_transport_callback_ = audio_callback; |
240 return 0; | 269 *error = 0; |
270 event->Signal(); | |
241 } | 271 } |
242 | 272 |
243 int32_t WebRtcAudioDeviceImpl::Init() { | 273 int32_t WebRtcAudioDeviceImpl::Init() { |
244 VLOG(1) << "Init()"; | 274 VLOG(1) << "Init()"; |
245 if (initialized_) | 275 if (initialized_) |
246 return 0; | 276 return 0; |
247 initialized_ = true; | 277 initialized_ = true; |
248 return 0; | 278 return 0; |
249 } | 279 } |
250 | 280 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
371 playing_ = !audio_output_device_->Stop(); | 401 playing_ = !audio_output_device_->Stop(); |
372 return (!playing_ ? 0 : -1); | 402 return (!playing_ ? 0 : -1); |
373 } | 403 } |
374 | 404 |
375 bool WebRtcAudioDeviceImpl::Playing() const { | 405 bool WebRtcAudioDeviceImpl::Playing() const { |
376 return playing_; | 406 return playing_; |
377 } | 407 } |
378 | 408 |
379 int32_t WebRtcAudioDeviceImpl::StartRecording() { | 409 int32_t WebRtcAudioDeviceImpl::StartRecording() { |
380 VLOG(1) << "StartRecording()"; | 410 VLOG(1) << "StartRecording()"; |
381 LOG_IF(ERROR, !audio_transport_callback_) << "Audio transport is missing"; | 411 adm_message_loop_->PostTask(FROM_HERE, |
382 if (!audio_transport_callback_) { | 412 NewRunnableMethod(this, |
383 LOG(ERROR) << "Audio transport is missing"; | 413 &WebRtcAudioDeviceImpl::StartRecordingOnAdmThread)); |
384 return -1; | 414 return 0; |
385 } | 415 } |
386 if (recording_) { | 416 |
417 void WebRtcAudioDeviceImpl::StartRecordingOnAdmThread() { | |
418 VLOG(1) << "StartRecordingOnAdmThread()"; | |
419 // Required to set audio_transport_callback_ before starting recording. | |
420 DCHECK(audio_transport_callback_); | |
421 if (recording_state_ != kStopped) { | |
387 // webrtc::VoiceEngine assumes that it is OK to call Start() twice and | 422 // webrtc::VoiceEngine assumes that it is OK to call Start() twice and |
388 // that the call is ignored the second time. | 423 // that the call is ignored the second time. |
389 LOG(WARNING) << "Recording is already active"; | 424 LOG(WARNING) << "Recording is already active"; |
390 return 0; | 425 return; |
391 } | 426 } |
392 recording_ = audio_input_device_->Start(); | 427 audio_input_device_->Start(); |
393 return (recording_ ? 0 : -1); | 428 recording_state_ = kStarting; |
394 } | 429 } |
395 | 430 |
396 int32_t WebRtcAudioDeviceImpl::StopRecording() { | 431 int32_t WebRtcAudioDeviceImpl::StopRecording() { |
397 VLOG(1) << "StopRecording()"; | 432 VLOG(1) << "StopRecording()"; |
398 DCHECK(audio_input_device_); | 433 adm_message_loop_->PostTask(FROM_HERE, |
399 if (!recording_) { | 434 NewRunnableMethod(this, |
435 &WebRtcAudioDeviceImpl::StopRecordingOnAdmThread)); | |
436 recording_stop_event_.Wait(); | |
437 return 0; | |
438 } | |
439 | |
440 void WebRtcAudioDeviceImpl::StopRecordingOnAdmThread() { | |
441 VLOG(1) << "StopRecordingOnAdmThread()"; | |
442 // Client never sees kStopping state since it's always blocked on | |
443 // StopRecording() call. | |
444 DCHECK_NE(recording_state_, kStopping); | |
445 if (recording_state_ == kStopped) { | |
400 // webrtc::VoiceEngine assumes that it is OK to call Stop() just in case. | 446 // webrtc::VoiceEngine assumes that it is OK to call Stop() just in case. |
401 LOG(WARNING) << "Recording was already stopped"; | 447 LOG(WARNING) << "Recording was already stopped"; |
402 return 0; | 448 recording_stop_event_.Signal(); |
449 return; | |
403 } | 450 } |
404 recording_ = !audio_input_device_->Stop(); | 451 audio_input_device_->Stop(); |
405 return (!recording_ ? 0 : -1); | 452 recording_state_ = kStopping; |
453 } | |
454 | |
455 void WebRtcAudioDeviceImpl::OnRecordingStarted() { | |
456 VLOG(1) << "OnRecordingStarted()"; | |
457 adm_message_loop_->PostTask(FROM_HERE, | |
henrika_dont_use
2011/08/07 16:52:27
Can't we set state in this method directly? It is
wjia(left Chromium)
2011/08/09 01:40:36
Setting state here put some assumption on AudioInp
| |
458 NewRunnableMethod(this, | |
459 &WebRtcAudioDeviceImpl::OnRecordingStartedOnAdmThread)); | |
460 } | |
461 | |
462 void WebRtcAudioDeviceImpl::OnRecordingStartedOnAdmThread() { | |
463 VLOG(1) << "OnRecordingStartedOnAdmThread()"; | |
464 recording_state_ = kStarted; | |
465 } | |
466 | |
467 void WebRtcAudioDeviceImpl::OnRecordingStopped() { | |
468 VLOG(1) << "OnRecordingStopped()"; | |
469 adm_message_loop_->PostTask(FROM_HERE, | |
henrika_dont_use
2011/08/07 16:52:27
Same comment as for Start.
wjia(left Chromium)
2011/08/09 01:40:36
See comments above.
| |
470 NewRunnableMethod(this, | |
471 &WebRtcAudioDeviceImpl::OnRecordingStoppedOnAdmThread)); | |
472 } | |
473 | |
474 void WebRtcAudioDeviceImpl::OnRecordingStoppedOnAdmThread() { | |
475 VLOG(1) << "OnRecordingStoppedOnAdmThread()"; | |
476 recording_state_ = kStopped; | |
477 // Always signal "stopped" since client must be waiting for it. | |
478 recording_stop_event_.Signal(); | |
406 } | 479 } |
407 | 480 |
408 bool WebRtcAudioDeviceImpl::Recording() const { | 481 bool WebRtcAudioDeviceImpl::Recording() const { |
409 return recording_; | 482 bool recording = false; |
483 base::WaitableEvent event(false, false); | |
484 adm_message_loop_->PostTask(FROM_HERE, | |
485 NewRunnableMethod(this, | |
486 &WebRtcAudioDeviceImpl::GetRecordingOnAdmThread, | |
487 &recording, &event)); | |
488 event.Wait(); | |
489 return recording; | |
490 } | |
491 | |
492 void WebRtcAudioDeviceImpl::GetRecordingOnAdmThread( | |
493 bool* recording, | |
494 base::WaitableEvent* event) const { | |
495 *recording = recording_state_ == kStarting || | |
496 recording_state_ == kStarted || | |
497 recording_state_ == kStopping; | |
498 event->Signal(); | |
410 } | 499 } |
411 | 500 |
412 int32_t WebRtcAudioDeviceImpl::SetAGC(bool enable) { | 501 int32_t WebRtcAudioDeviceImpl::SetAGC(bool enable) { |
413 NOTIMPLEMENTED(); | 502 NOTIMPLEMENTED(); |
414 return -1; | 503 return -1; |
415 } | 504 } |
416 | 505 |
417 bool WebRtcAudioDeviceImpl::AGC() const { | 506 bool WebRtcAudioDeviceImpl::AGC() const { |
418 NOTIMPLEMENTED(); | 507 NOTIMPLEMENTED(); |
419 return false; | 508 return false; |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
637 return -1; | 726 return -1; |
638 } | 727 } |
639 | 728 |
640 int32_t WebRtcAudioDeviceImpl::PlayoutDelay(uint16_t* delay_ms) const { | 729 int32_t WebRtcAudioDeviceImpl::PlayoutDelay(uint16_t* delay_ms) const { |
641 // Report the cached output delay value. | 730 // Report the cached output delay value. |
642 *delay_ms = static_cast<uint16_t>(output_delay_ms_); | 731 *delay_ms = static_cast<uint16_t>(output_delay_ms_); |
643 return 0; | 732 return 0; |
644 } | 733 } |
645 | 734 |
646 int32_t WebRtcAudioDeviceImpl::RecordingDelay(uint16_t* delay_ms) const { | 735 int32_t WebRtcAudioDeviceImpl::RecordingDelay(uint16_t* delay_ms) const { |
647 // Report the cached output delay value. | 736 base::WaitableEvent event(false, false); |
648 *delay_ms = static_cast<uint16_t>(input_delay_ms_); | 737 adm_message_loop_->PostTask(FROM_HERE, |
738 NewRunnableMethod(this, | |
739 &WebRtcAudioDeviceImpl::GetRecordingDelayOnAdmThread, | |
740 delay_ms, &event)); | |
741 event.Wait(); | |
649 return 0; | 742 return 0; |
650 } | 743 } |
651 | 744 |
745 void WebRtcAudioDeviceImpl::GetRecordingDelayOnAdmThread( | |
746 uint16_t* delay_ms, | |
747 base::WaitableEvent* event) const { | |
748 // Report the cached output delay value. | |
749 *delay_ms = static_cast<uint16_t>(input_delay_ms_); | |
750 event->Signal(); | |
751 } | |
752 | |
652 int32_t WebRtcAudioDeviceImpl::CPULoad(uint16_t* load) const { | 753 int32_t WebRtcAudioDeviceImpl::CPULoad(uint16_t* load) const { |
653 NOTIMPLEMENTED(); | 754 NOTIMPLEMENTED(); |
654 return -1; | 755 return -1; |
655 } | 756 } |
656 | 757 |
657 int32_t WebRtcAudioDeviceImpl::StartRawOutputFileRecording( | 758 int32_t WebRtcAudioDeviceImpl::StartRawOutputFileRecording( |
658 const char pcm_file_name_utf8[webrtc::kAdmMaxFileNameSize]) { | 759 const char pcm_file_name_utf8[webrtc::kAdmMaxFileNameSize]) { |
659 NOTIMPLEMENTED(); | 760 NOTIMPLEMENTED(); |
660 return -1; | 761 return -1; |
661 } | 762 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
723 size_t buffer_size, float sample_rate) const { | 824 size_t buffer_size, float sample_rate) const { |
724 const int samples_per_sec = static_cast<int>(sample_rate); | 825 const int samples_per_sec = static_cast<int>(sample_rate); |
725 const int samples_per_10_msec = (samples_per_sec / 100); | 826 const int samples_per_10_msec = (samples_per_sec / 100); |
726 bool size_is_valid = (((buffer_size % samples_per_10_msec) == 0) && | 827 bool size_is_valid = (((buffer_size % samples_per_10_msec) == 0) && |
727 (buffer_size <= kMaxBufferSize)); | 828 (buffer_size <= kMaxBufferSize)); |
728 DLOG_IF(WARNING, !size_is_valid) << "Size of buffer must be and even " | 829 DLOG_IF(WARNING, !size_is_valid) << "Size of buffer must be and even " |
729 << "multiple of 10 ms and less than " | 830 << "multiple of 10 ms and less than " |
730 << kMaxBufferSize; | 831 << kMaxBufferSize; |
731 return size_is_valid; | 832 return size_is_valid; |
732 } | 833 } |
OLD | NEW |