1 /* -*- c++ -*- */ 2 /* 3 * Copyright 2006-2011,2013-2014 Free Software Foundation, Inc. 4 * 5 * This file is part of GNU Radio. 6 * 7 * GNU Radio is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 3, or (at your option) 10 * any later version. 11 * 12 * GNU Radio is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with GNU Radio; see the file COPYING. If not, write to 19 * the Free Software Foundation, Inc., 51 Franklin Street, 20 * Boston, MA 02110-1301, USA. 21 */ 22 23 #ifndef INCLUDED_AUDIO_OSX_SOURCE_H 24 #define INCLUDED_AUDIO_OSX_SOURCE_H 25 26 #include <gnuradio/audio/source.h> 27 28 #include "circular_buffer.h" 29 #include "osx_common.h" 30 31 namespace gr { 32 namespace audio { 33 34 /*! 35 * \brief audio source using OSX 36 * \ingroup audio_blk 37 * 38 * Input signature is one or two streams of floats. 39 * Samples must be in the range [-1,1]. 40 */ 41 class osx_source : public source 42 { 43 private: 44 Float64 d_device_sample_rate, d_output_sample_rate; 45 UInt32 d_input_buffer_size_frames, d_input_buffer_size_bytes; 46 UInt32 d_output_buffer_size_frames, d_output_buffer_size_bytes; 47 UInt32 d_device_buffer_size_frames, d_device_buffer_size_bytes; 48 UInt32 d_lead_size_frames, d_lead_size_bytes; 49 UInt32 d_trail_size_frames, d_trail_size_bytes; 50 UInt32 d_extra_buffer_size_frames, d_extra_buffer_size_bytes; 51 UInt32 d_queue_sample_count, d_buffer_sample_count; 52 UInt32 d_n_available_input_frames, d_n_actual_input_frames; 53 UInt32 d_n_user_channels, d_n_dev_channels; 54 bool d_ok_to_block, d_pass_through; 55 bool d_waiting_for_data, d_do_reset, d_hardware_changed; 56 bool d_using_default_device; 57 gr::thread::mutex d_internal; 58 gr::thread::condition_variable d_cond_data; 59 std::vector<circular_buffer<float>*> d_buffers; 60 std::string d_desired_name, d_selected_name; 61 62 // CoreAudio variables 63 64 AudioDeviceID d_input_ad_id; 65 AudioUnit d_input_au; 66 AudioBufferList* d_input_buffer; 67 AudioBufferList* d_output_buffer; 68 AudioConverterRef d_audio_converter; 69 70 // d_asbd_device: ASBD of the device that is creating the input 71 // data stream 72 73 AudioStreamBasicDescription d_asbd_device; 74 75 // d_asbd_client: ASBD of the client side (output) of the 76 // hardware device 77 78 AudioStreamBasicDescription d_asbd_client; 79 80 // d_asbd_user: ASBD of the user's arguments, if an audio 81 // converter is needed outside that provided by the client side. 82 83 AudioStreamBasicDescription d_asbd_user; 84 85 public: 86 osx_source(int sample_rate, const std::string& device_name, bool ok_to_block); 87 ~osx_source()88 virtual inline ~osx_source() { teardown(); } 89 90 virtual bool start(); 91 virtual bool stop(); 92 93 virtual bool check_topology(int ninputs, int noutputs); 94 95 virtual int work(int noutput_items, 96 gr_vector_const_void_star& input_items, 97 gr_vector_void_star& output_items); 98 reset(bool hardware_changed)99 inline void reset(bool hardware_changed) 100 { 101 d_hardware_changed = hardware_changed; 102 d_do_reset = true; 103 } 104 105 private: 106 bool is_running(); 107 108 void setup(); 109 110 void teardown(); 111 112 void alloc_audio_buffer_list(AudioBufferList** t_abl, 113 UInt32 n_channels, 114 UInt32 input_buffer_size_bytes); 115 116 void free_audio_buffer_list(AudioBufferList** t_abl); 117 118 static OSStatus converter_callback(AudioConverterRef in_audio_converter, 119 UInt32* io_number_data_packets, 120 AudioBufferList* io_data, 121 AudioStreamPacketDescription** out_aspd, 122 void* in_user_data); 123 124 static OSStatus au_input_callback(void* in_ref_con, 125 AudioUnitRenderActionFlags* io_action_flags, 126 const AudioTimeStamp* in_time_stamp, 127 UInt32 in_bus_number, 128 UInt32 in_number_frames, 129 AudioBufferList* io_data); 130 131 #ifndef GR_USE_OLD_AUDIO_UNIT 132 133 // OSX 10.4 and newer 134 135 static OSStatus hardware_listener(AudioObjectID in_object_id, 136 UInt32 in_num_addresses, 137 const AudioObjectPropertyAddress in_addresses[], 138 void* in_client_data); 139 140 static OSStatus default_listener(AudioObjectID in_object_id, 141 UInt32 in_num_addresses, 142 const AudioObjectPropertyAddress in_addresses[], 143 void* in_client_data); 144 145 #else 146 147 // OSX 10.6 and older; removed as of 10.7 148 149 static OSStatus hardware_listener(AudioHardwarePropertyID in_property_id, 150 void* in_client_data); 151 152 static OSStatus default_listener(AudioHardwarePropertyID in_property_id, 153 void* in_client_data); 154 155 #endif 156 }; 157 } /* namespace audio */ 158 } /* namespace gr */ 159 160 #endif /* INCLUDED_AUDIO_OSX_SOURCE_H */ 161