diff options
Diffstat (limited to 'gr-audio/lib/osx/osx_impl.cc')
-rw-r--r-- | gr-audio/lib/osx/osx_impl.cc | 412 |
1 files changed, 195 insertions, 217 deletions
diff --git a/gr-audio/lib/osx/osx_impl.cc b/gr-audio/lib/osx/osx_impl.cc index 2a73375114..c3ef76ba8f 100644 --- a/gr-audio/lib/osx/osx_impl.cc +++ b/gr-audio/lib/osx/osx_impl.cc @@ -33,275 +33,253 @@ #include <locale> #include <stdexcept> -std::ostream& -operator<< -(std::ostream& s, - const AudioStreamBasicDescription& asbd) +std::ostream& operator<<(std::ostream& s, const AudioStreamBasicDescription& asbd) { - char format_id[sizeof(asbd.mFormatID)+1]; - memcpy(format_id, (void*)(&asbd.mFormatID), sizeof(asbd.mFormatID)); - format_id[sizeof(asbd.mFormatID)] = 0; - s << " Sample Rate : " << asbd.mSampleRate << std::endl; - s << " Format ID : " << format_id << std::endl; - s << " Format Flags : " << asbd.mFormatFlags << std::endl; - s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsFloat) != 0) - << " : Is Float" << std::endl; - s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0) - << " : Is Big Endian" << std::endl; - s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0) - << " : Is Signed Integer" << std::endl; - s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsPacked) != 0) - << " : Is Packed" << std::endl; - s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0) - << " : Is Aligned High" << std::endl; - s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsNonInterleaved) != 0) - << " : Is Non-Interleaved" << std::endl; - s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsNonMixable) != 0) - << " : Is Non-Mixable" << std::endl; - s << " Bytes / Packet : " << asbd.mBytesPerPacket << std::endl; - s << " Frames / Packet : " << asbd.mFramesPerPacket << std::endl; - s << " Bytes / Frame : " << asbd.mBytesPerFrame << std::endl; - s << " Channels / Frame : " << asbd.mChannelsPerFrame << std::endl; - s << " Bits / Channel : " << asbd.mBitsPerChannel; - return(s); + char format_id[sizeof(asbd.mFormatID) + 1]; + memcpy(format_id, (void*)(&asbd.mFormatID), sizeof(asbd.mFormatID)); + format_id[sizeof(asbd.mFormatID)] = 0; + s << " Sample Rate : " << asbd.mSampleRate << std::endl; + s << " Format ID : " << format_id << std::endl; + s << " Format Flags : " << asbd.mFormatFlags << std::endl; + s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsFloat) != 0) << " : Is Float" + << std::endl; + s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsBigEndian) != 0) + << " : Is Big Endian" << std::endl; + s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0) + << " : Is Signed Integer" << std::endl; + s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsPacked) != 0) << " : Is Packed" + << std::endl; + s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsAlignedHigh) != 0) + << " : Is Aligned High" << std::endl; + s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsNonInterleaved) != 0) + << " : Is Non-Interleaved" << std::endl; + s << " " << ((asbd.mFormatFlags & kAudioFormatFlagIsNonMixable) != 0) + << " : Is Non-Mixable" << std::endl; + s << " Bytes / Packet : " << asbd.mBytesPerPacket << std::endl; + s << " Frames / Packet : " << asbd.mFramesPerPacket << std::endl; + s << " Bytes / Frame : " << asbd.mBytesPerFrame << std::endl; + s << " Channels / Frame : " << asbd.mChannelsPerFrame << std::endl; + s << " Bits / Channel : " << asbd.mBitsPerChannel; + return (s); }; namespace gr { namespace audio { namespace osx { -static UInt32 -_get_num_channels -(AudioDeviceID ad_id, - AudioObjectPropertyScope scope) +static UInt32 _get_num_channels(AudioDeviceID ad_id, AudioObjectPropertyScope scope) { - // retrieve the AudioBufferList associated with this ID using - // the provided scope - - UInt32 num_channels = 0; - UInt32 prop_size = 0; - AudioObjectPropertyAddress ao_address = { - kAudioDevicePropertyStreamConfiguration, scope, 0 - }; - OSStatus err = noErr; - if ((err = AudioObjectGetPropertyDataSize - (ad_id, &ao_address, 0, NULL, - &prop_size)) == noErr) { - boost::scoped_array<AudioBufferList> buf_list - (reinterpret_cast<AudioBufferList*> - (new char[prop_size])); - if ((err = AudioObjectGetPropertyData - (ad_id, &ao_address, 0, NULL, - &prop_size, buf_list.get())) == noErr) { - for (UInt32 mm = 0; mm < buf_list.get()->mNumberBuffers; ++mm) { - num_channels += buf_list.get()->mBuffers[mm].mNumberChannels; - } - } - else { - // assume 2 channels - num_channels = 2; + // retrieve the AudioBufferList associated with this ID using + // the provided scope + + UInt32 num_channels = 0; + UInt32 prop_size = 0; + AudioObjectPropertyAddress ao_address = { kAudioDevicePropertyStreamConfiguration, + scope, + 0 }; + OSStatus err = noErr; + if ((err = AudioObjectGetPropertyDataSize(ad_id, &ao_address, 0, NULL, &prop_size)) == + noErr) { + boost::scoped_array<AudioBufferList> buf_list( + reinterpret_cast<AudioBufferList*>(new char[prop_size])); + if ((err = AudioObjectGetPropertyData( + ad_id, &ao_address, 0, NULL, &prop_size, buf_list.get())) == noErr) { + for (UInt32 mm = 0; mm < buf_list.get()->mNumberBuffers; ++mm) { + num_channels += buf_list.get()->mBuffers[mm].mNumberChannels; + } + } else { + // assume 2 channels + num_channels = 2; + } + } else { + // assume 2 channels + num_channels = 2; } - } - else { - // assume 2 channels - num_channels = 2; - } - return(num_channels); + return (num_channels); } // works with both char and wchar_t -template<typename charT> +template <typename charT> struct ci_equal { - ci_equal( const std::locale& loc ) : loc_(loc) {} - bool operator()(charT ch1, charT ch2) { - return std::tolower(ch1, loc_) == std::tolower(ch2, loc_); - } + ci_equal(const std::locale& loc) : loc_(loc) {} + bool operator()(charT ch1, charT ch2) + { + return std::tolower(ch1, loc_) == std::tolower(ch2, loc_); + } + private: - const std::locale& loc_; + const std::locale& loc_; }; // find substring (case insensitive) -static std::string::size_type ci_find_substr -(const std::string& str1, const std::string& str2, - const std::locale& loc = std::locale()) +static std::string::size_type ci_find_substr(const std::string& str1, + const std::string& str2, + const std::locale& loc = std::locale()) { - std::string::const_iterator it = std::search - (str1.begin(), str1.end(), - str2.begin(), str2.end(), - ci_equal<std::string::value_type>(loc)); - if (it != str1.end()) { - return(it - str1.begin()); - } - // not found - return(std::string::npos); + std::string::const_iterator it = std::search(str1.begin(), + str1.end(), + str2.begin(), + str2.end(), + ci_equal<std::string::value_type>(loc)); + if (it != str1.end()) { + return (it - str1.begin()); + } + // not found + return (std::string::npos); } -void -get_num_channels_for_audio_device_id -(AudioDeviceID ad_id, - UInt32* n_input, - UInt32* n_output) +void get_num_channels_for_audio_device_id(AudioDeviceID ad_id, + UInt32* n_input, + UInt32* n_output) { - if (n_input) { - *n_input = _get_num_channels - (ad_id, kAudioDevicePropertyScopeInput); - } - if (n_output) { - *n_output = _get_num_channels - (ad_id, kAudioDevicePropertyScopeOutput); - } + if (n_input) { + *n_input = _get_num_channels(ad_id, kAudioDevicePropertyScopeInput); + } + if (n_output) { + *n_output = _get_num_channels(ad_id, kAudioDevicePropertyScopeOutput); + } } -void -find_audio_devices -(const std::string& device_name, - bool is_input, - std::vector < AudioDeviceID >* all_ad_ids, - std::vector < std::string >* all_names) +void find_audio_devices(const std::string& device_name, + bool is_input, + std::vector<AudioDeviceID>* all_ad_ids, + std::vector<std::string>* all_names) { - if ((!all_ad_ids) && (!all_names)) { - // if nothing is requested, no point in doing anything! - return; - } + if ((!all_ad_ids) && (!all_names)) { + // if nothing is requested, no point in doing anything! + return; + } - OSStatus err = noErr; + OSStatus err = noErr; - // retrieve the size of the array of known audio device IDs + // retrieve the size of the array of known audio device IDs - UInt32 prop_size = 0; + UInt32 prop_size = 0; - AudioObjectPropertyAddress ao_address = { - kAudioHardwarePropertyDevices, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster - }; + AudioObjectPropertyAddress ao_address = { kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster }; - if ((err = AudioObjectGetPropertyDataSize - (kAudioObjectSystemObject, &ao_address, - 0, NULL, &prop_size)) != noErr) { + if ((err = AudioObjectGetPropertyDataSize( + kAudioObjectSystemObject, &ao_address, 0, NULL, &prop_size)) != noErr) { #if _OSX_AU_DEBUG_ - std::cerr << "audio_osx::find_audio_devices: " - << "Unable to retrieve number of audio objects: " - << err << std::endl; + std::cerr << "audio_osx::find_audio_devices: " + << "Unable to retrieve number of audio objects: " << err << std::endl; #endif - return; - } + return; + } - // get the total number of audio devices (input and output) + // get the total number of audio devices (input and output) - UInt32 num_devices = prop_size / sizeof(AudioDeviceID); + UInt32 num_devices = prop_size / sizeof(AudioDeviceID); - // retrieve all audio device ids + // retrieve all audio device ids - boost::scoped_array < AudioDeviceID > all_dev_ids - (new AudioDeviceID[num_devices]); + boost::scoped_array<AudioDeviceID> all_dev_ids(new AudioDeviceID[num_devices]); - if ((err = AudioObjectGetPropertyData - (kAudioObjectSystemObject, &ao_address, - 0, NULL, &prop_size, all_dev_ids.get())) != noErr) { + if ((err = AudioObjectGetPropertyData(kAudioObjectSystemObject, + &ao_address, + 0, + NULL, + &prop_size, + all_dev_ids.get())) != noErr) { #if _OSX_AU_DEBUG_ - std::cerr << "audio_osx::find_audio_devices: " - << "Unable to retrieve audio object ids: " - << err << std::endl; + std::cerr << "audio_osx::find_audio_devices: " + << "Unable to retrieve audio object ids: " << err << std::endl; #endif - return; - } - - // success; loop over all retrieved output device ids, retrieving - // the name for each and comparing with the desired name. - - std::vector< std::string > valid_names(num_devices); - std::vector< UInt32 > valid_indices(num_devices); - UInt32 num_found_devices = 0; - AudioObjectPropertyScope scope = is_input ? - kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - - for (UInt32 nn = 0; nn < num_devices; ++nn) { - - // make sure this device has input / output channels (it might - // also have output / input channels, too, but we do not care - // about that here) - - AudioDeviceID t_id = all_dev_ids[nn]; - - if (is_input) { - UInt32 n_input_channels = 0; - get_num_channels_for_audio_device_id - (t_id, &n_input_channels, NULL); - if (n_input_channels == 0) { - // no input channels; must be output device; just continue - // to the next audio device. - continue; - } - } else { - UInt32 n_output_channels = 0; - get_num_channels_for_audio_device_id - (t_id, NULL, &n_output_channels); - if (n_output_channels == 0) { - // no output channels; must be input device; just continue - // to the next audio device. - continue; - } + return; } - // retrieve the device name; max name length is 64 characters. - - prop_size = 65; - char c_name_buf[prop_size]; - bzero((void*)c_name_buf, prop_size); - --prop_size; - - AudioObjectPropertyAddress ao_address = { - kAudioDevicePropertyDeviceName, scope, 0 - }; - - if ((err = AudioObjectGetPropertyData - (t_id, &ao_address, 0, NULL, - &prop_size, (void*)c_name_buf)) != noErr) { + // success; loop over all retrieved output device ids, retrieving + // the name for each and comparing with the desired name. + + std::vector<std::string> valid_names(num_devices); + std::vector<UInt32> valid_indices(num_devices); + UInt32 num_found_devices = 0; + AudioObjectPropertyScope scope = + is_input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; + + for (UInt32 nn = 0; nn < num_devices; ++nn) { + + // make sure this device has input / output channels (it might + // also have output / input channels, too, but we do not care + // about that here) + + AudioDeviceID t_id = all_dev_ids[nn]; + + if (is_input) { + UInt32 n_input_channels = 0; + get_num_channels_for_audio_device_id(t_id, &n_input_channels, NULL); + if (n_input_channels == 0) { + // no input channels; must be output device; just continue + // to the next audio device. + continue; + } + } else { + UInt32 n_output_channels = 0; + get_num_channels_for_audio_device_id(t_id, NULL, &n_output_channels); + if (n_output_channels == 0) { + // no output channels; must be input device; just continue + // to the next audio device. + continue; + } + } + + // retrieve the device name; max name length is 64 characters. + + prop_size = 65; + char c_name_buf[prop_size]; + bzero((void*)c_name_buf, prop_size); + --prop_size; + + AudioObjectPropertyAddress ao_address = { kAudioDevicePropertyDeviceName, + scope, + 0 }; + + if ((err = AudioObjectGetPropertyData( + t_id, &ao_address, 0, NULL, &prop_size, (void*)c_name_buf)) != noErr) { #if _OSX_AU_DEBUG_ - std::cerr << "audio_osx::find_audio_devices: " - << "Unable to retrieve audio device name #" - << (nn+1) << ": " << err << std::endl; + std::cerr << "audio_osx::find_audio_devices: " + << "Unable to retrieve audio device name #" << (nn + 1) << ": " + << err << std::endl; #endif - continue; - } - std::string name_buf(c_name_buf); - - // compare the retrieved name with the desired one, if - // provided; case insensitive. + continue; + } + std::string name_buf(c_name_buf); - if (device_name.length() > 0) { + // compare the retrieved name with the desired one, if + // provided; case insensitive. - std::string::size_type found = - ci_find_substr(name_buf, device_name); - if (found == std::string::npos) { - // not found; continue to the next ID - continue; - } - } + if (device_name.length() > 0) { - // store this info + std::string::size_type found = ci_find_substr(name_buf, device_name); + if (found == std::string::npos) { + // not found; continue to the next ID + continue; + } + } - valid_names[nn] = name_buf; - valid_indices[num_found_devices++] = nn; + // store this info - } + valid_names[nn] = name_buf; + valid_indices[num_found_devices++] = nn; + } - // resize valid function arguments, then copy found values + // resize valid function arguments, then copy found values - if (all_ad_ids) { - all_ad_ids->resize(num_found_devices); - for (UInt32 nn = 0; nn < num_found_devices; ++nn) { - (*all_ad_ids)[nn] = all_dev_ids[valid_indices[nn]]; + if (all_ad_ids) { + all_ad_ids->resize(num_found_devices); + for (UInt32 nn = 0; nn < num_found_devices; ++nn) { + (*all_ad_ids)[nn] = all_dev_ids[valid_indices[nn]]; + } } - } - if (all_names) { - all_names->resize(num_found_devices); - for (UInt32 nn = 0; nn < num_found_devices; ++nn) { - (*all_names)[nn] = valid_names[valid_indices[nn]]; + if (all_names) { + all_names->resize(num_found_devices); + for (UInt32 nn = 0; nn < num_found_devices; ++nn) { + (*all_names)[nn] = valid_names[valid_indices[nn]]; + } } - } } } /* namespace osx */ |