diff options
author | Michael Dickens <mlk@alum.mit.edu> | 2014-03-07 11:10:07 -0500 |
---|---|---|
committer | Michael Dickens <mlk@alum.mit.edu> | 2014-03-07 11:10:07 -0500 |
commit | 6e0895cb3cbc355060eab037ef74b8e237dcf133 (patch) | |
tree | 41d7f98abee78a8154bb4841761de8850f1ae607 /gr-audio/lib/osx/osx_source.h | |
parent | ca69ec5d64b67dfc714917bd94162a5d1f131d69 (diff) |
fix gr-audio osx:
+ use GNU Radio preferences file to set default input and output audio device, if provided;
+ use gr::logger for all non-debug messages;
+ case-insensitive string find with desired audio device name;
+ fixes buffer allocation bug with low sample rates;
+ allows using a specific (named) audio device, or the default;
+ handles the case when the selected audio device becomes unavailable (e.g., a USB stick is removed while in use);
+ if no audio device name is provided, uses the default audio device as found in System Preferences::Sound;
+ handles the case when the default audio device is in use, and the user changes that audio device in System Preferences::Sound, by internally resetting to use the newly selected audio device;
+ all non-Apple names are now lower_case, not CamelCase;
+ move osx_impl functions to gr::audio::osx, and use them correctly;
+ install osx_impl.h to expose gr::audio::osx functions, but iff OSX audio is enabled.
Diffstat (limited to 'gr-audio/lib/osx/osx_source.h')
-rw-r--r-- | gr-audio/lib/osx/osx_source.h | 192 |
1 files changed, 123 insertions, 69 deletions
diff --git a/gr-audio/lib/osx/osx_source.h b/gr-audio/lib/osx/osx_source.h index 0b675f8863..3c9147d26c 100644 --- a/gr-audio/lib/osx/osx_source.h +++ b/gr-audio/lib/osx/osx_source.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006-2011,2013 Free Software Foundation, Inc. + * Copyright 2006-2011,2013-2014 Free Software Foundation, Inc. * * This file is part of GNU Radio. * @@ -24,10 +24,9 @@ #define INCLUDED_AUDIO_OSX_SOURCE_H #include <gnuradio/audio/source.h> -#include <string> -#include <AudioToolbox/AudioToolbox.h> -#include <AudioUnit/AudioUnit.h> -#include <circular_buffer.h> + +#include "osx_common.h" +#include "circular_buffer.h" namespace gr { namespace audio { @@ -41,80 +40,135 @@ namespace gr { */ class osx_source : public source { - Float64 d_deviceSampleRate, d_outputSampleRate; - int d_channel_config; - UInt32 d_inputBufferSizeFrames, d_inputBufferSizeBytes; - UInt32 d_outputBufferSizeFrames, d_outputBufferSizeBytes; - UInt32 d_deviceBufferSizeFrames, d_deviceBufferSizeBytes; - UInt32 d_leadSizeFrames, d_leadSizeBytes; - UInt32 d_trailSizeFrames, d_trailSizeBytes; - UInt32 d_extraBufferSizeFrames, d_extraBufferSizeBytes; - UInt32 d_queueSampleCount, d_max_sample_count; - UInt32 d_n_AvailableInputFrames, d_n_ActualInputFrames; - UInt32 d_n_user_channels, d_n_max_channels, d_n_deviceChannels; - bool d_do_block, d_passThrough, d_waiting_for_data; - gr::thread::mutex* d_internal; - gr::thread::condition_variable* d_cond_data; - circular_buffer<float>** d_buffers; - - // AudioUnits and Such - AudioUnit d_InputAU; - AudioBufferList* d_InputBuffer; - AudioBufferList* d_OutputBuffer; - AudioConverterRef d_AudioConverter; + private: + + Float64 d_device_sample_rate, d_output_sample_rate; + UInt32 d_input_buffer_size_frames, d_input_buffer_size_bytes; + UInt32 d_output_buffer_size_frames, d_output_buffer_size_bytes; + UInt32 d_device_buffer_size_frames, d_device_buffer_size_bytes; + UInt32 d_lead_size_frames, d_lead_size_bytes; + UInt32 d_trail_size_frames, d_trail_size_bytes; + UInt32 d_extra_buffer_size_frames, d_extra_buffer_size_bytes; + UInt32 d_queue_sample_count, d_buffer_sample_count; + UInt32 d_n_available_input_frames, d_n_actual_input_frames; + UInt32 d_n_user_channels, d_n_dev_channels; + bool d_ok_to_block, d_pass_through; + bool d_waiting_for_data, d_do_reset, d_hardware_changed; + bool d_using_default_device; + gr::thread::mutex d_internal; + gr::thread::condition_variable d_cond_data; + std::vector < circular_buffer<float>* > d_buffers; + std::string d_desired_name, d_selected_name; + + // CoreAudio variables + + AudioDeviceID d_input_ad_id; + AudioUnit d_input_au; + AudioBufferList* d_input_buffer; + AudioBufferList* d_output_buffer; + AudioConverterRef d_audio_converter; + + // d_asbd_device: ASBD of the device that is creating the input + // data stream + + AudioStreamBasicDescription d_asbd_device; + + // d_asbd_client: ASBD of the client side (output) of the + // hardware device + + AudioStreamBasicDescription d_asbd_client; + + // d_asbd_user: ASBD of the user's arguments, if an audio + // converter is needed outside that provided by the client side. + + AudioStreamBasicDescription d_asbd_user; public: - osx_source(int sample_rate = 44100, - const std::string device_name = "", - bool do_block = true, - int channel_config = -1, - int max_sample_count = -1); - ~osx_source(); + osx_source(int sample_rate, + const std::string& device_name, + bool ok_to_block); + + virtual inline ~osx_source() { + teardown(); + } - bool start(); - bool stop(); - bool IsRunning(); + virtual bool start(); + virtual bool stop(); - bool check_topology(int ninputs, int noutputs); + virtual bool check_topology(int ninputs, int noutputs); - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + virtual int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + inline void reset(bool hardware_changed) { + d_hardware_changed = hardware_changed; + d_do_reset = true; + } private: - void SetDefaultInputDeviceAsCurrent(); - - void AllocAudioBufferList(AudioBufferList** t_ABL, - UInt32 n_channels, - UInt32 inputBufferSizeBytes); - - void FreeAudioBufferList(AudioBufferList** t_ABL); - - static OSStatus ConverterCallback(AudioConverterRef inAudioConverter, - UInt32* ioNumberDataPackets, - AudioBufferList* ioData, - AudioStreamPacketDescription** outASPD, - void* inUserData); - - static OSStatus AUInputCallback(void *inRefCon, - AudioUnitRenderActionFlags *ioActionFlags, - const AudioTimeStamp *inTimeStamp, - UInt32 inBusNumber, - UInt32 inNumberFrames, - AudioBufferList *ioData); -#if _OSX_DO_LISTENERS_ - static OSStatus UnitListener(void *inRefCon, - AudioUnit ci, - AudioUnitPropertyID inID, - AudioUnitScope inScope, - AudioUnitElement inElement); - - static OSStatus HardwareListener(AudioHardwarePropertyID inPropertyID, - void *inClientData); + + bool is_running(); + + void setup(); + + void teardown(); + + void alloc_audio_buffer_list + (AudioBufferList** t_abl, + UInt32 n_channels, + UInt32 input_buffer_size_bytes); + + void free_audio_buffer_list + (AudioBufferList** t_abl); + + static OSStatus converter_callback + (AudioConverterRef in_audio_converter, + UInt32* io_number_data_packets, + AudioBufferList* io_data, + AudioStreamPacketDescription** out_aspd, + void* in_user_data); + + static OSStatus au_input_callback + (void *in_ref_con, + AudioUnitRenderActionFlags *io_action_flags, + const AudioTimeStamp *in_time_stamp, + UInt32 in_bus_number, + UInt32 in_number_frames, + AudioBufferList *io_data); + +#ifndef GR_USE_OLD_AUDIO_UNIT + + // OSX 10.4 and newer + + static OSStatus hardware_listener + (AudioObjectID in_object_id, + UInt32 in_num_addresses, + const AudioObjectPropertyAddress in_addresses[], + void* in_client_data); + + static OSStatus default_listener + (AudioObjectID in_object_id, + UInt32 in_num_addresses, + const AudioObjectPropertyAddress in_addresses[], + void* in_client_data); + +#else + + // OSX 10.6 and older; removed as of 10.7 + + static OSStatus hardware_listener + (AudioHardwarePropertyID in_property_id, + void* in_client_data); + + static OSStatus default_listener + (AudioHardwarePropertyID in_property_id, + void* in_client_data); + #endif - }; + }; } /* namespace audio */ } /* namespace gr */ |