summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2013-08-01 14:43:12 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2013-08-01 14:43:12 -0400
commit682ebad62bdc85df151ad0b81dc27cc9f3e71cec (patch)
tree3e283d18fa8609a1f98502a038b9388f8404285a /libs
parent18c68bfd12130b8a3e95c99d3c0472c8b7f377bc (diff)
full compilation and linking (coding not finished, will not run)
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/audio_backend.h15
-rw-r--r--libs/ardour/ardour/audioengine.h18
-rw-r--r--libs/ardour/ardour/jack_audiobackend.h2
-rw-r--r--libs/ardour/ardour/jack_portengine.h25
-rw-r--r--libs/ardour/ardour/port_engine.h21
-rw-r--r--libs/ardour/ardour/port_manager.h1
-rw-r--r--libs/ardour/ardour/slave.h6
-rw-r--r--libs/ardour/audioengine.cc178
-rw-r--r--libs/ardour/bundle.cc4
-rw-r--r--libs/ardour/jack_audiobackend.cc7
-rw-r--r--libs/ardour/jack_portengine.cc309
-rw-r--r--libs/ardour/jack_slave.cc33
-rw-r--r--libs/ardour/port.cc12
-rw-r--r--libs/ardour/port_manager.cc71
-rw-r--r--libs/ardour/route.cc10
-rw-r--r--libs/ardour/session.cc6
-rw-r--r--libs/ardour/session_export.cc2
-rw-r--r--libs/ardour/session_state.cc2
-rw-r--r--libs/ardour/session_transport.cc20
-rw-r--r--libs/ardour/wscript4
-rw-r--r--libs/midi++2/jack_midi_port.cc2
21 files changed, 536 insertions, 212 deletions
diff --git a/libs/ardour/ardour/audio_backend.h b/libs/ardour/ardour/audio_backend.h
index 44525c8353..3b68432b6f 100644
--- a/libs/ardour/ardour/audio_backend.h
+++ b/libs/ardour/ardour/audio_backend.h
@@ -296,18 +296,17 @@ class AudioBackend {
* It is extremely likely that any implementation will use a DLL, since
* this function can be called from any thread, at any time, and must be
* able to accurately determine the correct sample time.
+ *
+ * Can be called from any thread.
*/
virtual pframes_t sample_time () = 0;
- /** return the time according to the sample clock in use when the current
- * buffer process cycle began.
- *
- * Can ONLY be called from within a process() callback tree (which
- * implies that it can only be called by a process thread)
+ /** Return the time according to the sample clock in use when the most
+ * recent buffer process cycle began. Can be called from any thread.
*/
virtual pframes_t sample_time_at_cycle_start () = 0;
- /** return the time since the current buffer process cycle started,
+ /** Return the time since the current buffer process cycle started,
* in samples, according to the sample clock in use.
*
* Can ONLY be called from within a process() callback tree (which
@@ -315,7 +314,7 @@ class AudioBackend {
*/
virtual pframes_t samples_since_cycle_start () = 0;
- /** return true if it possible to determine the offset in samples of the
+ /** Return true if it possible to determine the offset in samples of the
* first video frame that starts within the current buffer process cycle,
* measured from the first sample of the cycle. If returning true,
* set @param offset to that offset.
@@ -339,6 +338,8 @@ class AudioBackend {
* when that function returns.
*/
virtual int create_process_thread (boost::function<void()> func, pthread_t*, size_t stacksize) = 0;
+
+ virtual void update_latencies () = 0;
protected:
AudioEngine& engine;
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
index 9e9da62ce0..0bbbe90ef4 100644
--- a/libs/ardour/ardour/audioengine.h
+++ b/libs/ardour/ardour/audioengine.h
@@ -108,6 +108,16 @@ public:
bool is_realtime() const;
bool connected() const;
+ int set_device_name (const std::string&);
+ int set_sample_rate (float);
+ int set_buffer_size (uint32_t);
+ int set_sample_format (SampleFormat);
+ int set_interleaved (bool yn);
+ int set_input_channels (uint32_t);
+ int set_output_channels (uint32_t);
+ int set_systemic_input_latency (uint32_t);
+ int set_systemic_output_latency (uint32_t);
+
/* END BACKEND PROXY API */
bool freewheeling() const { return _freewheeling; }
@@ -115,7 +125,9 @@ public:
Glib::Threads::Mutex& process_lock() { return _process_lock; }
- int request_buffer_size (pframes_t);
+ int request_buffer_size (pframes_t samples) {
+ return set_buffer_size (samples);
+ }
framecnt_t processed_frames() const { return _processed_frames; }
@@ -165,10 +177,6 @@ public:
PBD::Signal0<void> Running;
PBD::Signal0<void> Stopped;
- std::string make_port_name_relative (std::string) const;
- std::string make_port_name_non_relative (std::string) const;
- bool port_is_mine (const std::string&) const;
-
static AudioEngine* instance() { return _instance; }
static void destroy();
void died ();
diff --git a/libs/ardour/ardour/jack_audiobackend.h b/libs/ardour/ardour/jack_audiobackend.h
index 0855b8e90f..7104b814c2 100644
--- a/libs/ardour/ardour/jack_audiobackend.h
+++ b/libs/ardour/ardour/jack_audiobackend.h
@@ -99,6 +99,8 @@ class JACKAudioBackend : public AudioBackend {
int set_time_master (bool /*yn*/);
bool get_sync_offset (pframes_t& /*offset*/) const;
+ void update_latencies ();
+
private:
boost::shared_ptr<JackConnection> _jack_connection; //< shared with JACKPortEngine
bool _running;
diff --git a/libs/ardour/ardour/jack_portengine.h b/libs/ardour/ardour/jack_portengine.h
index 80e34f3c92..bee87532d3 100644
--- a/libs/ardour/ardour/jack_portengine.h
+++ b/libs/ardour/ardour/jack_portengine.h
@@ -38,8 +38,8 @@ class JACKPortEngine : public PortEngine
{
public:
JACKPortEngine (PortManager&, boost::shared_ptr<JackConnection>);
+ ~JACKPortEngine();
- bool connected() const;
void* private_handle() const;
const std::string& my_name() const;
@@ -48,10 +48,6 @@ class JACKPortEngine : public PortEngine
std::string get_port_name (PortHandle) const;
PortHandle* get_port_by_name (const std::string&) const;
- std::string make_port_name_relative (const std::string& name) const;
- std::string make_port_name_non_relative (const std::string& name) const;
- bool port_is_mine (const std::string& fullname) const;
-
int get_ports (const std::string& port_name_pattern, DataType type, PortFlags flags, std::vector<std::string>&) const;
DataType port_data_type (PortHandle) const;
@@ -62,19 +58,16 @@ class JACKPortEngine : public PortEngine
bool connected (PortHandle);
bool connected_to (PortHandle, const std::string&);
bool physically_connected (PortHandle);
-
int get_connections (PortHandle, std::vector<std::string>&);
-
int connect (PortHandle, const std::string&);
int disconnect (PortHandle, const std::string&);
int disconnect_all (PortHandle);
-
int connect (const std::string& src, const std::string& dst);
int disconnect (const std::string& src, const std::string& dst);
/* MIDI */
- void midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index);
+ int midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index);
int midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size);
uint32_t get_midi_event_count (void* port_buffer);
void midi_clear (void* port_buffer);
@@ -91,7 +84,8 @@ class JACKPortEngine : public PortEngine
void set_latency_range (PortHandle, bool for_playback, LatencyRange);
LatencyRange get_latency_range (PortHandle, bool for_playback);
- LatencyRange get_connected_latency_range (PortHandle, int dir);
+
+ /* Physical ports */
bool port_is_physical (PortHandle) const;
void get_physical_outputs (DataType type, std::vector<std::string>&);
@@ -99,9 +93,13 @@ class JACKPortEngine : public PortEngine
ChanCount n_physical_outputs () const;
ChanCount n_physical_inputs () const;
+ /* Getting access to the data buffer for a port */
+
void* get_buffer (PortHandle, pframes_t);
- framecnt_t last_frame_time () const;
+ /* Miscellany */
+
+ pframes_t sample_time_at_cycle_start ();
private:
boost::shared_ptr<JackConnection> _jack_connection;
@@ -110,10 +108,11 @@ class JACKPortEngine : public PortEngine
static void _registration_callback (jack_port_id_t, int, void *);
static void _connect_callback (jack_port_id_t, jack_port_id_t, int, void *);
- int graph_order_callback ();
-
void connect_callback (jack_port_id_t, jack_port_id_t, int);
+ ChanCount n_physical (unsigned long flags) const;
+ void get_physical (DataType type, unsigned long flags, std::vector<std::string>& phy) const;
+
};
} // namespace
diff --git a/libs/ardour/ardour/port_engine.h b/libs/ardour/ardour/port_engine.h
index 5992a48a85..e63c52630d 100644
--- a/libs/ardour/ardour/port_engine.h
+++ b/libs/ardour/ardour/port_engine.h
@@ -77,7 +77,7 @@ class PortManager;
class PortEngine {
public:
PortEngine (PortManager& pm) : manager (pm) {}
- virtual ~PortEngine();
+ virtual ~PortEngine() {}
/* We use void* here so that the API can be defined for any implementation.
*
@@ -89,7 +89,6 @@ class PortEngine {
typedef void* PortHandle;
- virtual bool connected() const = 0;
virtual void* private_handle() const = 0;
virtual const std::string& my_name() const = 0;
@@ -125,10 +124,10 @@ class PortEngine {
/* MIDI */
- virtual void midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index) = 0;
+ virtual int midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index) = 0;
virtual int midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size) = 0;
- virtual uint32_t get_midi_event_count (void* port_buffer);
- virtual void midi_clear (void* port_buffer);
+ virtual uint32_t get_midi_event_count (void* port_buffer) = 0;
+ virtual void midi_clear (void* port_buffer) = 0;
/* Monitoring */
@@ -142,7 +141,6 @@ class PortEngine {
virtual void set_latency_range (PortHandle, bool for_playback, LatencyRange) = 0;
virtual LatencyRange get_latency_range (PortHandle, bool for_playback) = 0;
- virtual LatencyRange get_connected_latency_range (PortHandle, int dir) = 0;
/* Discovering physical ports */
@@ -158,7 +156,16 @@ class PortEngine {
virtual void* get_buffer (PortHandle, pframes_t) = 0;
- virtual framecnt_t last_frame_time() const = 0;
+ /* MIDI ports (the ones in libmidi++) need this to be able to correctly
+ * schedule MIDI events within their buffers. It is a bit odd that we
+ * expose this here, because it is also exposed by AudioBackend, but they
+ * only have access to a PortEngine object, not an AudioBackend.
+ *
+ * Return the time according to the sample clock in use when the current
+ * buffer process cycle began.
+ *
+ */
+ virtual pframes_t sample_time_at_cycle_start () = 0;
protected:
PortManager& manager;
diff --git a/libs/ardour/ardour/port_manager.h b/libs/ardour/ardour/port_manager.h
index 5838ac66af..d88143d110 100644
--- a/libs/ardour/ardour/port_manager.h
+++ b/libs/ardour/ardour/port_manager.h
@@ -59,7 +59,6 @@ class PortManager
int connect (const std::string& source, const std::string& destination);
int disconnect (const std::string& source, const std::string& destination);
int disconnect (boost::shared_ptr<Port>);
- bool has_connections (const std::string&);
int reestablish_ports ();
int reconnect_ports ();
diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h
index 88c9a09be7..4408da2d25 100644
--- a/libs/ardour/ardour/slave.h
+++ b/libs/ardour/ardour/slave.h
@@ -48,6 +48,7 @@ namespace ARDOUR {
class TempoMap;
class Session;
+class AudioEngine;
/**
* @class Slave
@@ -492,7 +493,7 @@ class MIDIClock_Slave : public Slave {
class JACK_Slave : public Slave
{
public:
- JACK_Slave (jack_client_t*);
+ JACK_Slave (AudioEngine&);
~JACK_Slave ();
bool speed_and_position (double& speed, framepos_t& pos);
@@ -502,11 +503,10 @@ class JACK_Slave : public Slave
bool ok() const;
framecnt_t resolution () const { return 1; }
bool requires_seekahead () const { return false; }
- void reset_client (jack_client_t* jack);
bool is_always_synced() const { return true; }
private:
- jack_client_t* jack;
+ AudioEngine& engine;
double speed;
bool _starting;
};
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 3d1bf6e77e..05f59707a8 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -104,39 +104,6 @@ AudioEngine::create (const std::string& bcn, const std::string& bsu)
}
void
-AudioEngine::drop_backend ()
-{
- if (_backend) {
- _backend->stop ();
- _backend.reset ();
- }
-}
-
-int
-AudioEngine::set_backend (const std::string& name)
-{
- BackendMap::iterator b = _backends.find (name);
-
- if (b == _backends.end()) {
- return -1;
- }
-
- drop_backend ();
-
- try {
-
- _backend = b->second->backend_factory (*this);
- _impl = b->second->portengine_factory (*this);
-
- } catch (...) {
- error << string_compose (_("Could not create backend for %1"), name) << endmsg;
- return -1;
- }
-
- return 0;
-}
-
-void
_thread_init_callback (void * /*arg*/)
{
/* make sure that anybody who needs to know about this thread
@@ -570,6 +537,60 @@ AudioEngine::backend_discover (const string& path)
return info;
}
+vector<string>
+AudioEngine::available_backends() const
+{
+ vector<string> r;
+
+ for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
+ r.push_back (i->first);
+ }
+
+ return r;
+}
+
+string
+AudioEngine::current_backend_name() const
+{
+ if (_backend) {
+ return _backend->name();
+ }
+ return string();
+}
+
+void
+AudioEngine::drop_backend ()
+{
+ if (_backend) {
+ _backend->stop ();
+ _backend.reset ();
+ }
+}
+
+int
+AudioEngine::set_backend (const std::string& name)
+{
+ BackendMap::iterator b = _backends.find (name);
+
+ if (b == _backends.end()) {
+ return -1;
+ }
+
+ drop_backend ();
+
+ try {
+
+ _backend = b->second->backend_factory (*this);
+ _impl = b->second->portengine_factory (*this);
+
+ } catch (...) {
+ error << string_compose (_("Could not create backend for %1"), name) << endmsg;
+ return -1;
+ }
+
+ return 0;
+}
+
/* BACKEND PROXY WRAPPERS */
int
@@ -812,6 +833,89 @@ AudioEngine::create_process_thread (boost::function<void()> func, pthread_t* thr
}
+int
+AudioEngine::set_device_name (const std::string& name)
+{
+ if (!_backend) {
+ return -1;
+ }
+ return _backend->set_device_name (name);
+}
+
+int
+AudioEngine::set_sample_rate (float sr)
+{
+ if (!_backend) {
+ return -1;
+ }
+ return _backend->set_sample_rate (sr);
+}
+
+int
+AudioEngine::set_buffer_size (uint32_t bufsiz)
+{
+ if (!_backend) {
+ return -1;
+ }
+ return _backend->set_buffer_size (bufsiz);
+}
+
+int
+AudioEngine::set_sample_format (SampleFormat sf)
+{
+ if (!_backend) {
+ return -1;
+ }
+ return _backend->set_sample_format (sf);
+}
+
+int
+AudioEngine::set_interleaved (bool yn)
+{
+ if (!_backend) {
+ return -1;
+ }
+ return _backend->set_interleaved (yn);
+}
+
+int
+AudioEngine::set_input_channels (uint32_t ic)
+{
+ if (!_backend) {
+ return -1;
+ }
+ return _backend->set_input_channels (ic);
+}
+
+int
+AudioEngine::set_output_channels (uint32_t oc)
+{
+ if (!_backend) {
+ return -1;
+ }
+ return _backend->set_output_channels (oc);
+}
+
+int
+AudioEngine::set_systemic_input_latency (uint32_t il)
+{
+ if (!_backend) {
+ return -1;
+ }
+ return _backend->set_systemic_input_latency (il);
+}
+
+int
+AudioEngine::set_systemic_output_latency (uint32_t ol)
+{
+ if (!_backend) {
+ return -1;
+ }
+ return _backend->set_systemic_output_latency (ol);
+}
+
+/* END OF BACKEND PROXY API */
+
void
AudioEngine::thread_init_callback (void* arg)
{
@@ -874,6 +978,14 @@ AudioEngine::latency_callback (bool for_playback)
}
void
+AudioEngine::update_latencies ()
+{
+ if (_backend) {
+ _backend->update_latencies ();
+ }
+}
+
+void
AudioEngine::halted_callback (const char* why)
{
stop_metering_thread ();
diff --git a/libs/ardour/bundle.cc b/libs/ardour/bundle.cc
index 162db6c793..be4b04e36a 100644
--- a/libs/ardour/bundle.cc
+++ b/libs/ardour/bundle.cc
@@ -450,6 +450,8 @@ Bundle::connected_to (boost::shared_ptr<Bundle> other, AudioEngine & engine)
bool
Bundle::connected_to_anything (AudioEngine& engine)
{
+ PortManager& pm (engine);
+
for (uint32_t i = 0; i < nchannels().n_total(); ++i) {
Bundle::PortList const & ports = channel_ports (i);
@@ -459,7 +461,7 @@ Bundle::connected_to_anything (AudioEngine& engine)
rather than doing it with Port.
*/
- if (engine.has_connections (ports[j])) {
+ if (pm.connected (ports[j])) {
return true;
}
}
diff --git a/libs/ardour/jack_audiobackend.cc b/libs/ardour/jack_audiobackend.cc
index b993135f5a..04ee94a80c 100644
--- a/libs/ardour/jack_audiobackend.cc
+++ b/libs/ardour/jack_audiobackend.cc
@@ -818,3 +818,10 @@ JACKAudioBackend::cpu_load() const
GET_PRIVATE_JACK_POINTER_RET(_priv_jack,0);
return jack_cpu_load (_priv_jack);
}
+
+void
+JACKAudioBackend::update_latencies ()
+{
+ GET_PRIVATE_JACK_POINTER (_priv_jack);
+ jack_recompute_total_latencies (_priv_jack);
+}
diff --git a/libs/ardour/jack_portengine.cc b/libs/ardour/jack_portengine.cc
index 4a6f3a1fca..7280c9ff24 100644
--- a/libs/ardour/jack_portengine.cc
+++ b/libs/ardour/jack_portengine.cc
@@ -1,3 +1,35 @@
+/*
+ Copyright (C) 2013 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.
+
+*/
+
+#include <string.h>
+#include <stdint.h>
+
+#include "pbd/failed_constructor.h"
+
+#include "ardour/jack_portengine.h"
+#include "ardour/jack_connection.h"
+#include "ardour/port_manager.h"
+
+using namespace ARDOUR;
+using std::string;
+using std::vector;
+
#define GET_PRIVATE_JACK_POINTER(localvar) jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return; }
#define GET_PRIVATE_JACK_POINTER_RET(localvar,r) jack_client_t* localvar = _jack_connection->jack(); if (!(localvar)) { return r; }
@@ -6,13 +38,13 @@ ardour_port_flags_to_jack_flags (PortFlags flags)
{
uint32_t jack_flags = 0;
- if (flags & PortIsInput) {
+ if (flags & IsInput) {
jack_flags |= JackPortIsInput;
}
- if (flags & IsInput) {
+ if (flags & IsOutput) {
jack_flags |= JackPortIsOutput;
}
- if (flags & IsOutput) {
+ if (flags & IsTerminal) {
jack_flags |= JackPortIsTerminal;
}
if (flags & IsPhysical) {
@@ -53,17 +85,63 @@ JACKPortEngine::JACKPortEngine (PortManager& pm, boost::shared_ptr<JackConnectio
: PortEngine (pm)
, _jack_connection (jc)
{
- jack_client_t* client = _jack_connection->
+ jack_client_t* client = _jack_connection->jack();
+
+ if (!client) {
+ throw failed_constructor ();
+ }
+
+ /* register callbacks for stuff that is our responsibility */
+
+ jack_set_port_registration_callback (client, _registration_callback, this);
+ jack_set_port_connect_callback (client, _connect_callback, this);
+ jack_set_graph_order_callback (client, _graph_order_callback, this);
+}
+
+JACKPortEngine::~JACKPortEngine ()
+{
+ /* a default destructor would do this, and so would this one,
+ but we'll make it explicit in case we ever need to debug
+ the lifetime of the JACKConnection
+ */
+ _jack_connection.reset ();
+}
+
+void*
+JACKPortEngine::private_handle() const
+{
+ return _jack_connection->jack();
+}
+
+int
+JACKPortEngine::set_port_name (PortHandle port, const std::string& name)
+{
+ return jack_port_set_name ((jack_port_t*) port, name.c_str());
+}
+
+string
+JACKPortEngine::get_port_name (PortHandle port) const
+{
+ return jack_port_name ((jack_port_t*) port);
+}
- jack_set_port_registration_callback (_priv_jack, _registration_callback, this);
- jack_set_port_connect_callback (_priv_jack, _connect_callback, this);
- jack_set_graph_order_callback (_priv_jack, _graph_order_callback, this);
+PortEngine::PortHandle*
+JACKPortEngine:: get_port_by_name (const std::string& name) const
+{
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack, 0);
+ return (PortHandle*) jack_port_by_name (_priv_jack, name.c_str());
}
void
JACKPortEngine::_registration_callback (jack_port_id_t /*id*/, int /*reg*/, void* arg)
{
- static_cast<JACKPortEngine*> (arg)->_manager->registration_callback ();
+ static_cast<JACKPortEngine*> (arg)->manager.registration_callback ();
+}
+
+int
+JACKPortEngine::_graph_order_callback (void *arg)
+{
+ return static_cast<JACKPortEngine*> (arg)->manager.graph_order_callback ();
}
void
@@ -75,7 +153,7 @@ JACKPortEngine::_connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int
void
JACKPortEngine::connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int conn)
{
- if (_manager->port_remove_in_progress()) {
+ if (manager.port_remove_in_progress()) {
return;
}
@@ -84,79 +162,90 @@ JACKPortEngine::connect_callback (jack_port_id_t id_a, jack_port_id_t id_b, int
jack_port_t* a = jack_port_by_id (_priv_jack, id_a);
jack_port_t* b = jack_port_by_id (_priv_jack, id_b);
- _manager->connect_callback (jack_port_name (a), jack_port_name (b), conn == 0 ? false : true);
+ manager.connect_callback (jack_port_name (a), jack_port_name (b), conn == 0 ? false : true);
}
-int
-JACKPortEngine::_graph_order_callback (void *arg)
+bool
+JACKPortEngine::connected (PortHandle port)
{
- return static_cast<JACKPortEngine*> (arg)->graph_order_callback ();
+ bool ret = false;
+
+ const char** ports = jack_port_get_connections ((jack_port_t*) port);
+
+ if (ports) {
+ ret = true;
+ }
+
+ jack_free (ports);
+
+ return ret;
}
-int
-JACKPortEngine::graph_order_callback ()
+bool
+JACKPortEngine::connected_to (PortHandle port, const std::string& other)
{
- if (_jack_connection->connected()) {
- _manager->graph_order_callback ();
+ bool ret = false;
+ const char** ports = jack_port_get_connections ((jack_port_t*) port);
+
+ if (ports) {
+ for (int i = 0; ports[i]; ++i) {
+ if (other == ports[i]) {
+ ret = true;
+ }
+ }
+ jack_free (ports);
}
- return 0;
+ return ret;
}
+bool
JACKPortEngine::physically_connected (PortHandle p)
{
- jack_port_t* _jack_port = (jack_port_t*) p;
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack, false);
+ jack_port_t* port = (jack_port_t*) p;
- const char** jc = jack_port_get_connections (_jack_port);
+ const char** ports = jack_port_get_connections (port);
- if (jc) {
- for (int i = 0; jc[i]; ++i) {
+ if (ports) {
+ for (int i = 0; ports[i]; ++i) {
- jack_port_t* port = jack_port_by_name (_engine->jack(), jc[i]);
+ jack_port_t* other = jack_port_by_name (_priv_jack, ports[i]);
- if (port && (jack_port_flags (port) & JackPortIsPhysical)) {
- if (jack_free) {
- jack_free (jc);
- } else {
- free (jc);
- }
+ if (other && (jack_port_flags (other) & JackPortIsPhysical)) {
return true;
}
}
- if (jack_free) {
- jack_free (jc);
- } else {
- free (jc);
- }
+ jack_free (ports);
}
return false;
}
DataType
-JACKPortEngine::port_data_type (PortHandle p)
+JACKPortEngine::port_data_type (PortHandle p) const
{
- return jack_port_type_to_ardour_data_type (jack_port_type (p));
+ return jack_port_type_to_ardour_data_type (jack_port_type ((jack_port_t*) p));
}
const string&
JACKPortEngine::my_name() const
{
- return _client_name;
+ return _jack_connection->client_name();
}
bool
-JACKPortEngine::port_is_physical (PortHandle* ph) const
+JACKPortEngine::port_is_physical (PortHandle ph) const
{
if (!ph) {
return false;
}
- return jack_port_flags (ph) & JackPortIsPhysical;
+ return jack_port_flags ((jack_port_t*) ph) & JackPortIsPhysical;
}
int
-JACKPortEngine::get_ports (const string& port_name_pattern, DataType type, PortFlags flags, vector<string>& s)
+JACKPortEngine::get_ports (const string& port_name_pattern, DataType type, PortFlags flags, vector<string>& s) const
{
GET_PRIVATE_JACK_POINTER_RET (_priv_jack,0);
@@ -166,12 +255,11 @@ JACKPortEngine::get_ports (const string& port_name_pattern, DataType type, PortF
ardour_port_flags_to_jack_flags (flags));
if (ports == 0) {
- return s;
+ return 0;
}
for (uint32_t i = 0; ports[i]; ++i) {
s.push_back (ports[i]);
- jack_free (ports[i]);
}
jack_free (ports);
@@ -184,16 +272,15 @@ JACKPortEngine::n_physical (unsigned long flags) const
{
ChanCount c;
- GET_PRIVATE_JACK_POINTER_RET (_jack, c);
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack, c);
const char ** ports = jack_get_ports (_priv_jack, NULL, NULL, JackPortIsPhysical | flags);
if (ports) {
for (uint32_t i = 0; ports[i]; ++i) {
if (!strstr (ports[i], "Midi-Through")) {
- DataType t (jack_port_type (jack_port_by_name (_jack, ports[i])));
+ DataType t (jack_port_type (jack_port_by_name (_priv_jack, ports[i])));
c.set (t, c.get (t) + 1);
- jack_free (ports[i]);
}
}
@@ -216,12 +303,12 @@ JACKPortEngine::n_physical_outputs () const
}
void
-JACKPortEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy)
+JACKPortEngine::get_physical (DataType type, unsigned long flags, vector<string>& phy) const
{
GET_PRIVATE_JACK_POINTER (_priv_jack);
const char ** ports;
- if ((ports = jack_get_ports (_priv_jack, NULL, type.to_jack_type(), JackPortIsPhysical | flags)) == 0) {
+ if ((ports = jack_get_ports (_priv_jack, NULL, ardour_data_type_to_jack_port_type (type), JackPortIsPhysical | flags)) == 0) {
return;
}
@@ -231,7 +318,6 @@ JACKPortEngine::get_physical (DataType type, unsigned long flags, vector<string>
continue;
}
phy.push_back (ports[i]);
- jack_free (ports[i]);
}
jack_free (ports);
}
@@ -257,7 +343,7 @@ JACKPortEngine::get_physical_outputs (DataType type, vector<string>& outs)
bool
-JACKPortEngine::can_request_hardware_monitoring ()
+JACKPortEngine::can_monitor_input () const
{
GET_PRIVATE_JACK_POINTER_RET (_priv_jack,false);
const char ** ports;
@@ -266,18 +352,131 @@ JACKPortEngine::can_request_hardware_monitoring ()
return false;
}
- for (uint32_t i = 0; ports[i]; ++i) {
- jack_free (ports[i]);
- }
-
jack_free (ports);
return true;
}
-framecnt_t
-JACKPortEngine::last_frame_time () const
+pframes_t
+JACKPortEngine::sample_time_at_cycle_start ()
{
GET_PRIVATE_JACK_POINTER_RET (_priv_jack, 0);
return jack_last_frame_time (_priv_jack);
}
+
+
+PortEngine::PortHandle
+JACKPortEngine::register_port (const std::string& shortname, ARDOUR::DataType type, ARDOUR::PortFlags flags)
+{
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack, 0);
+ return jack_port_register (_priv_jack, shortname.c_str(),
+ ardour_data_type_to_jack_port_type (type),
+ ardour_port_flags_to_jack_flags (flags),
+ 0);
+}
+
+void
+JACKPortEngine::unregister_port (PortHandle port)
+{
+ GET_PRIVATE_JACK_POINTER (_priv_jack);
+ (void) jack_port_unregister (_priv_jack, (jack_port_t*) port);
+}
+
+int
+JACKPortEngine::connect (PortHandle port, const std::string& other)
+{
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
+ return jack_connect (_priv_jack, jack_port_name ((jack_port_t*) port), other.c_str());
+}
+int
+JACKPortEngine::connect (const std::string& src, const std::string& dst)
+{
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
+ return jack_connect (_priv_jack, src.c_str(), dst.c_str());
+}
+
+int
+JACKPortEngine::disconnect (PortHandle port, const std::string& other)
+{
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
+ return jack_disconnect (_priv_jack, jack_port_name ((jack_port_t*) port), other.c_str());
+}
+
+int
+JACKPortEngine::disconnect (const std::string& src, const std::string& dst)
+{
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
+ return jack_disconnect (_priv_jack, src.c_str(), dst.c_str());
+}
+
+int
+JACKPortEngine::disconnect_all (PortHandle port)
+{
+ GET_PRIVATE_JACK_POINTER_RET (_priv_jack, -1);
+ return jack_port_disconnect (_priv_jack, (jack_port_t*) port);
+}
+
+
+int
+JACKPortEngine::midi_event_get (pframes_t& timestamp, size_t& size, uint8_t** buf, void* port_buffer, uint32_t event_index)
+{
+ jack_midi_event_t ev;
+ int ret;
+
+ if ((ret = jack_midi_event_get (&ev, port_buffer, event_index)) == 0) {
+ timestamp = ev.time;
+ size = ev.size;
+ *buf = ev.buffer;
+ }
+
+ return ret;
+}
+
+int
+JACKPortEngine::midi_event_put (void* port_buffer, pframes_t timestamp, const uint8_t* buffer, size_t size)
+{
+ return jack_midi_event_write (port_buffer, timestamp, buffer, size);
+}
+
+uint32_t
+JACKPortEngine::get_midi_event_count (void* port_buffer)
+{
+ return jack_midi_get_event_count (port_buffer);
+}
+
+void
+JACKPortEngine::midi_clear (void* port_buffer)
+{
+ jack_midi_clear_buffer (port_buffer);
+}
+
+void
+JACKPortEngine::set_latency_range (PortHandle port, bool for_playback, LatencyRange r)
+{
+ jack_latency_range_t range;
+
+ range.min = r.min;
+ range.max = r.max;
+
+ jack_port_set_latency_range ((jack_port_t*) port, for_playback ? JackPlaybackLatency : JackCaptureLatency, &range);
+}
+
+LatencyRange
+JACKPortEngine::get_latency_range (PortHandle port, bool for_playback)
+{
+ jack_latency_range_t range;
+ LatencyRange ret;
+
+ jack_port_get_latency_range ((jack_port_t*) port, for_playback ? JackPlaybackLatency : JackCaptureLatency, &range);
+
+ ret.min = range.min;
+ ret.max = range.max;
+
+ return ret;
+}
+
+void*
+JACKPortEngine::get_buffer (PortHandle port, pframes_t nframes)
+{
+ return jack_port_get_buffer ((jack_port_t*) port, nframes);
+}
diff --git a/libs/ardour/jack_slave.cc b/libs/ardour/jack_slave.cc
index 4c2da4c6c4..4b2f3b1860 100644
--- a/libs/ardour/jack_slave.cc
+++ b/libs/ardour/jack_slave.cc
@@ -20,16 +20,14 @@
#include <iostream>
#include <cerrno>
-#include <jack/jack.h>
-#include <jack/transport.h>
-
+#include "ardour/audioengine.h"
#include "ardour/slave.h"
using namespace std;
using namespace ARDOUR;
-JACK_Slave::JACK_Slave (jack_client_t* j)
- : jack (j)
+JACK_Slave::JACK_Slave (AudioEngine& e)
+ : engine (e)
{
double x;
framepos_t p;
@@ -41,12 +39,6 @@ JACK_Slave::~JACK_Slave ()
{
}
-void
-JACK_Slave::reset_client (jack_client_t* j)
-{
- jack = j;
-}
-
bool
JACK_Slave::locked() const
{
@@ -62,33 +54,26 @@ JACK_Slave::ok() const
bool
JACK_Slave::speed_and_position (double& sp, framepos_t& position)
{
- jack_position_t pos;
- jack_transport_state_t state;
-
- state = jack_transport_query (jack, &pos);
-
- switch (state) {
- case JackTransportStopped:
+ switch (engine.transport_state()) {
+ case TransportStopped:
speed = 0;
_starting = false;
break;
- case JackTransportRolling:
+ case TransportRolling:
speed = 1.0;
_starting = false;
break;
- case JackTransportLooping:
+ case TransportLooping:
speed = 1.0;
_starting = false;
break;
- case JackTransportStarting:
+ case TransportStarting:
_starting = true;
// don't adjust speed here, just leave it as it was
break;
- default:
- cerr << "WARNING: Unknown JACK transport state: " << state << endl;
}
sp = speed;
- position = pos.frame;
+ position = engine.transport_frame();
return true;
}
diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc
index 5aa6ad0ae7..571d227711 100644
--- a/libs/ardour/port.cc
+++ b/libs/ardour/port.cc
@@ -70,10 +70,6 @@ Port::Port (std::string const & n, DataType t, PortFlags f)
assert (_name.find_first_of (':') == std::string::npos);
- if (!port_engine.connected()) {
- throw failed_constructor ();
- }
-
if ((_port_handle = port_engine.register_port (_name, t, _flags)) == 0) {
cerr << "Failed to register port \"" << _name << "\", reason is unknown from here\n";
throw failed_constructor ();
@@ -124,14 +120,6 @@ Port::disconnect_all ()
bool
Port::connected_to (std::string const & o) const
{
- if (!port_engine.connected()) {
- /* in some senses, this answer isn't the right one all the time,
- because we know about our connections and will re-establish
- them when we reconnect to the port engine.
- */
- return false;
- }
-
return port_engine.connected_to (_port_handle, AudioEngine::instance()->make_port_name_non_relative (o));
}
diff --git a/libs/ardour/port_manager.cc b/libs/ardour/port_manager.cc
index 9c5eaa998b..b5f280292e 100644
--- a/libs/ardour/port_manager.cc
+++ b/libs/ardour/port_manager.cc
@@ -127,6 +127,30 @@ PortManager::port_is_physical (const std::string& portname) const
return _impl->port_is_physical (ph);
}
+void
+PortManager::get_physical_outputs (DataType type, std::vector<std::string>& s)
+{
+ _impl->get_physical_outputs (type, s);
+}
+
+void
+PortManager::get_physical_inputs (DataType type, std::vector<std::string>& s)
+{
+ _impl->get_physical_inputs (type, s);
+}
+
+ChanCount
+PortManager::n_physical_outputs () const
+{
+ return _impl->n_physical_outputs ();
+}
+
+ChanCount
+PortManager::n_physical_inputs () const
+{
+ return _impl->n_physical_inputs ();
+}
+
/** @param name Full or short name of port
* @return Corresponding Port or 0.
*/
@@ -134,11 +158,6 @@ PortManager::port_is_physical (const std::string& portname) const
boost::shared_ptr<Port>
PortManager::get_port_by_name (const string& portname)
{
- if (!_impl->connected()) {
- fatal << _("get_port_by_name() called before engine was started") << endmsg;
- /*NOTREACHED*/
- }
-
if (!port_is_mine (portname)) {
/* not an ardour port */
return boost::shared_ptr<Port> ();
@@ -254,13 +273,6 @@ PortManager::unregister_port (boost::shared_ptr<Port> port)
{
/* caller must hold process lock */
- if (!_impl->connected()) {
- /* probably happening when the engine has been halted by JACK,
- in which case, there is nothing we can do here.
- */
- return 0;
- }
-
{
RCUWriter<Ports> writer (ports);
boost::shared_ptr<Ports> ps = writer.get_copy ();
@@ -295,10 +307,6 @@ PortManager::connect (const string& source, const string& destination)
{
int ret;
- if (!_impl->connected()) {
- return -1;
- }
-
string s = make_port_name_non_relative (source);
string d = make_port_name_non_relative (destination);
@@ -330,10 +338,6 @@ PortManager::disconnect (const string& source, const string& destination)
{
int ret;
- if (!_impl->connected()) {
- return -1;
- }
-
string s = make_port_name_non_relative (source);
string d = make_port_name_non_relative (destination);
@@ -429,3 +433,30 @@ PortManager::registration_callback ()
PortRegisteredOrUnregistered (); /* EMIT SIGNAL */
}
}
+
+bool
+PortManager::can_request_input_monitoring () const
+{
+ return _impl->can_monitor_input ();
+}
+
+void
+PortManager::request_input_monitoring (const string& name, bool yn) const
+{
+ PortEngine::PortHandle ph = _impl->get_port_by_name (name);
+
+ if (ph) {
+ _impl->request_input_monitoring (ph, yn);
+ }
+}
+
+void
+PortManager::ensure_input_monitoring (const string& name, bool yn) const
+{
+ PortEngine::PortHandle ph = _impl->get_port_by_name (name);
+
+ if (ph) {
+ _impl->ensure_input_monitoring (ph, yn);
+ }
+}
+
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index c2965a4617..eabfbaacc0 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -967,7 +967,7 @@ Route::add_processor (boost::shared_ptr<Processor> processor, boost::shared_ptr<
DEBUG_TRACE (DEBUG::Processors, string_compose (
"%1 adding processor %2\n", name(), processor->name()));
- if (!AudioEngine::instance()->port_engine().connected() || !processor) {
+ if (!AudioEngine::instance()->connected() || !processor) {
return 1;
}
@@ -1132,7 +1132,7 @@ Route::add_processors (const ProcessorList& others, boost::shared_ptr<Processor>
loc = _processors.end ();
}
- if (!_session.engine().port_engine().connected()) {
+ if (!_session.engine().connected()) {
return 1;
}
@@ -1329,7 +1329,7 @@ Route::ab_plugins (bool forward)
void
Route::clear_processors (Placement p)
{
- if (!_session.engine().port_engine().connected()) {
+ if (!_session.engine().connected()) {
return;
}
@@ -1416,7 +1416,7 @@ Route::remove_processor (boost::shared_ptr<Processor> processor, ProcessorStream
return 0;
}
- if (!_session.engine().port_engine().connected()) {
+ if (!_session.engine().connected()) {
return 1;
}
@@ -1508,7 +1508,7 @@ Route::remove_processors (const ProcessorList& to_be_deleted, ProcessorStreams*
{
ProcessorList deleted;
- if (!_session.engine().port_engine().connected()) {
+ if (!_session.engine().connected()) {
return 1;
}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 1ea3732e3f..e1634db536 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -170,7 +170,7 @@ Session::Session (AudioEngine &eng,
interpolation.add_channel_to (0, 0);
- if (!eng.port_engine().connected()) {
+ if (!eng.connected()) {
throw failed_constructor();
}
@@ -4677,7 +4677,7 @@ Session::set_worst_playback_latency ()
_worst_output_latency = 0;
- if (!_engine.port_engine().connected()) {
+ if (!_engine.connected()) {
return;
}
@@ -4699,7 +4699,7 @@ Session::set_worst_capture_latency ()
_worst_input_latency = 0;
- if (!_engine.port_engine().connected()) {
+ if (!_engine.connected()) {
return;
}
diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc
index 02bf48a0d6..0db4fc33bb 100644
--- a/libs/ardour/session_export.cc
+++ b/libs/ardour/session_export.cc
@@ -147,7 +147,7 @@ Session::start_audio_export (framepos_t position)
/* we are ready to go ... */
- if (!_engine.port_engine().connected()) {
+ if (!_engine.connected()) {
return -1;
}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index aa0c90204d..cae3b9720a 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -765,7 +765,7 @@ Session::save_state (string snapshot_name, bool pending, bool switch_to_snapshot
return 1;
}
- if (!_engine.port_engine().connected ()) {
+ if (!_engine.connected ()) {
error << string_compose (_("the %1 audio engine is not connected and state saving would lose all I/O connections. Session not saved"),
PROGRAM_NAME)
<< endmsg;
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index fea2fcd96a..0b0351f506 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -44,7 +44,6 @@
#include "ardour/session.h"
#include "ardour/slave.h"
#include "ardour/operations.h"
-#include "ardour/jack_portengine.h"
#include "i18n.h"
@@ -1417,13 +1416,6 @@ Session::switch_to_sync_source (SyncSource src)
break;
case JACK:
- /* if we are not using JACK as the port engine, we can't do
- * this
- */
- if (dynamic_cast<JACKPortEngine*>(&AudioEngine::instance()->port_engine())) {
- return;
- }
-
if (_slave && dynamic_cast<JACK_Slave*>(_slave)) {
return;
}
@@ -1432,7 +1424,7 @@ Session::switch_to_sync_source (SyncSource src)
return;
}
- new_slave = new JACK_Slave ((jack_client_t*) AudioEngine::instance()->port_engine().private_handle());
+ new_slave = new JACK_Slave (*AudioEngine::instance());
break;
default:
@@ -1622,16 +1614,6 @@ Session::allow_auto_play (bool yn)
auto_play_legal = yn;
}
-void
-Session::reset_jack_connection (jack_client_t* jack)
-{
- JACK_Slave* js;
-
- if (_slave && ((js = dynamic_cast<JACK_Slave*> (_slave)) != 0)) {
- js->reset_client (jack);
- }
-}
-
bool
Session::maybe_stop (framepos_t limit)
{
diff --git a/libs/ardour/wscript b/libs/ardour/wscript
index 48cfda7bc2..07bb10f08d 100644
--- a/libs/ardour/wscript
+++ b/libs/ardour/wscript
@@ -43,6 +43,7 @@ libardour_sources = [
'automation_control.cc',
'automation_list.cc',
'automation_watch.cc',
+ 'backend_search_path.cc',
'beats_frames_converter.cc',
'broadcast_info.cc',
'buffer.cc',
@@ -439,7 +440,8 @@ def build(bld):
source = [
'jack_api.cc',
'jack_connection.cc',
- 'jack_audiobackend.cc'
+ 'jack_audiobackend.cc',
+ 'jack_portengine.cc'
])
obj.cxxflags = [ '-fPIC' ]
obj.name = 'jack_audiobackend'
diff --git a/libs/midi++2/jack_midi_port.cc b/libs/midi++2/jack_midi_port.cc
index 372a7891c9..8ba27759bc 100644
--- a/libs/midi++2/jack_midi_port.cc
+++ b/libs/midi++2/jack_midi_port.cc
@@ -155,7 +155,7 @@ JackMIDIPort::cycle_start (pframes_t nframes)
pframes_t time;
size_t size;
uint8_t* buf;
- timestamp_t cycle_start_frame = _port_engine.last_frame_time ();
+ timestamp_t cycle_start_frame = _port_engine.sample_time_at_cycle_start ();
for (pframes_t i = 0; i < event_count; ++i) {
_port_engine.midi_event_get (time, size, &buf, buffer, i);