13
0

full compilation and linking (coding not finished, will not run)

This commit is contained in:
Paul Davis 2013-08-01 14:43:12 -04:00
parent 18c68bfd12
commit 682ebad62b
21 changed files with 538 additions and 214 deletions

View File

@ -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;

View File

@ -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 ();

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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 ();

View File

@ -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;
};

View File

@ -103,39 +103,6 @@ AudioEngine::create (const std::string& bcn, const std::string& bsu)
return new AudioEngine (bcn, 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*/)
{
@ -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)
{
@ -873,6 +977,14 @@ AudioEngine::latency_callback (bool for_playback)
}
}
void
AudioEngine::update_latencies ()
{
if (_backend) {
_backend->update_latencies ();
}
}
void
AudioEngine::halted_callback (const char* why)
{

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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();
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);
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);
}
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;
int
JACKPortEngine::graph_order_callback ()
{
if (_jack_connection->connected()) {
_manager->graph_order_callback ();
const char** ports = jack_port_get_connections ((jack_port_t*) port);
if (ports) {
ret = true;
}
return 0;
jack_free (ports);
return ret;
}
bool
JACKPortEngine::connected_to (PortHandle port, const std::string& other)
{
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 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);
}

View File

@ -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;
}

View File

@ -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));
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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)
{

View File

@ -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'

View File

@ -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);