1 /* 2 * Copyright (C) 2015 Tim Mayberry <mojofunk@gmail.com> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License along 15 * with this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 */ 18 19 #ifndef __libbackend_portaudio_pcmio_h__ 20 #define __libbackend_portaudio_pcmio_h__ 21 22 #include <map> 23 #include <vector> 24 #include <string> 25 #include <boost/shared_ptr.hpp> 26 27 #include <stdint.h> 28 29 #include <portaudio.h> 30 31 namespace ARDOUR { 32 33 class PortAudioIO { 34 public: 35 PortAudioIO (void); 36 ~PortAudioIO (void); 37 38 enum StandardDevices { 39 DeviceNone = -2, 40 DeviceDefault = -1 41 }; 42 43 void host_api_list (std::vector<std::string>&); 44 bool set_host_api (const std::string& host_api_name); get_host_api()45 std::string get_host_api () const { return _host_api_name; } 46 PaHostApiTypeId get_current_host_api_type () const; 47 PaHostApiIndex get_host_api_index_from_name (const std::string& name); 48 49 PaDeviceIndex get_default_input_device () const; 50 PaDeviceIndex get_default_output_device () const; 51 52 bool update_devices(); 53 void input_device_list (std::map<int, std::string> &devices) const; 54 void output_device_list (std::map<int, std::string> &devices) const; 55 56 int available_sample_rates (int device_id, std::vector<float>& sample_rates); 57 int available_buffer_sizes (int device_id, std::vector<uint32_t>& buffer_sizes); 58 59 #ifdef WITH_ASIO 60 bool get_asio_buffer_properties (int device_id, 61 long& min_size_samples, 62 long& max_size_samples, 63 long& preferred_size_samples, 64 long& granularity); 65 66 bool get_asio_buffer_sizes(int device_id, 67 std::vector<uint32_t>& buffer_size, 68 bool preferred_only); 69 #endif 70 71 std::string control_app_name (int device_id) const; 72 void launch_control_app (int device_id); 73 74 PaErrorCode open_blocking_stream(int device_input, 75 int device_output, 76 double sample_rate, 77 uint32_t samples_per_period); 78 79 PaErrorCode open_callback_stream(int device_input, 80 int device_output, 81 double sample_rate, 82 uint32_t samples_per_period, 83 PaStreamCallback* callback, 84 void* data); 85 86 PaErrorCode start_stream(void); 87 88 PaErrorCode close_stream(void); 89 n_playback_channels(void)90 uint32_t n_playback_channels (void) const { return _playback_channels; } n_capture_channels(void)91 uint32_t n_capture_channels (void) const { return _capture_channels; } 92 93 std::string get_input_channel_name (int device_id, uint32_t channel) const; 94 std::string get_output_channel_name (int device_id, uint32_t channel) const; 95 sample_rate(void)96 double sample_rate (void) const { return _cur_sample_rate; } capture_latency(void)97 uint32_t capture_latency (void) const { return _cur_input_latency; } playback_latency(void)98 uint32_t playback_latency (void) const { return _cur_output_latency; } stream_time(void)99 double stream_time(void) const { if (_stream) return Pa_GetStreamTime (_stream); return 0; } 100 101 int next_cycle(uint32_t n_samples); 102 int get_capture_channel (uint32_t chn, float *input, uint32_t n_samples); 103 int set_playback_channel (uint32_t chn, const float *input, uint32_t n_samples); 104 get_capture_buffer()105 float* get_capture_buffer () { return _input_buffer; } get_playback_buffer()106 float* get_playback_buffer () { return _output_buffer; } 107 108 private: // Methods 109 110 static bool pa_initialize(); 111 static bool pa_deinitialize(); 112 static bool& pa_initialized(); 113 114 void clear_device_lists (); 115 void add_none_devices (); 116 void add_default_devices (); 117 void add_devices (); 118 std::string get_host_api_name_from_index (PaHostApiIndex index); 119 120 bool get_output_stream_params(int device_output, 121 PaStreamParameters& outputParam) const; 122 bool get_input_stream_params(int device_input, 123 PaStreamParameters& inputParam) const; 124 125 bool set_sample_rate_and_latency_from_stream(); 126 bool allocate_buffers_for_blocking_api (uint32_t samples_per_period); 127 128 PaErrorCode pre_stream_open(int device_input, 129 PaStreamParameters& inputParam, 130 int device_output, 131 PaStreamParameters& outputParam, 132 uint32_t sample_rate, 133 uint32_t samples_per_period); 134 135 void reset_stream_dependents (); 136 137 static void get_default_sample_rates(std::vector<float>&); 138 static void get_default_buffer_sizes(std::vector<uint32_t>&); 139 140 private: // Data 141 uint32_t _capture_channels; 142 uint32_t _playback_channels; 143 144 PaStream *_stream; 145 146 float *_input_buffer; 147 float *_output_buffer; 148 149 double _cur_sample_rate; 150 uint32_t _cur_input_latency; 151 uint32_t _cur_output_latency; 152 153 struct paDevice { 154 std::string name; 155 uint32_t n_inputs; 156 uint32_t n_outputs; 157 paDevicepaDevice158 paDevice (std::string n, uint32_t i, uint32_t o) 159 : name (n) 160 , n_inputs (i) 161 , n_outputs (o) 162 {} 163 }; 164 165 std::map<int, paDevice *> _input_devices; 166 std::map<int, paDevice *> _output_devices; 167 168 PaHostApiIndex _host_api_index; 169 std::string _host_api_name; 170 171 }; 172 173 } // namespace 174 175 #endif /* __libbackend_portaudio_pcmio_h__ */ 176