From ef3a90f4ba8d65e8c210898c48acd3a07eafaf4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Gl=C3=B6ckner?= Date: Fri, 22 Jan 2016 11:59:00 +0100 Subject: added JackaudioOutputEngine --- drumgizmo/Makefile.am | 7 ++ drumgizmo/drumgizmoc.cc | 6 +- drumgizmo/enginefactory.cc | 16 ++++- drumgizmo/enginefactory.h | 8 ++- drumgizmo/input/jackmidi/jackmidi.cc | 2 + drumgizmo/jackclient.cc | 112 +++++++++++++++++--------------- drumgizmo/jackclient.h | 72 +++++++++++--------- drumgizmo/output/jackaudio/jackaudio.cc | 2 + 8 files changed, 136 insertions(+), 89 deletions(-) diff --git a/drumgizmo/Makefile.am b/drumgizmo/Makefile.am index bdf36c4..4eb770c 100644 --- a/drumgizmo/Makefile.am +++ b/drumgizmo/Makefile.am @@ -58,6 +58,13 @@ drumgizmo_SOURCES += output/alsa.cc drumgizmo_CXXFLAGS += -DHAVE_OUTPUT_ALSA endif # HAVE_OUTPUT_ALSA +if HAVE_OUTPUT_JACKAUDIO +drumgizmo_CXXFLAGS += $(JACK_CFLAGS) +drumgizmo_LDFLAGS += $(JACK_LIBS) +drumgizmo_SOURCES += output/jackaudio.cc +drumgizmo_CXXFLAGS += -DHAVE_OUTPUT_JACKAUDIO +endif # HAVE_OUTPUT_JACKAUDIO + EXTRA_DIST = \ drumgizmoc.h \ jackclient.h \ diff --git a/drumgizmo/drumgizmoc.cc b/drumgizmo/drumgizmoc.cc index 978b0cc..14ebe64 100644 --- a/drumgizmo/drumgizmoc.cc +++ b/drumgizmo/drumgizmoc.cc @@ -226,7 +226,9 @@ int CliMain::run(int argc, char *argv[]) return 1; } - auto ie = createInputEngine(inputengine); + JackClientPtr client{nullptr}; + + auto ie = createInputEngine(client, inputengine); if(ie == NULL) { printf("Invalid input engine: %s\n", inputengine.c_str()); @@ -265,7 +267,7 @@ int CliMain::run(int argc, char *argv[]) return 1; } - auto oe = createOutputEngine(outputengine); + auto oe = createOutputEngine(client, outputengine); if(oe == NULL) { printf("Invalid output engine: %s\n", outputengine.c_str()); diff --git a/drumgizmo/enginefactory.cc b/drumgizmo/enginefactory.cc index c9f2ef3..8c40a28 100644 --- a/drumgizmo/enginefactory.cc +++ b/drumgizmo/enginefactory.cc @@ -49,7 +49,11 @@ #include "output/alsa.h" #endif -InputEnginePtr createInputEngine(std::string const & name) { +#ifdef HAVE_OUTPUT_JACKAUDIO +#include "output/jackaudio.h" +#endif + +InputEnginePtr createInputEngine(JackClientPtr& jack, std::string const & name) { #ifdef HAVE_INPUT_DUMMY if (name == "dummy") { return std::make_unique(); @@ -67,7 +71,7 @@ InputEnginePtr createInputEngine(std::string const & name) { return nullptr; } -OutputEnginePtr createOutputEngine(std::string const & name) { +OutputEnginePtr createOutputEngine(JackClientPtr& jack, std::string const & name) { #ifdef HAVE_OUTPUT_DUMMY if (name == "dummy") { return std::make_unique(); @@ -83,6 +87,14 @@ OutputEnginePtr createOutputEngine(std::string const & name) { return std::make_unique(); } #endif +#ifdef HAVE_OUTPUT_JACKAUDIO + if (name == "jackaudio") { + if (jack.get() == nullptr) { + jack = std::make_unique(); + } + return std::make_unique(*jack); + } +#endif // todo: add more engines diff --git a/drumgizmo/enginefactory.h b/drumgizmo/enginefactory.h index 613e49f..93ce67b 100644 --- a/drumgizmo/enginefactory.h +++ b/drumgizmo/enginefactory.h @@ -31,8 +31,12 @@ #include "audioinputengine.h" #include "audiooutputengine.h" +// todo: ifdef jack enabled +#include "jackclient.h" + +using JackClientPtr = std::unique_ptr; using InputEnginePtr = std::unique_ptr; using OutputEnginePtr = std::unique_ptr; -InputEnginePtr createInputEngine(std::string const & name); -OutputEnginePtr createOutputEngine(std::string const & name); +InputEnginePtr createInputEngine(JackClientPtr& jack, std::string const & name); +OutputEnginePtr createOutputEngine(JackClientPtr& jack, std::string const & name); diff --git a/drumgizmo/input/jackmidi/jackmidi.cc b/drumgizmo/input/jackmidi/jackmidi.cc index a6b49b7..e632484 100644 --- a/drumgizmo/input/jackmidi/jackmidi.cc +++ b/drumgizmo/input/jackmidi/jackmidi.cc @@ -24,6 +24,7 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +/* #include #include @@ -231,6 +232,7 @@ extern "C" { jackmidi->post(); } } +*/ #ifdef TEST_AUDIOINPUTENGINEJACKMIDI //Additional dependency files diff --git a/drumgizmo/jackclient.cc b/drumgizmo/jackclient.cc index e4af141..8d422cb 100644 --- a/drumgizmo/jackclient.cc +++ b/drumgizmo/jackclient.cc @@ -24,77 +24,85 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include "jackclient.h" +#include -extern "C" -{ - int _wrap_jack_process(jack_nframes_t nframes, void *arg){ - return ((JackClient*)arg)->process(nframes);} -} // extern "C" +#include "jackclient.h" -JackClient::JackClient() - : refcnt(0) -{ - jack_status_t status; +JackProcess::~JackProcess() { +} - jack_client = jack_client_open("DrumGizmo", JackNullOption, &status); +// -------------------------------------------------------------------- - jack_set_process_callback(jack_client, _wrap_jack_process, this); +JackChannel::JackChannel() + : samples{} + , client{nullptr} + , port{nullptr} { +} - active = false; +JackChannel::JackChannel(JackClient& client, std::size_t buffer_size, + std::string const & name) + : samples{} + , client{client.client} + // register jack port for given client + , port{jack_port_register(this->client, name.c_str(), + JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)} { + samples.resize(buffer_size); } -JackClient::~JackClient() -{ - jack_client_close(jack_client); +JackChannel::~JackChannel() { + if (port != nullptr) { + assert(client != nullptr); + jack_port_unregister(client, port); + } } -/* -void JackClient::addJackProcess(JackProcess *process) -{ - jack_processes.insert(process); +// -------------------------------------------------------------------- + +int _wrap_jack_process(jack_nframes_t nframes, void* arg){ + return static_cast(arg)->process(nframes); } -*/ -void JackClient::removeJackProcess(JackProcess *process) -{ - jack_processes.erase(process); +JackClient::JackClient() + : client{nullptr} + , processes{} + , is_active{false} { + jack_status_t status; + client = jack_client_open("DrumGizmo", JackNullOption, &status); + jack_set_process_callback(client, _wrap_jack_process, this); } -void JackClient::activate() -{ - if(!active) jack_activate(jack_client); - active = true; +JackClient::~JackClient() { + if (client != nullptr) { + jack_client_close(client); + } } -int JackClient::process(jack_nframes_t nframes) -{ - std::set::iterator i = jack_processes.begin(); - while(i != jack_processes.end()) { - JackProcess *jp = *i; - jp->jack_process(nframes); - i++; - } +void JackClient::add(JackProcess& process) { + processes.insert(&process); +} - return 0; +void JackClient::remove(JackProcess& process) { + processes.erase(&process); } -JackClient *jackclient = NULL; +void JackClient::activate() { + if (!is_active) { + jack_activate(client); + } + is_active = true; +} -JackClient *init_jack_client() -{ - if(jackclient == NULL) jackclient = new JackClient(); - jackclient->refcnt++; - return jackclient; +int JackClient::process(jack_nframes_t num_frames) { + for (auto& ptr: processes) { + ptr->process(num_frames); + } + return 0; +} +std::size_t JackClient::getBufferSize() const { + return jack_get_buffer_size(client); } -void close_jack_client() -{ - if(jackclient) { - jackclient->refcnt--; - if(jackclient->refcnt == 0) { - delete jackclient; - jackclient = NULL; - } - } + +std::size_t JackClient::getSampleRate() const { + return jack_get_sample_rate(client); } diff --git a/drumgizmo/jackclient.h b/drumgizmo/jackclient.h index f093220..ef7abf1 100644 --- a/drumgizmo/jackclient.h +++ b/drumgizmo/jackclient.h @@ -24,44 +24,54 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_JACKCLIENT_H__ -#define __DRUMGIZMO_JACKCLIENT_H__ - -#include +#pragma once +#include +#include #include -class JackProcess { -public: - virtual ~JackProcess() {} - virtual void jack_process(jack_nframes_t nframes) = 0; -}; - -class JackClient { -public: - JackClient(); - ~JackClient(); - - void addJackProcess(JackProcess *process) - { - jack_processes.insert(process); - } +#include - void removeJackProcess(JackProcess *process); +#include - void activate(); - int process(jack_nframes_t nframes); +class JackClient; - jack_client_t *jack_client; +class JackProcess { + public: + virtual ~JackProcess(); + virtual void process(jack_nframes_t num_frames) = 0; +}; - // Sort of private... - int refcnt; +// -------------------------------------------------------------------- -private: - std::set jack_processes; - bool active; +struct JackChannel { + std::vector samples; + jack_client_t* const client; + jack_port_t* const port; + + JackChannel(); + JackChannel(JackClient& client, std::size_t buffer_size, + std::string const & name); + ~JackChannel(); }; -JackClient *init_jack_client(); -void close_jack_client(); +// -------------------------------------------------------------------- -#endif/*__DRUMGIZMO_JACKCLIENT_H__*/ +class JackClient { + friend struct JackChannel; + + public: + JackClient(); + ~JackClient(); + + void add(JackProcess& process); + void remove(JackProcess& process); + void activate(); + int process(jack_nframes_t num_frames); + std::size_t getBufferSize() const; + std::size_t getSampleRate() const; + + private: + jack_client_t* client; + std::set processes; + bool is_active; +}; diff --git a/drumgizmo/output/jackaudio/jackaudio.cc b/drumgizmo/output/jackaudio/jackaudio.cc index 511c145..3e489a9 100644 --- a/drumgizmo/output/jackaudio/jackaudio.cc +++ b/drumgizmo/output/jackaudio/jackaudio.cc @@ -24,6 +24,7 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +/* #include #include @@ -218,3 +219,4 @@ extern "C" { return jack->samplerate(); } } +*/ -- cgit v1.2.3