mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 14:54:56 +01:00
audioengine branch can now load and run at least one test session.
currently hard-coded to deal only with the situation where JACK is already running
This commit is contained in:
parent
df59a000b7
commit
1c4d00e8b7
13 changed files with 131 additions and 72 deletions
|
|
@ -61,6 +61,7 @@
|
||||||
#include "midi++/manager.h"
|
#include "midi++/manager.h"
|
||||||
|
|
||||||
#include "ardour/ardour.h"
|
#include "ardour/ardour.h"
|
||||||
|
#include "ardour/audio_backend.h"
|
||||||
#include "ardour/audioengine.h"
|
#include "ardour/audioengine.h"
|
||||||
#include "ardour/audiofilesource.h"
|
#include "ardour/audiofilesource.h"
|
||||||
#include "ardour/automation_watch.h"
|
#include "ardour/automation_watch.h"
|
||||||
|
|
@ -373,6 +374,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
|
||||||
_process_thread->init ();
|
_process_thread->init ();
|
||||||
|
|
||||||
DPIReset.connect (sigc::mem_fun (*this, &ARDOUR_UI::resize_text_widgets));
|
DPIReset.connect (sigc::mem_fun (*this, &ARDOUR_UI::resize_text_widgets));
|
||||||
|
|
||||||
|
attach_to_engine ();
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalPortMatrixWindow*
|
GlobalPortMatrixWindow*
|
||||||
|
|
@ -384,18 +387,10 @@ ARDOUR_UI::create_global_port_matrix (ARDOUR::DataType type)
|
||||||
return new GlobalPortMatrixWindow (_session, type);
|
return new GlobalPortMatrixWindow (_session, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
ARDOUR_UI::create_engine ()
|
ARDOUR_UI::attach_to_engine ()
|
||||||
{
|
{
|
||||||
// this gets called every time by new_session()
|
engine = AudioEngine::instance();
|
||||||
|
|
||||||
if (engine) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
loading_message (_("Starting audio engine"));
|
|
||||||
|
|
||||||
AudioEngine* engine = AudioEngine::instance();
|
|
||||||
|
|
||||||
engine->Stopped.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_stopped, this), gui_context());
|
engine->Stopped.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_stopped, this), gui_context());
|
||||||
engine->Running.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_running, this), gui_context());
|
engine->Running.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_running, this), gui_context());
|
||||||
|
|
@ -405,8 +400,6 @@ ARDOUR_UI::create_engine ()
|
||||||
engine->BackendAvailable.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::post_engine, this));
|
engine->BackendAvailable.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::post_engine, this));
|
||||||
|
|
||||||
ARDOUR::Port::set_connecting_blocked (ARDOUR_COMMAND_LINE::no_connect_ports);
|
ARDOUR::Port::set_connecting_blocked (ARDOUR_COMMAND_LINE::no_connect_ports);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -414,7 +407,7 @@ ARDOUR_UI::post_engine ()
|
||||||
{
|
{
|
||||||
cerr << "Backend available!\n";
|
cerr << "Backend available!\n";
|
||||||
|
|
||||||
/* Things to be done once we create the AudioEngine
|
/* Things to be done once we have a backend running in the AudioEngine
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ARDOUR::init_post_engine ();
|
ARDOUR::init_post_engine ();
|
||||||
|
|
@ -2572,6 +2565,17 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
bool likely_new = false;
|
bool likely_new = false;
|
||||||
|
|
||||||
|
/* if the audio/midi backend does not require setup, get our use of it underway
|
||||||
|
* right here
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!EngineControl::need_setup()) {
|
||||||
|
vector<const AudioBackendInfo*> backends = AudioEngine::instance()->available_backends();
|
||||||
|
cerr << "Setting up backend " << backends.front()->name;
|
||||||
|
AudioEngine::instance()->set_backend (backends.front()->name, ARDOUR_COMMAND_LINE::backend_client_name, ARDOUR_COMMAND_LINE::backend_session_uuid);
|
||||||
|
AudioEngine::instance()->start ();
|
||||||
|
}
|
||||||
|
|
||||||
/* deal with any existing DIRTY session now, rather than later. don't
|
/* deal with any existing DIRTY session now, rather than later. don't
|
||||||
* treat a non-dirty session this way, so that it stays visible
|
* treat a non-dirty session this way, so that it stays visible
|
||||||
* as we bring up the new session dialog.
|
* as we bring up the new session dialog.
|
||||||
|
|
@ -2693,10 +2697,6 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (create_engine ()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
|
if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
|
||||||
|
|
||||||
if (likely_new && !nsm) {
|
if (likely_new && !nsm) {
|
||||||
|
|
|
||||||
|
|
@ -263,7 +263,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
|
||||||
session_add_midi_route (false);
|
session_add_midi_route (false);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
int create_engine ();
|
void attach_to_engine ();
|
||||||
void post_engine ();
|
void post_engine ();
|
||||||
|
|
||||||
gint exit_on_main_window_close (GdkEventAny *);
|
gint exit_on_main_window_close (GdkEventAny *);
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@
|
||||||
#include <gtkmm/stock.h>
|
#include <gtkmm/stock.h>
|
||||||
#include <gtkmm2ext/utils.h>
|
#include <gtkmm2ext/utils.h>
|
||||||
|
|
||||||
|
#include "ardour/audio_backend.h"
|
||||||
|
#include "ardour/audioengine.h"
|
||||||
#include "ardour/rc_configuration.h"
|
#include "ardour/rc_configuration.h"
|
||||||
|
|
||||||
#include "pbd/convert.h"
|
#include "pbd/convert.h"
|
||||||
|
|
@ -594,33 +596,13 @@ EngineControl::build_command_line (vector<string>& cmd)
|
||||||
bool
|
bool
|
||||||
EngineControl::need_setup ()
|
EngineControl::need_setup ()
|
||||||
{
|
{
|
||||||
return !engine_running();
|
vector<const ARDOUR::AudioBackendInfo*> backends = ARDOUR::AudioEngine::instance()->available_backends();
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
if (backends.size() == 1 && backends.front()->already_configured()) {
|
||||||
EngineControl::engine_running ()
|
|
||||||
{
|
|
||||||
EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
|
|
||||||
boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
|
|
||||||
|
|
||||||
/* revert all environment settings back to whatever they were when
|
|
||||||
* ardour started, because ardour's startup script may have reset
|
|
||||||
* something in ways that interfere with finding/starting JACK.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (global_epa) {
|
|
||||||
current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
|
|
||||||
global_epa->restore ();
|
|
||||||
}
|
|
||||||
|
|
||||||
jack_status_t status;
|
|
||||||
jack_client_t* c = jack_client_open ("ardourprobe", JackNoStartServer, &status);
|
|
||||||
|
|
||||||
if (status == 0) {
|
|
||||||
jack_client_close (c);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
||||||
|
|
@ -353,6 +353,15 @@ struct AudioBackendInfo {
|
||||||
|
|
||||||
boost::shared_ptr<AudioBackend> (*backend_factory) (AudioEngine&);
|
boost::shared_ptr<AudioBackend> (*backend_factory) (AudioEngine&);
|
||||||
boost::shared_ptr<PortEngine> (*portengine_factory) (PortManager&);
|
boost::shared_ptr<PortEngine> (*portengine_factory) (PortManager&);
|
||||||
|
|
||||||
|
/** Return true if the underlying mechanism/API has been
|
||||||
|
* configured and does not need (re)configuration in order
|
||||||
|
* to be usable. Return false otherwise.
|
||||||
|
*
|
||||||
|
* Note that this may return true if (re)configuration is possible,
|
||||||
|
* but not required.
|
||||||
|
*/
|
||||||
|
bool (*already_configured)();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ public:
|
||||||
virtual ~AudioEngine ();
|
virtual ~AudioEngine ();
|
||||||
|
|
||||||
int discover_backends();
|
int discover_backends();
|
||||||
std::vector<std::string> available_backends() const;
|
std::vector<const AudioBackendInfo*> available_backends() const;
|
||||||
std::string current_backend_name () const;
|
std::string current_backend_name () const;
|
||||||
int set_backend (const std::string&, const std::string& arg1, const std::string& arg2);
|
int set_backend (const std::string&, const std::string& arg1, const std::string& arg2);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,8 @@ class JACKAudioBackend : public AudioBackend {
|
||||||
|
|
||||||
void update_latencies ();
|
void update_latencies ();
|
||||||
|
|
||||||
|
static bool already_configured();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<JackConnection> _jack_connection; //< shared with JACKPortEngine
|
boost::shared_ptr<JackConnection> _jack_connection; //< shared with JACKPortEngine
|
||||||
bool _running;
|
bool _running;
|
||||||
|
|
@ -145,6 +147,8 @@ class JACKAudioBackend : public AudioBackend {
|
||||||
|
|
||||||
ChanCount n_physical (unsigned long) const;
|
ChanCount n_physical (unsigned long) const;
|
||||||
|
|
||||||
|
void preset_jack_startup_command ();
|
||||||
|
|
||||||
/* pffooo */
|
/* pffooo */
|
||||||
|
|
||||||
std::string _target_device;
|
std::string _target_device;
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,14 @@ class JackConnection {
|
||||||
|
|
||||||
jack_client_t* jack() const { return _jack; }
|
jack_client_t* jack() const { return _jack; }
|
||||||
|
|
||||||
|
PBD::Signal0<void> Connected;
|
||||||
PBD::Signal1<void,const char*> Disconnected;
|
PBD::Signal1<void,const char*> Disconnected;
|
||||||
|
|
||||||
void halted_callback ();
|
void halted_callback ();
|
||||||
void halted_info_callback (jack_status_t, const char*);
|
void halted_info_callback (jack_status_t, const char*);
|
||||||
|
|
||||||
|
static bool server_running();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
jack_client_t* volatile _jack;
|
jack_client_t* volatile _jack;
|
||||||
std::string _client_name;
|
std::string _client_name;
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#include "pbd/signals.h"
|
||||||
|
|
||||||
#include "ardour/port_engine.h"
|
#include "ardour/port_engine.h"
|
||||||
#include "ardour/types.h"
|
#include "ardour/types.h"
|
||||||
|
|
||||||
|
|
@ -115,6 +117,9 @@ class JACKPortEngine : public PortEngine
|
||||||
ChanCount n_physical (unsigned long flags) const;
|
ChanCount n_physical (unsigned long flags) const;
|
||||||
void get_physical (DataType type, unsigned long flags, std::vector<std::string>& phy) const;
|
void get_physical (DataType type, unsigned long flags, std::vector<std::string>& phy) const;
|
||||||
|
|
||||||
|
PBD::ScopedConnection jack_connection_connection;
|
||||||
|
void connected_to_jack ();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
||||||
|
|
@ -537,13 +537,13 @@ AudioEngine::backend_discover (const string& path)
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<string>
|
vector<const AudioBackendInfo*>
|
||||||
AudioEngine::available_backends() const
|
AudioEngine::available_backends() const
|
||||||
{
|
{
|
||||||
vector<string> r;
|
vector<const AudioBackendInfo*> r;
|
||||||
|
|
||||||
for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
|
for (BackendMap::const_iterator i = _backends.begin(); i != _backends.end(); ++i) {
|
||||||
r.push_back (i->first);
|
r.push_back (i->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
@ -581,17 +581,21 @@ AudioEngine::set_backend (const std::string& name, const std::string& arg1, cons
|
||||||
drop_backend ();
|
drop_backend ();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
cerr << "Instantiate " << b->second->name << " with " << arg1 << " + " << arg2 << endl;
|
||||||
|
|
||||||
if (b->second->instantiate (arg1, arg2)) {
|
if (b->second->instantiate (arg1, arg2)) {
|
||||||
|
cerr << "i failed\n";
|
||||||
throw failed_constructor ();
|
throw failed_constructor ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cerr << "bf\n";
|
||||||
_backend = b->second->backend_factory (*this);
|
_backend = b->second->backend_factory (*this);
|
||||||
|
cerr << "pf\n";
|
||||||
_impl = b->second->portengine_factory (*this);
|
_impl = b->second->portengine_factory (*this);
|
||||||
|
cerr << "done\n";
|
||||||
|
|
||||||
|
} catch (exception& e) {
|
||||||
} catch (...) {
|
error << string_compose (_("Could not create backend for %1: %2"), name, e.what()) << endmsg;
|
||||||
error << string_compose (_("Could not create backend for %1"), name) << endmsg;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,7 @@
|
||||||
|
|
||||||
#include "ardour/analyser.h"
|
#include "ardour/analyser.h"
|
||||||
#include "ardour/audio_library.h"
|
#include "ardour/audio_library.h"
|
||||||
|
#include "ardour/audio_backend.h"
|
||||||
#include "ardour/audioengine.h"
|
#include "ardour/audioengine.h"
|
||||||
#include "ardour/audioplaylist.h"
|
#include "ardour/audioplaylist.h"
|
||||||
#include "ardour/audioregion.h"
|
#include "ardour/audioregion.h"
|
||||||
|
|
@ -333,15 +334,12 @@ ARDOUR::init (bool use_windows_vst, bool try_optimization, const char* localedir
|
||||||
|
|
||||||
ARDOUR::AudioEngine::create ();
|
ARDOUR::AudioEngine::create ();
|
||||||
|
|
||||||
uint32_t backend_cnt;
|
vector<const AudioBackendInfo*> backends = AudioEngine::instance()->available_backends();
|
||||||
|
|
||||||
if ((backend_cnt = AudioEngine::instance()->available_backends().size()) == 0) {
|
for (vector<const AudioBackendInfo*>::const_iterator i = backends.begin(); i != backends.end(); ++i) {
|
||||||
error << _("No audio/MIDI backends are available") << endmsg;
|
cerr << "BACKEND: [" << (*i)->name << "] already configured " << (*i)->already_configured() << endl;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cerr << "We have " << backend_cnt << endl;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -354,12 +354,26 @@ JACKAudioBackend::raw_buffer_size(DataType t)
|
||||||
return (s != _raw_buffer_sizes.end()) ? s->second : 0;
|
return (s != _raw_buffer_sizes.end()) ? s->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JACKAudioBackend::preset_jack_startup_command ()
|
||||||
|
{
|
||||||
|
/* write parameter settings to ~/.jackdrc file so that next invocation
|
||||||
|
* of JACK (presumably from a call to jack_client_open() from this
|
||||||
|
* process) will do the right thing.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
/* ---- BASIC STATE CONTROL API: start/stop/pause/freewheel --- */
|
/* ---- BASIC STATE CONTROL API: start/stop/pause/freewheel --- */
|
||||||
|
|
||||||
int
|
int
|
||||||
JACKAudioBackend::start ()
|
JACKAudioBackend::start ()
|
||||||
{
|
{
|
||||||
if (!connected()) {
|
if (!connected()) {
|
||||||
|
|
||||||
|
if (!_jack_connection->server_running()) {
|
||||||
|
preset_jack_startup_command ();
|
||||||
|
}
|
||||||
|
std::cerr << "Open JACK connection\n";
|
||||||
_jack_connection->open ();
|
_jack_connection->open ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,33 @@ JackConnection::~JackConnection ()
|
||||||
close ();
|
close ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
JackConnection::server_running ()
|
||||||
|
{
|
||||||
|
EnvironmentalProtectionAgency* global_epa = EnvironmentalProtectionAgency::get_global_epa ();
|
||||||
|
boost::scoped_ptr<EnvironmentalProtectionAgency> current_epa;
|
||||||
|
|
||||||
|
/* revert all environment settings back to whatever they were when
|
||||||
|
* ardour started, because ardour's startup script may have reset
|
||||||
|
* something in ways that interfere with finding/starting JACK.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (global_epa) {
|
||||||
|
current_epa.reset (new EnvironmentalProtectionAgency(true)); /* will restore settings when we leave scope */
|
||||||
|
global_epa->restore ();
|
||||||
|
}
|
||||||
|
|
||||||
|
jack_status_t status;
|
||||||
|
jack_client_t* c = jack_client_open ("ardourprobe", JackNoStartServer, &status);
|
||||||
|
|
||||||
|
if (status == 0) {
|
||||||
|
jack_client_close (c);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
JackConnection::open ()
|
JackConnection::open ()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,16 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "pbd/failed_constructor.h"
|
#include "pbd/error.h"
|
||||||
|
|
||||||
#include "ardour/jack_portengine.h"
|
#include "ardour/jack_portengine.h"
|
||||||
#include "ardour/jack_connection.h"
|
#include "ardour/jack_connection.h"
|
||||||
#include "ardour/port_manager.h"
|
#include "ardour/port_manager.h"
|
||||||
|
|
||||||
|
#include "i18n.h"
|
||||||
|
|
||||||
using namespace ARDOUR;
|
using namespace ARDOUR;
|
||||||
|
using namespace PBD;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
|
|
@ -85,17 +88,7 @@ JACKPortEngine::JACKPortEngine (PortManager& pm, boost::shared_ptr<JackConnectio
|
||||||
: PortEngine (pm)
|
: PortEngine (pm)
|
||||||
, _jack_connection (jc)
|
, _jack_connection (jc)
|
||||||
{
|
{
|
||||||
jack_client_t* client = _jack_connection->jack();
|
_jack_connection->Connected.connect_same_thread (jack_connection_connection, boost::bind (&JACKPortEngine::connected_to_jack, 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 ()
|
JACKPortEngine::~JACKPortEngine ()
|
||||||
|
|
@ -107,6 +100,24 @@ JACKPortEngine::~JACKPortEngine ()
|
||||||
_jack_connection.reset ();
|
_jack_connection.reset ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JACKPortEngine::connected_to_jack ()
|
||||||
|
{
|
||||||
|
/* register callbacks for stuff that is our responsibility */
|
||||||
|
|
||||||
|
jack_client_t* client = _jack_connection->jack();
|
||||||
|
|
||||||
|
if (!client) {
|
||||||
|
/* how could this happen? it could ... */
|
||||||
|
error << _("Already disconnected from JACK before PortEngine could register callbacks") << endmsg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
JACKPortEngine::private_handle() const
|
JACKPortEngine::private_handle() const
|
||||||
{
|
{
|
||||||
|
|
@ -294,10 +305,12 @@ JACKPortEngine::n_physical (unsigned long flags) const
|
||||||
if (ports) {
|
if (ports) {
|
||||||
for (uint32_t i = 0; ports[i]; ++i) {
|
for (uint32_t i = 0; ports[i]; ++i) {
|
||||||
if (!strstr (ports[i], "Midi-Through")) {
|
if (!strstr (ports[i], "Midi-Through")) {
|
||||||
DataType t (jack_port_type (jack_port_by_name (_priv_jack, ports[i])));
|
DataType t = port_data_type (jack_port_by_name (_priv_jack, ports[i]));
|
||||||
|
if (t != DataType::NIL) {
|
||||||
c.set (t, c.get (t) + 1);
|
c.set (t, c.get (t) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jack_free (ports);
|
jack_free (ports);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue