| 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(), |
| 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, |
| 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, |
| 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 |