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

Side by Side Diff: media/audio/mac/audio_low_latency_input_mac.cc

Issue 396263004: Switch the input code to use AudioBlockFifo (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed the comments. Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « media/audio/mac/audio_low_latency_input_mac.h ('k') | media/audio/pulse/pulse_input.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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_bus.h" 13 #include "media/base/audio_bus.h"
14 #include "media/base/audio_fifo.h"
15 #include "media/base/data_buffer.h" 14 #include "media/base/data_buffer.h"
16 15
17 namespace media { 16 namespace media {
18 17
18 // Number of blocks of buffers used in the |fifo_|.
19 const int kNumberOfBlocksBufferInFifo = 2;
20
19 static std::ostream& operator<<(std::ostream& os, 21 static std::ostream& operator<<(std::ostream& os,
20 const AudioStreamBasicDescription& format) { 22 const AudioStreamBasicDescription& format) {
21 os << "sample rate : " << format.mSampleRate << std::endl 23 os << "sample rate : " << format.mSampleRate << std::endl
22 << "format ID : " << format.mFormatID << std::endl 24 << "format ID : " << format.mFormatID << std::endl
23 << "format flags : " << format.mFormatFlags << std::endl 25 << "format flags : " << format.mFormatFlags << std::endl
24 << "bytes per packet : " << format.mBytesPerPacket << std::endl 26 << "bytes per packet : " << format.mBytesPerPacket << std::endl
25 << "frames per packet : " << format.mFramesPerPacket << std::endl 27 << "frames per packet : " << format.mFramesPerPacket << std::endl
26 << "bytes per frame : " << format.mBytesPerFrame << std::endl 28 << "bytes per frame : " << format.mBytesPerFrame << std::endl
27 << "channels per frame: " << format.mChannelsPerFrame << std::endl 29 << "channels per frame: " << format.mChannelsPerFrame << std::endl
28 << "bits per channel : " << format.mBitsPerChannel; 30 << "bits per channel : " << format.mBitsPerChannel;
29 return os; 31 return os;
30 } 32 }
31 33
32 // See "Technical Note TN2091 - Device input using the HAL Output Audio Unit" 34 // See "Technical Note TN2091 - Device input using the HAL Output Audio Unit"
33 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html 35 // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html
34 // for more details and background regarding this implementation. 36 // for more details and background regarding this implementation.
35 37
36 AUAudioInputStream::AUAudioInputStream(AudioManagerMac* manager, 38 AUAudioInputStream::AUAudioInputStream(AudioManagerMac* manager,
37 const AudioParameters& input_params, 39 const AudioParameters& input_params,
38 AudioDeviceID audio_device_id) 40 AudioDeviceID audio_device_id)
39 : manager_(manager), 41 : manager_(manager),
40 number_of_frames_(input_params.frames_per_buffer()), 42 number_of_frames_(input_params.frames_per_buffer()),
41 sink_(NULL), 43 sink_(NULL),
42 audio_unit_(0), 44 audio_unit_(0),
43 input_device_id_(audio_device_id), 45 input_device_id_(audio_device_id),
44 started_(false), 46 started_(false),
45 hardware_latency_frames_(0), 47 hardware_latency_frames_(0),
46 number_of_channels_in_frame_(0), 48 number_of_channels_in_frame_(0),
47 audio_bus_(media::AudioBus::Create(input_params)), 49 fifo_(input_params.channels(),
48 audio_wrapper_(media::AudioBus::Create(input_params)) { 50 number_of_frames_,
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
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 DCHECK_EQ(audio_bus->frames(), static_cast<int>(number_of_frames_));
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_.GetAvailableFrames() * format_.mBytesPerFrame;
514 audio_data, audio_wrapper_->frames(), format_.mBitsPerChannel / 8); 510 sink_->OnData(this, audio_bus, capture_delay_bytes, normalized_volume);
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(
520 this, audio_wrapper_.get(), 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 } 511 }
535 512
536 return noErr; 513 return noErr;
537 } 514 }
538 515
539 int AUAudioInputStream::HardwareSampleRate() { 516 int AUAudioInputStream::HardwareSampleRate() {
540 // Determine the default input device's sample-rate. 517 // Determine the default input device's sample-rate.
541 AudioDeviceID device_id = kAudioObjectUnknown; 518 AudioDeviceID device_id = kAudioObjectUnknown;
542 UInt32 info_size = sizeof(device_id); 519 UInt32 info_size = sizeof(device_id);
543 520
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 kAudioDevicePropertyScopeInput, 642 kAudioDevicePropertyScopeInput,
666 static_cast<UInt32>(channel) 643 static_cast<UInt32>(channel)
667 }; 644 };
668 OSStatus result = AudioObjectIsPropertySettable(input_device_id_, 645 OSStatus result = AudioObjectIsPropertySettable(input_device_id_,
669 &property_address, 646 &property_address,
670 &is_settable); 647 &is_settable);
671 return (result == noErr) ? is_settable : false; 648 return (result == noErr) ? is_settable : false;
672 } 649 }
673 650
674 } // namespace media 651 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/mac/audio_low_latency_input_mac.h ('k') | media/audio/pulse/pulse_input.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698