Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/mac/audio_low_latency_input_mac.h" | 5 #include "media/audio/mac/audio_low_latency_input_mac.h" |
| 6 | 6 |
| 7 #include <CoreServices/CoreServices.h> | 7 #include <CoreServices/CoreServices.h> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/mac/mac_logging.h" | 11 #include "base/mac/mac_logging.h" |
| 12 #include "media/audio/mac/audio_manager_mac.h" | 12 #include "media/audio/mac/audio_manager_mac.h" |
| 13 #include "media/base/audio_block_fifo.h" | |
| 13 #include "media/base/audio_bus.h" | 14 #include "media/base/audio_bus.h" |
| 14 #include "media/base/audio_fifo.h" | |
| 15 #include "media/base/data_buffer.h" | 15 #include "media/base/data_buffer.h" |
| 16 | 16 |
| 17 namespace media { | 17 namespace media { |
| 18 | 18 |
| 19 // Number of blocks of buffers used in the |fifo_|. | |
| 20 const int kNumberOfBlocksBufferInFifo = 2; | |
| 21 | |
| 19 static std::ostream& operator<<(std::ostream& os, | 22 static std::ostream& operator<<(std::ostream& os, |
| 20 const AudioStreamBasicDescription& format) { | 23 const AudioStreamBasicDescription& format) { |
| 21 os << "sample rate : " << format.mSampleRate << std::endl | 24 os << "sample rate : " << format.mSampleRate << std::endl |
| 22 << "format ID : " << format.mFormatID << std::endl | 25 << "format ID : " << format.mFormatID << std::endl |
| 23 << "format flags : " << format.mFormatFlags << std::endl | 26 << "format flags : " << format.mFormatFlags << std::endl |
| 24 << "bytes per packet : " << format.mBytesPerPacket << std::endl | 27 << "bytes per packet : " << format.mBytesPerPacket << std::endl |
| 25 << "frames per packet : " << format.mFramesPerPacket << std::endl | 28 << "frames per packet : " << format.mFramesPerPacket << std::endl |
| 26 << "bytes per frame : " << format.mBytesPerFrame << std::endl | 29 << "bytes per frame : " << format.mBytesPerFrame << std::endl |
| 27 << "channels per frame: " << format.mChannelsPerFrame << std::endl | 30 << "channels per frame: " << format.mChannelsPerFrame << std::endl |
| 28 << "bits per channel : " << format.mBitsPerChannel; | 31 << "bits per channel : " << format.mBitsPerChannel; |
| 29 return os; | 32 return os; |
| 30 } | 33 } |
| 31 | 34 |
| 32 // See "Technical Note TN2091 - Device input using the HAL Output Audio Unit" | 35 // See "Technical Note TN2091 - Device input using the HAL Output Audio Unit" |
| 33 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html | 36 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html |
| 34 // for more details and background regarding this implementation. | 37 // for more details and background regarding this implementation. |
| 35 | 38 |
| 36 AUAudioInputStream::AUAudioInputStream(AudioManagerMac* manager, | 39 AUAudioInputStream::AUAudioInputStream(AudioManagerMac* manager, |
| 37 const AudioParameters& input_params, | 40 const AudioParameters& input_params, |
| 38 AudioDeviceID audio_device_id) | 41 AudioDeviceID audio_device_id) |
| 39 : manager_(manager), | 42 : manager_(manager), |
| 40 number_of_frames_(input_params.frames_per_buffer()), | 43 number_of_frames_(input_params.frames_per_buffer()), |
| 41 sink_(NULL), | 44 sink_(NULL), |
| 42 audio_unit_(0), | 45 audio_unit_(0), |
| 43 input_device_id_(audio_device_id), | 46 input_device_id_(audio_device_id), |
| 44 started_(false), | 47 started_(false), |
| 45 hardware_latency_frames_(0), | 48 hardware_latency_frames_(0), |
| 46 number_of_channels_in_frame_(0), | 49 number_of_channels_in_frame_(0), |
| 47 audio_bus_(media::AudioBus::Create(input_params)), | 50 fifo_(new AudioBlockFifo(input_params.channels(), number_of_frames_, |
|
DaleCurtis
2014/07/18 18:21:54
No need for dynamic allocation.
no longer working on chromium
2014/07/21 15:13:30
Done.
| |
| 48 audio_wrapper_(media::AudioBus::Create(input_params)) { | 51 kNumberOfBlocksBufferInFifo)) { |
| 49 DCHECK(manager_); | 52 DCHECK(manager_); |
| 50 | 53 |
| 51 // Set up the desired (output) format specified by the client. | 54 // Set up the desired (output) format specified by the client. |
| 52 format_.mSampleRate = input_params.sample_rate(); | 55 format_.mSampleRate = input_params.sample_rate(); |
| 53 format_.mFormatID = kAudioFormatLinearPCM; | 56 format_.mFormatID = kAudioFormatLinearPCM; |
| 54 format_.mFormatFlags = kLinearPCMFormatFlagIsPacked | | 57 format_.mFormatFlags = kLinearPCMFormatFlagIsPacked | |
| 55 kLinearPCMFormatFlagIsSignedInteger; | 58 kLinearPCMFormatFlagIsSignedInteger; |
| 56 format_.mBitsPerChannel = input_params.bits_per_sample(); | 59 format_.mBitsPerChannel = input_params.bits_per_sample(); |
| 57 format_.mChannelsPerFrame = input_params.channels(); | 60 format_.mChannelsPerFrame = input_params.channels(); |
| 58 format_.mFramesPerPacket = 1; // uncompressed audio | 61 format_.mFramesPerPacket = 1; // uncompressed audio |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 487 GetAgcVolume(&normalized_volume); | 490 GetAgcVolume(&normalized_volume); |
| 488 | 491 |
| 489 AudioBuffer& buffer = io_data->mBuffers[0]; | 492 AudioBuffer& buffer = io_data->mBuffers[0]; |
| 490 uint8* audio_data = reinterpret_cast<uint8*>(buffer.mData); | 493 uint8* audio_data = reinterpret_cast<uint8*>(buffer.mData); |
| 491 uint32 capture_delay_bytes = static_cast<uint32> | 494 uint32 capture_delay_bytes = static_cast<uint32> |
| 492 ((capture_latency_frames + 0.5) * format_.mBytesPerFrame); | 495 ((capture_latency_frames + 0.5) * format_.mBytesPerFrame); |
| 493 DCHECK(audio_data); | 496 DCHECK(audio_data); |
| 494 if (!audio_data) | 497 if (!audio_data) |
| 495 return kAudioUnitErr_InvalidElement; | 498 return kAudioUnitErr_InvalidElement; |
| 496 | 499 |
| 497 if (number_of_frames != number_of_frames_) { | 500 // Copy captured (and interleaved) data into FIFO. |
| 498 // Create a FIFO on the fly to handle any discrepancies in callback rates. | 501 fifo_->Push(audio_data, number_of_frames, format_.mBitsPerChannel / 8); |
| 499 if (!fifo_) { | |
| 500 VLOG(1) << "Audio frame size changed from " << number_of_frames_ << " to " | |
| 501 << number_of_frames << "; adding FIFO to compensate."; | |
| 502 fifo_.reset(new AudioFifo( | |
| 503 format_.mChannelsPerFrame, number_of_frames_ + number_of_frames)); | |
| 504 } | |
| 505 | 502 |
| 506 if (audio_wrapper_->frames() != static_cast<int>(number_of_frames)) { | 503 // Consume and deliver the data when the FIFO has a block of available data. |
| 507 audio_wrapper_ = media::AudioBus::Create(format_.mChannelsPerFrame, | 504 while (fifo_->available_blocks()) { |
| 508 number_of_frames); | 505 const AudioBus* audio_bus = fifo_->Consume(); |
| 509 } | 506 CHECK_EQ(audio_bus->frames(), static_cast<int>(number_of_frames_)); |
|
DaleCurtis
2014/07/18 18:21:54
DCHECK? shouldn't ever be wrong since you're no lo
no longer working on chromium
2014/07/21 15:13:30
Done. DCHECK is helping to make sure we deliver wh
| |
| 510 } | |
| 511 | 507 |
| 512 // Copy captured (and interleaved) data into deinterleaved audio bus. | 508 // Compensate the audio delay caused by the FIFO. |
| 513 audio_wrapper_->FromInterleaved( | 509 capture_delay_bytes += fifo_->available_frames() * format_.mBytesPerFrame; |
| 514 audio_data, audio_wrapper_->frames(), format_.mBitsPerChannel / 8); | |
| 515 | |
| 516 // When FIFO does not kick in, data will be directly passed to the callback. | |
| 517 if (!fifo_) { | |
| 518 CHECK_EQ(audio_wrapper_->frames(), static_cast<int>(number_of_frames_)); | |
| 519 sink_->OnData( | 510 sink_->OnData( |
| 520 this, audio_wrapper_.get(), capture_delay_bytes, normalized_volume); | 511 this, audio_bus, capture_delay_bytes, normalized_volume); |
| 521 return noErr; | |
| 522 } | |
| 523 | |
| 524 // Compensate the audio delay caused by the FIFO. | |
| 525 capture_delay_bytes += fifo_->frames() * format_.mBytesPerFrame; | |
| 526 fifo_->Push(audio_wrapper_.get()); | |
| 527 if (fifo_->frames() >= static_cast<int>(number_of_frames_)) { | |
| 528 // Consume the audio from the FIFO. | |
| 529 fifo_->Consume(audio_bus_.get(), 0, audio_bus_->frames()); | |
| 530 DCHECK(fifo_->frames() < static_cast<int>(number_of_frames_)); | |
| 531 | |
| 532 sink_->OnData( | |
| 533 this, audio_bus_.get(), capture_delay_bytes, normalized_volume); | |
| 534 } | 512 } |
| 535 | 513 |
| 536 return noErr; | 514 return noErr; |
| 537 } | 515 } |
| 538 | 516 |
| 539 int AUAudioInputStream::HardwareSampleRate() { | 517 int AUAudioInputStream::HardwareSampleRate() { |
| 540 // Determine the default input device's sample-rate. | 518 // Determine the default input device's sample-rate. |
| 541 AudioDeviceID device_id = kAudioObjectUnknown; | 519 AudioDeviceID device_id = kAudioObjectUnknown; |
| 542 UInt32 info_size = sizeof(device_id); | 520 UInt32 info_size = sizeof(device_id); |
| 543 | 521 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 665 kAudioDevicePropertyScopeInput, | 643 kAudioDevicePropertyScopeInput, |
| 666 static_cast<UInt32>(channel) | 644 static_cast<UInt32>(channel) |
| 667 }; | 645 }; |
| 668 OSStatus result = AudioObjectIsPropertySettable(input_device_id_, | 646 OSStatus result = AudioObjectIsPropertySettable(input_device_id_, |
| 669 &property_address, | 647 &property_address, |
| 670 &is_settable); | 648 &is_settable); |
| 671 return (result == noErr) ? is_settable : false; | 649 return (result == noErr) ? is_settable : false; |
| 672 } | 650 } |
| 673 | 651 |
| 674 } // namespace media | 652 } // namespace media |
| OLD | NEW |