/*
- Copyright (C) 2002-2004 Paul Davis
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
+ * Copyright (C) 2006-2011 David Robillard <d@drobilla.net>
+ * Copyright (C) 2006-2019 Paul Davis <paul@linuxaudiosystems.com>
+ * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
+ * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
+ * Copyright (C) 2013-2015 Tim Mayberry <mojofunk@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
#ifndef __ardour_audioengine_h__
#define __ardour_audioengine_h__
class AudioBackend;
struct AudioBackendInfo;
-class LIBARDOUR_API AudioEngine : public SessionHandlePtr, public PortManager
+class LIBARDOUR_API AudioEngine : public PortManager, public SessionHandlePtr
{
public:
int discover_backends();
std::vector<const AudioBackendInfo*> available_backends() const;
std::string current_backend_name () const;
- boost::shared_ptr<AudioBackend> set_default_backend ();
boost::shared_ptr<AudioBackend> set_backend (const std::string&, const std::string& arg1, const std::string& arg2);
boost::shared_ptr<AudioBackend> current_backend() const { return _backend; }
bool setup_required () const;
ProcessThread* main_thread() const { return _main_thread; }
- /* START BACKEND PROXY API
+ /* START BACKEND PROXY API
*
* See audio_backend.h for full documentation and semantics. These wrappers
* just forward to a backend implementation.
void transport_start ();
void transport_stop ();
TransportState transport_state ();
- void transport_locate (framepos_t pos);
- framepos_t transport_frame();
- framecnt_t sample_rate () const;
+ void transport_locate (samplepos_t pos);
+ samplepos_t transport_sample();
+ samplecnt_t sample_rate () const;
pframes_t samples_per_cycle () const;
int usecs_per_cycle () const;
size_t raw_buffer_size (DataType t);
- framepos_t sample_time ();
- framepos_t sample_time_at_cycle_start ();
+ samplepos_t sample_time ();
+ samplepos_t sample_time_at_cycle_start ();
pframes_t samples_since_cycle_start ();
bool get_sync_offset (pframes_t& offset) const;
+ std::string get_last_backend_error () const { return _last_backend_error_string; }
+
int create_process_thread (boost::function<void()> func);
int join_process_threads ();
bool in_process_thread ();
uint32_t process_thread_count ();
+ /* internal backends
+ * -20 : main thread
+ * -21 : additional I/O threads e.g. MIDI
+ * -22 : client/process threads
+ *
+ * search for
+ * - pbd_realtime_pthread_create
+ * - pbd_set_thread_priority
+ */
+ virtual int client_real_time_priority () { return -22; }
+
int backend_reset_requested();
void request_backend_reset();
void request_device_list_update();
void launch_device_control_app();
bool is_realtime() const;
- bool connected() const;
// for the user which hold state_lock to check if reset operation is pending
bool is_reset_requested() const { return g_atomic_int_get(const_cast<gint*>(&_hw_reset_request_count)); }
return set_buffer_size (samples);
}
- framecnt_t processed_frames() const { return _processed_frames; }
-
+ samplecnt_t processed_samples() const { return _processed_samples; }
+
void set_session (Session *);
void remove_session (); // not a replacement for SessionHandle::session_going_away()
Session* session() const { return _session; }
- void reconnect_session_routes (bool reconnect_inputs = true, bool reconnect_outputs = true);
-
class NoBackendAvailable : public std::exception {
public:
virtual const char *what() const throw() { return "could not connect to engine backend"; }
};
-
+
void split_cycle (pframes_t offset);
-
+
int reset_timebase ();
-
+
void update_latencies ();
-
+
/* this signal is sent for every process() cycle while freewheeling.
(the regular process() call to session->process() is not made)
*/
-
- PBD::Signal1<int, pframes_t> Freewheel;
-
+
+ PBD::Signal1<void, pframes_t> Freewheel;
+
PBD::Signal0<void> Xrun;
/** this signal is emitted if the sample rate changes */
- PBD::Signal1<void, framecnt_t> SampleRateChanged;
+ PBD::Signal1<void, samplecnt_t> SampleRateChanged;
/** this signal is emitted if the buffer size changes */
PBD::Signal1<void, pframes_t> BufferSizeChanged;
PBD::Signal0<void> DeviceError;
/* this signal is emitted if the device list changed */
-
+
PBD::Signal0<void> DeviceListChanged;
-
+
/* this signal is sent if the backend ever disconnects us */
-
+
PBD::Signal1<void,const char*> Halted;
-
+
/* these two are emitted when the engine itself is
started and stopped
*/
-
- PBD::Signal0<void> Running;
+
+ PBD::Signal1<void,uint32_t> Running;
PBD::Signal0<void> Stopped;
/* these two are emitted when a device reset is initiated/finished
*/
-
+
PBD::Signal0<void> DeviceResetStarted;
PBD::Signal0<void> DeviceResetFinished;
static AudioEngine* instance() { return _instance; }
static void destroy();
void died ();
-
+
/* The backend will cause these at the appropriate time(s)
*/
int process_callback (pframes_t nframes);
int buffer_size_change (pframes_t nframes);
int sample_rate_change (pframes_t nframes);
void freewheel_callback (bool);
- void timebase_callback (TransportState state, pframes_t nframes, framepos_t pos, int new_position);
- int sync_callback (TransportState state, framepos_t position);
+ void timebase_callback (TransportState state, pframes_t nframes, samplepos_t pos, int new_position);
+ int sync_callback (TransportState state, samplepos_t position);
int port_registration_callback ();
void latency_callback (bool for_playback);
void halted_callback (const char* reason);
+ /* checks if current thread is properly set up for audio processing */
+ static bool thread_initialised_for_audio_processing ();
+
/* sets up the process callback thread */
static void thread_init_callback (void *);
* countdown, whose duration will be reduced to half of its previous
* value.
*/
-
+
PBD::Signal0<void> BecameSilent;
void reset_silence_countdown ();
-
+
+ void add_pending_port_deletion (Port*);
+
private:
AudioEngine ();
static AudioEngine* _instance;
- Glib::Threads::Mutex _process_lock;
+ Glib::Threads::Mutex _process_lock;
Glib::Threads::RecMutex _state_lock;
Glib::Threads::Cond session_removed;
bool session_remove_pending;
- frameoffset_t session_removal_countdown;
+ sampleoffset_t session_removal_countdown;
gain_t session_removal_gain;
gain_t session_removal_gain_step;
bool _running;
bool _freewheeling;
- /// number of frames between each check for changes in monitor input
- framecnt_t monitor_check_interval;
- /// time of the last monitor check in frames
- framecnt_t last_monitor_check;
- /// the number of frames processed since start() was called
- framecnt_t _processed_frames;
+ /// number of samples between each check for changes in monitor input
+ samplecnt_t monitor_check_interval;
+ /// time of the last monitor check in samples
+ samplecnt_t last_monitor_check;
+ /// the number of samples processed since start() was called
+ samplecnt_t _processed_samples;
Glib::Threads::Thread* m_meter_thread;
ProcessThread* _main_thread;
MTDM* _mtdm;
LatencyMeasurement _measuring_latency;
PortEngine::PortHandle _latency_input_port;
PortEngine::PortHandle _latency_output_port;
- framecnt_t _latency_flush_frames;
+ samplecnt_t _latency_flush_samples;
std::string _latency_input_name;
std::string _latency_output_name;
- framecnt_t _latency_signal_latency;
+ samplecnt_t _latency_signal_latency;
bool _stopped_for_latency;
bool _started_for_latency;
bool _in_destructor;
- Glib::Threads::Thread* _hw_reset_event_thread;
- gint _hw_reset_request_count;
- Glib::Threads::Cond _hw_reset_condition;
- Glib::Threads::Mutex _reset_request_lock;
- gint _stop_hw_reset_processing;
- Glib::Threads::Thread* _hw_devicelist_update_thread;
- gint _hw_devicelist_update_count;
- Glib::Threads::Cond _hw_devicelist_update_condition;
- Glib::Threads::Mutex _devicelist_update_lock;
- gint _stop_hw_devicelist_processing;
+ std::string _last_backend_error_string;
+
+ Glib::Threads::Thread* _hw_reset_event_thread;
+ gint _hw_reset_request_count;
+ Glib::Threads::Cond _hw_reset_condition;
+ Glib::Threads::Mutex _reset_request_lock;
+ gint _stop_hw_reset_processing;
+ Glib::Threads::Thread* _hw_devicelist_update_thread;
+ gint _hw_devicelist_update_count;
+ Glib::Threads::Cond _hw_devicelist_update_condition;
+ Glib::Threads::Mutex _devicelist_update_lock;
+ gint _stop_hw_devicelist_processing;
+ uint32_t _start_cnt;
+ uint32_t _init_countdown;
void start_hw_event_processing();
void stop_hw_event_processing();
void do_reset_backend();
void do_devicelist_update();
- void meter_thread ();
- void start_metering_thread ();
- void stop_metering_thread ();
-
- static gint m_meter_exit;
-
typedef std::map<std::string,AudioBackendInfo*> BackendMap;
BackendMap _backends;
AudioBackendInfo* backend_discover (const std::string&);
void drop_backend ();
#ifdef SILENCE_AFTER
- framecnt_t _silence_countdown;
+ samplecnt_t _silence_countdown;
uint32_t _silence_hit_cnt;
-#endif
+#endif
};
-
+
} // namespace ARDOUR
#endif /* __ardour_audioengine_h__ */