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

Unified Diff: media/audio/mac/audio_low_latency_input_mac.cc

Issue 9418042: Adding microphone volume support to chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed henrik's comments Created 8 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: media/audio/mac/audio_low_latency_input_mac.cc
diff --git a/media/audio/mac/audio_low_latency_input_mac.cc b/media/audio/mac/audio_low_latency_input_mac.cc
index 36858acaea72197ca17b0bc5d4412bd65578ec7d..378360ffc353188437e165fba642cfa40d09d6e7 100644
--- a/media/audio/mac/audio_low_latency_input_mac.cc
+++ b/media/audio/mac/audio_low_latency_input_mac.cc
@@ -37,7 +37,8 @@ AUAudioInputStream::AUAudioInputStream(
audio_unit_(0),
input_device_id_(audio_device_id),
started_(false),
- hardware_latency_frames_(0) {
+ hardware_latency_frames_(0),
+ number_of_channels_in_frame_(0) {
DCHECK(manager_);
// Set up the desired (output) format specified by the client.
@@ -211,6 +212,8 @@ bool AUAudioInputStream::Open() {
// The hardware latency is fixed and will not change during the call.
hardware_latency_frames_ = GetHardwareLatency();
+ number_of_channels_in_frame_ = GetNumberOfChannelsFromStream();
+
return true;
}
@@ -263,6 +266,127 @@ void AUAudioInputStream::Close() {
manager_->ReleaseInputStream(this);
}
+double AUAudioInputStream::GetMaxVolume() {
+ // Verify that we have a valid device.
+ if (input_device_id_ == kAudioObjectUnknown)
+ return 0.0;
+
+ for (UInt32 i = 0; i <= number_of_channels_in_frame_; i++) {
tommi (sloooow) - chröme 2012/02/24 12:07:34 ++i
tommi (sloooow) - chröme 2012/02/24 12:07:34 is the condition correct? Shouldn't it be 'i < nu
tommi (sloooow) - chröme 2012/02/24 12:07:34 Please clean up all the unnecessary UInt32 (and po
no longer working on chromium 2012/02/24 15:05:55 I think it is correct. For example number_of_chann
no longer working on chromium 2012/02/24 15:05:55 Done.
no longer working on chromium 2012/02/24 15:05:55 Done.
+ // If the volume is settable, the valid volume range is [0.0, 1.0].
+ if (IsVolumeSettableOnChannel(i))
+ return 1.0;
+ }
+
+ // Volume control is not available for the audio stream.
+ return 0.0;
+}
+
+void AUAudioInputStream::SetVolume(double volume) {
+ DCHECK(volume <= 1.0 && volume >= 0.0);
+
+ // Verify that we have a valid device.
+ if (input_device_id_ == kAudioObjectUnknown)
+ return;
tommi (sloooow) - chröme 2012/02/24 12:07:34 NOTREACHED?
no longer working on chromium 2012/02/24 15:05:55 Done.
+
+ Float32 volume_float32 = static_cast<Float32> (volume);
tommi (sloooow) - chröme 2012/02/24 12:07:34 no space between >(
no longer working on chromium 2012/02/24 15:05:55 Done.
+ AudioObjectPropertyAddress property_address = {
+ kAudioDevicePropertyVolumeScalar,
+ kAudioDevicePropertyScopeInput,
+ kAudioObjectPropertyElementMaster
+ };
+
+ // Try to set the volume for master volume channel.
+ if (IsVolumeSettableOnChannel(kAudioObjectPropertyElementMaster)) {
+ UInt32 size = sizeof(volume_float32);
tommi (sloooow) - chröme 2012/02/24 12:07:34 nit: this variable isn't necessary. Just pass size
no longer working on chromium 2012/02/24 15:05:55 Done.
+ OSStatus result = AudioObjectSetPropertyData(input_device_id_,
+ &property_address,
+ 0,
+ NULL,
+ size,
+ &volume_float32);
+ if (result != noErr) {
+ DLOG(WARNING) << "Failed to set volume to " << volume_float32;
tommi (sloooow) - chröme 2012/02/24 12:07:34 use DLOG_IF instead
no longer working on chromium 2012/02/24 15:05:55 As discussed, keep it to get rid of the "unused va
+ }
+ return;
+ }
+
+ // There is no master volume control, try to set volume for each channel.
+ int success_on_channel = 0;
+ for (UInt32 i = 1; i <= number_of_channels_in_frame_; i++) {
+ property_address.mElement = i;
+ if (IsVolumeSettableOnChannel(i)) {
+ UInt32 size = sizeof(volume_float32);
+ OSStatus result = AudioObjectSetPropertyData(input_device_id_,
+ &property_address,
+ 0,
+ NULL,
+ size,
+ &volume_float32);
+ if (result == noErr)
+ ++success_on_channel;
+ }
+ }
+
+ DLOG_IF(WARNING, success_on_channel == 0)
+ << "Failed to set volume to " << volume_float32;
+}
+
+double AUAudioInputStream::GetVolume() {
+ // Verify that we have a valid device.
+ if (input_device_id_ == kAudioObjectUnknown)
+ return 0.0;
+
+ AudioObjectPropertyAddress property_address = {
+ kAudioDevicePropertyVolumeScalar,
+ kAudioDevicePropertyScopeInput,
+ kAudioObjectPropertyElementMaster
+ };
+
+ if (AudioObjectHasProperty(input_device_id_, &property_address)) {
+ // The device supports master volume control, get the volume from the
+ // master channel.
+ Float32 volume_float32 = 0.0;
+ UInt32 size = sizeof(volume_float32);
+ OSStatus result = AudioObjectGetPropertyData(input_device_id_,
+ &property_address,
+ 0,
+ NULL,
+ &size,
+ &volume_float32);
+ if (result == noErr)
+ return static_cast<double> (volume_float32);
+ } else {
+ // There is no master volume control, try to get the average volume of
+ // all the channels.
+ Float32 volume_float32 = 0.0;
+ int success_on_channel = 0;
tommi (sloooow) - chröme 2012/02/24 12:07:34 successful_channels?
no longer working on chromium 2012/02/24 15:05:55 Done.
+ for (UInt32 i = 1; i <= number_of_channels_in_frame_; i++) {
tommi (sloooow) - chröme 2012/02/24 12:07:34 ++i please fix throughout
no longer working on chromium 2012/02/24 15:05:55 Done.
+ property_address.mElement = i;
+ if (AudioObjectHasProperty(input_device_id_, &property_address)) {
+ Float32 channel_volume = 0;
+ UInt32 size = sizeof(channel_volume);
+ OSStatus result = AudioObjectGetPropertyData(input_device_id_,
+ &property_address,
+ 0,
+ NULL,
+ &size,
+ &channel_volume);
+ if (result == noErr) {
+ volume_float32 += channel_volume;
+ ++success_on_channel;
+ }
+ }
+ }
+
+ // Get the average volume of the channels.
+ if (success_on_channel != 0)
+ return static_cast<double> (volume_float32 / success_on_channel);
tommi (sloooow) - chröme 2012/02/24 12:07:34 no space between >( please fix throughout
no longer working on chromium 2012/02/24 15:05:55 Done.
+ }
+
+ DLOG(WARNING) << "Failed not get volume";
tommi (sloooow) - chröme 2012/02/24 12:07:34 -> "Failed to get volume"
no longer working on chromium 2012/02/24 15:05:55 Done.
+ return 0.0;
+}
+
// AUHAL AudioDeviceOutput unit callback
OSStatus AUAudioInputStream::InputProc(void* user_data,
AudioUnitRenderActionFlags* flags,
@@ -407,9 +531,46 @@ double AUAudioInputStream::GetCaptureLatency(
return (delay_frames + hardware_latency_frames_);
}
+UInt32 AUAudioInputStream::GetNumberOfChannelsFromStream() {
+ // Get the stream format, to be able to read the number of channels.
+ AudioObjectPropertyAddress property_address = {
+ kAudioDevicePropertyStreamFormat,
+ kAudioDevicePropertyScopeInput,
+ kAudioObjectPropertyElementMaster
+ };
+ AudioStreamBasicDescription stream_format;
+ UInt32 size = sizeof(stream_format);
+ OSStatus result = AudioObjectGetPropertyData(input_device_id_,
+ &property_address,
+ 0,
+ NULL,
+ &size,
+ &stream_format);
+ if (result != noErr) {
+ DLOG(WARNING) << "Could not get stream format";
+ return 0;
+ }
+
+ return stream_format.mChannelsPerFrame;
+}
+
void AUAudioInputStream::HandleError(OSStatus err) {
NOTREACHED() << "error " << GetMacOSStatusErrorString(err)
<< " (" << err << ")";
if (sink_)
sink_->OnError(this, static_cast<int>(err));
}
+
+bool AUAudioInputStream::IsVolumeSettableOnChannel(int channel) {
+ Boolean is_settable = false;
+ AudioObjectPropertyAddress property_address = {
+ kAudioDevicePropertyVolumeScalar,
+ kAudioDevicePropertyScopeInput,
+ kAudioObjectPropertyElementMaster
+ };
+ property_address.mElement = channel;
+ OSStatus result = AudioObjectIsPropertySettable(input_device_id_,
+ &property_address,
+ &is_settable);
+ return (result == noErr) ? is_settable : false;
+}

Powered by Google App Engine
This is Rietveld 408576698