summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2013-05-20 08:26:48 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2013-05-20 08:26:48 +0200
commita609e6895a96db134697acce266e0cb94488f60b (patch)
tree77d854e202e973349e3500b10dc36069e388105b
parent98430d96a1d25cba36ad304fde6518e493fe3441 (diff)
Centralise jackclient code for reuse among the jack client modules. Implement most of the jackaudio output module (probably broken atm.).
-rw-r--r--configure.in20
-rw-r--r--drumgizmo/audioinputenginedl.cc27
-rw-r--r--drumgizmo/audioinputenginedl.h4
-rw-r--r--drumgizmo/audiooutputenginedl.cc11
-rw-r--r--drumgizmo/audiooutputenginedl.h4
-rw-r--r--drumgizmo/input/jackmidi/Makefile.am8
-rw-r--r--drumgizmo/input/jackmidi/jackmidi.cc46
-rw-r--r--drumgizmo/jackclient.cc2
-rw-r--r--drumgizmo/jackclient.h6
-rw-r--r--drumgizmo/output/jackaudio/jackaudio.cc206
-rw-r--r--src/drumgizmo.cc2
11 files changed, 303 insertions, 33 deletions
diff --git a/configure.in b/configure.in
index c551c84..cb3c99a 100644
--- a/configure.in
+++ b/configure.in
@@ -14,6 +14,8 @@ AM_PROG_LIBTOOL
AM_CONFIG_HEADER(config.h)
AC_STDC_HEADERS
+need_jack=no
+
dnl ======================
dnl Init pkg-config
dnl ======================
@@ -129,10 +131,7 @@ if test "x$enable_cli" = "xyes"; then
[enable_input_jackmidi="yes"])
if test "x$enable_input_jackmidi" = "xyes"; then
have_input_jackmidi=yes
- dnl ======================
- dnl Check for jack
- dnl ======================
- PKG_CHECK_MODULES(JACK, jack >= 0.120.1)
+ need_jack=yes
else
AC_MSG_RESULT([*** input jackmidi plugin disabled per user request ***])
have_input_jackmidi=no
@@ -178,10 +177,7 @@ if test "x$enable_cli" = "xyes"; then
[enable_output_jackaudio="yes"])
if test "x$enable_output_jackaudio" = "xyes"; then
have_output_jackaudio=yes
- dnl ======================
- dnl Check for jack
- dnl ======================
- PKG_CHECK_MODULES(JACK, jack >= 0.120.1)
+ need_jack=yes
else
AC_MSG_RESULT([*** output jack plugin disabled per user request ***])
have_output_jackaudio=no
@@ -390,6 +386,14 @@ else
AC_MSG_RESULT([*** Disabling SSE ***])
fi
+if test "x$need_jack" = "xyes"
+then
+ dnl ======================
+ dnl Check for jack
+ dnl ======================
+ PKG_CHECK_MODULES(JACK, jack >= 0.120.1)
+fi
+
AC_SUBST(CFLAGS)
AC_SUBST(CPPFLAGS)
AC_SUBST(CXXFLAGS)
diff --git a/drumgizmo/audioinputenginedl.cc b/drumgizmo/audioinputenginedl.cc
index 799e56f..e7f19c6 100644
--- a/drumgizmo/audioinputenginedl.cc
+++ b/drumgizmo/audioinputenginedl.cc
@@ -34,8 +34,12 @@
#include <string.h>
#include <stdlib.h>
+#include "jackclient.h"
+
AudioInputEngineDL::AudioInputEngineDL(std::string name)
{
+ is_jack_plugin = strstr(name.c_str(), "jack");
+
std::string plugin = INPUT_PLUGIN_DIR"/lib" + name + ".so";
void *lib = dlopen(plugin.c_str(), RTLD_LAZY);
if(!lib) {
@@ -60,58 +64,66 @@ AudioInputEngineDL::AudioInputEngineDL(std::string name)
i_init = (input_init_func_t) dlsym(lib, "init");
dlsym_error = dlerror();
if(dlsym_error) {
- printf("Cannot load symbol destroy: %s\n", dlsym_error);
+ printf("Cannot load symbol init: %s\n", dlsym_error);
return;
}
i_setparm = (input_setparm_func_t) dlsym(lib, "setparm");
dlsym_error = dlerror();
if(dlsym_error) {
- printf("Cannot load symbol destroy: %s\n", dlsym_error);
+ printf("Cannot load symbol setparm: %s\n", dlsym_error);
return;
}
i_start = (input_start_func_t) dlsym(lib, "start");
dlsym_error = dlerror();
if(dlsym_error) {
- printf("Cannot load symbol destroy: %s\n", dlsym_error);
+ printf("Cannot load symbol start: %s\n", dlsym_error);
return;
}
i_stop = (input_stop_func_t) dlsym(lib, "stop");
dlsym_error = dlerror();
if(dlsym_error) {
- printf("Cannot load symbol destroy: %s\n", dlsym_error);
+ printf("Cannot load symbol stop: %s\n", dlsym_error);
return;
}
i_pre = (input_pre_func_t) dlsym(lib, "pre");
dlsym_error = dlerror();
if(dlsym_error) {
- printf("Cannot load symbol destroy: %s\n", dlsym_error);
+ printf("Cannot load symbol pre: %s\n", dlsym_error);
return;
}
i_run = (input_run_func_t) dlsym(lib, "run");
dlsym_error = dlerror();
if(dlsym_error) {
- printf("Cannot load symbol destroy: %s\n", dlsym_error);
+ printf("Cannot load symbol run: %s\n", dlsym_error);
return;
}
i_post = (input_post_func_t) dlsym(lib, "post");
dlsym_error = dlerror();
if(dlsym_error) {
- printf("Cannot load symbol destroy: %s\n", dlsym_error);
+ printf("Cannot load symbol post: %s\n", dlsym_error);
return;
}
ptr = i_create();
+
+ if(is_jack_plugin) {
+ char ptrbuf[32];
+ jackclient = init_jack_client();
+ sprintf(ptrbuf, "%p", jackclient);
+ setParm("jack_client", ptrbuf);
+ }
}
AudioInputEngineDL::~AudioInputEngineDL()
{
i_destroy(ptr);
+ if(is_jack_plugin) close_jack_client();
}
bool AudioInputEngineDL::init(Instruments &instruments)
@@ -138,6 +150,7 @@ void AudioInputEngineDL::setParm(std::string parm, std::string value)
bool AudioInputEngineDL::start()
{
+ if(is_jack_plugin) jackclient->activate();
return i_start(ptr);
}
diff --git a/drumgizmo/audioinputenginedl.h b/drumgizmo/audioinputenginedl.h
index b8829e5..ed1fb27 100644
--- a/drumgizmo/audioinputenginedl.h
+++ b/drumgizmo/audioinputenginedl.h
@@ -28,6 +28,7 @@
#define __DRUMGIZMO_AUDIOINPUTENGINEDL_H__
#include "audioinputengine.h"
+#include "jackclient.h"
typedef void* (*input_create_func_t)(void);
typedef void (*input_destroy_func_t)(void*);
@@ -66,6 +67,9 @@ private:
input_pre_func_t i_pre;
input_run_func_t i_run;
input_post_func_t i_post;
+
+ bool is_jack_plugin;
+ JackClient *jackclient;
};
#endif/*__DRUMGIZMO_AUDIOINPUTENGINEDL_H__*/
diff --git a/drumgizmo/audiooutputenginedl.cc b/drumgizmo/audiooutputenginedl.cc
index 411c14b..ad8d815 100644
--- a/drumgizmo/audiooutputenginedl.cc
+++ b/drumgizmo/audiooutputenginedl.cc
@@ -33,6 +33,8 @@
AudioOutputEngineDL::AudioOutputEngineDL(std::string name)
{
+ is_jack_plugin = strstr(name.c_str(), "jack");
+
std::string plugin = OUTPUT_PLUGIN_DIR"/lib" + name + ".so";
void *lib = dlopen(plugin.c_str(), RTLD_LAZY);
if(!lib) {
@@ -104,11 +106,19 @@ AudioOutputEngineDL::AudioOutputEngineDL(std::string name)
}
ptr = o_create();
+
+ if(is_jack_plugin) {
+ char ptrbuf[32];
+ jackclient = init_jack_client();
+ sprintf(ptrbuf, "%p", jackclient);
+ setParm("jack_client", ptrbuf);
+ }
}
AudioOutputEngineDL::~AudioOutputEngineDL()
{
o_destroy(ptr);
+ if(is_jack_plugin) close_jack_client();
}
bool AudioOutputEngineDL::init(Channels channels)
@@ -135,6 +145,7 @@ void AudioOutputEngineDL::setParm(std::string parm, std::string value)
bool AudioOutputEngineDL::start()
{
+ if(is_jack_plugin) jackclient->activate();
return o_start(ptr);
}
diff --git a/drumgizmo/audiooutputenginedl.h b/drumgizmo/audiooutputenginedl.h
index 7faa78e..4b22131 100644
--- a/drumgizmo/audiooutputenginedl.h
+++ b/drumgizmo/audiooutputenginedl.h
@@ -34,6 +34,7 @@
#include "channel.h"
#include "audiooutputengine.h"
+#include "jackclient.h"
typedef void* (*output_create_func_t)(void);
typedef void (*output_destroy_func_t)(void*);
@@ -72,6 +73,9 @@ private:
output_pre_func_t o_pre;
output_run_func_t o_run;
output_post_func_t o_post;
+
+ bool is_jack_plugin;
+ JackClient *jackclient;
};
#endif/*__DRUMGIZMO_AUDIOOUTPUTENGINEDL_H__*/
diff --git a/drumgizmo/input/jackmidi/Makefile.am b/drumgizmo/input/jackmidi/Makefile.am
index cd77a74..809ca96 100644
--- a/drumgizmo/input/jackmidi/Makefile.am
+++ b/drumgizmo/input/jackmidi/Makefile.am
@@ -1,6 +1,10 @@
jackmidisources = \
- jackmidi.cc
+ jackmidi.cc \
+ $(top_srcdir)/src/midimapper.cc \
+ $(top_srcdir)/src/midimapparser.cc \
+ $(top_srcdir)/src/saxparser.cc \
+ $(top_srcdir)/hugin/hugin.c
if HAVE_INPUT_JACKMIDI
@@ -20,7 +24,7 @@ lib_LTLIBRARIES = $(jackmidiltlibs)
libdir = $(INPUT_PLUGIN_DIR)
-AM_CPPFLAGS = -I$(top_srcdir)/include
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src -I$(top_srcdir)/hugin
libjackmidi_la_LDFLAGS =
libjackmidi_la_LIBADD =
libjackmidi_la_SOURCES = $(jackmidibuildsources)
diff --git a/drumgizmo/input/jackmidi/jackmidi.cc b/drumgizmo/input/jackmidi/jackmidi.cc
index 7af257e..52c0bb8 100644
--- a/drumgizmo/input/jackmidi/jackmidi.cc
+++ b/drumgizmo/input/jackmidi/jackmidi.cc
@@ -30,6 +30,8 @@
#include <string>
#include <stdio.h>
+#include <midimapper.h>
+#include <midimapparser.h>
#define NOTE_ON 0x90
@@ -65,12 +67,13 @@ private:
event_t *list;
size_t listsize;
+
+ std::string midimapfile;
+ MidiMapper mmap;
};
JackMidi::JackMidi()
{
- jackclient = init_jack_client();
- jackclient->addJackProcess(this);
pos = 0;
list = (event_t *)malloc(sizeof(event_t) * 1000);
@@ -79,8 +82,6 @@ JackMidi::JackMidi()
JackMidi::~JackMidi()
{
- jackclient->removeJackProcess(this);
- close_jack_client();
}
bool JackMidi::init(int instruments, char *inames[])
@@ -91,17 +92,29 @@ bool JackMidi::init(int instruments, char *inames[])
JackPortIsInput,// | JackPortIsTerminal,
0);
+ MidiMapParser p(midimapfile);
+ if(p.parse()) return false;
+ mmap.midimap = p.midimap;
+
+ for(int i = 0; i < instruments; i++) {
+ mmap.instrmap[inames[i]] = i;
+ }
+
return true;
}
void JackMidi::setParm(std::string parm, std::string value)
{
- if(parm == "map") loadMap(value);
+ if(parm == "map") midimapfile = value;
+ if(parm == "jack_client") {
+ sscanf(value.c_str(), "%p", &jackclient);
+ if(jackclient) jackclient->addJackProcess(this);
+ }
}
bool JackMidi::start()
{
- jackclient->activate();
+ // jackclient->activate();
return true;
}
@@ -124,6 +137,8 @@ event_t *JackMidi::run(size_t pos, size_t len, size_t *nevents)
void JackMidi::jack_process(jack_nframes_t nframes)
{
+ printf("i"); fflush(stdout);
+
void *midibuffer = jack_port_get_buffer(midi_port, nframes);
jack_nframes_t midievents = jack_midi_get_event_count(midibuffer);
@@ -139,13 +154,17 @@ void JackMidi::jack_process(jack_nframes_t nframes)
int velocity = event.buffer[2];
printf("Event key:%d vel:%d\n", key, velocity);
-
- if(velocity) {
- list[listsize].type = TYPE_ONSET;
- list[listsize].instrument = key;
- list[listsize].velocity = velocity / 127.0;
- list[listsize].offset = event.time;
- listsize++;
+
+ int i = mmap.lookup(key);
+ if(i != -1) {
+
+ if(velocity) {
+ list[listsize].type = TYPE_ONSET;
+ list[listsize].instrument = i;
+ list[listsize].velocity = velocity / 127.0;
+ list[listsize].offset = event.time;
+ listsize++;
+ }
}
}
@@ -154,7 +173,6 @@ void JackMidi::jack_process(jack_nframes_t nframes)
pos += nframes;
}
-
void JackMidi::post()
{
}
diff --git a/drumgizmo/jackclient.cc b/drumgizmo/jackclient.cc
index 4fbafb5..56c9da8 100644
--- a/drumgizmo/jackclient.cc
+++ b/drumgizmo/jackclient.cc
@@ -47,10 +47,12 @@ JackClient::~JackClient()
jack_client_close(jack_client);
}
+/*
void JackClient::addJackProcess(JackProcess *process)
{
jack_processes.insert(process);
}
+*/
void JackClient::removeJackProcess(JackProcess *process)
{
diff --git a/drumgizmo/jackclient.h b/drumgizmo/jackclient.h
index 636d4d0..88a733f 100644
--- a/drumgizmo/jackclient.h
+++ b/drumgizmo/jackclient.h
@@ -40,7 +40,11 @@ public:
JackClient();
~JackClient();
- void addJackProcess(JackProcess *process);
+ void addJackProcess(JackProcess *process)
+ {
+ jack_processes.insert(process);
+ }
+
void removeJackProcess(JackProcess *process);
void activate();
diff --git a/drumgizmo/output/jackaudio/jackaudio.cc b/drumgizmo/output/jackaudio/jackaudio.cc
new file mode 100644
index 0000000..9410915
--- /dev/null
+++ b/drumgizmo/output/jackaudio/jackaudio.cc
@@ -0,0 +1,206 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * jackaudio.cc
+ *
+ * Sat Apr 30 21:11:54 CEST 2011
+ * Copyright 2011 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo 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.
+ *
+ * DrumGizmo 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 DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include <stdlib.h>
+
+#include <string>
+#include <audiotypes.h>
+
+#define NOTE_ON 0x90
+
+#include "../../jackclient.h"
+#include <stdio.h>
+
+class JackAudio : public JackProcess {
+public:
+ JackAudio();
+ ~JackAudio();
+ bool init(int channels, char *cnames[]);
+
+ void setParm(std::string parm, std::string value);
+
+ bool start();
+ void stop();
+
+ void pre(size_t size);
+ void run(int channel, sample_t* data, size_t size);
+ void post(size_t size);
+
+ void jack_process(jack_nframes_t nframes);
+
+private:
+ JackClient *jackclient;
+ jack_port_t *output_port[64];
+ size_t nchannels;
+ sample_t **channels;
+};
+
+JackAudio::JackAudio()
+{
+}
+
+JackAudio::~JackAudio()
+{
+}
+
+bool JackAudio::init(int nchannels, char *cnames[])
+{
+ this->nchannels = nchannels;
+ channels = (sample_t**)malloc(nchannels * sizeof(sample_t*));
+
+ for(int i = 0; i < nchannels; i++) {
+ char buf[32];
+ sprintf(buf, "%d", i + 1);
+ std::string name;
+ name += buf;
+ name += "-";
+ name += cnames[i];
+ output_port[i] = jack_port_register(jackclient->jack_client,
+ name.c_str(),
+ JACK_DEFAULT_AUDIO_TYPE,
+ JackPortIsOutput, 0);
+ channels[i] = (sample_t*)malloc(2048 * sizeof(sample_t));
+ }
+ return true;
+}
+
+void JackAudio::setParm(std::string parm, std::string value)
+{
+ if(parm == "jack_client") {
+ sscanf(value.c_str(), "%p", &jackclient);
+ if(jackclient) jackclient->addJackProcess(this);
+ }
+}
+
+bool JackAudio::start()
+{
+ return true;
+}
+
+void JackAudio::stop()
+{
+}
+
+void JackAudio::pre(size_t size)
+{
+}
+
+void JackAudio::run(int channel, sample_t* data, size_t size)
+{
+ // Copy engine data to ringbuffer.
+ for(int i = 0; i < size; i++) {
+ channels[channel][i] = data[i];
+ }
+}
+
+void JackAudio::post(size_t size)
+{
+}
+
+void JackAudio::jack_process(jack_nframes_t nframes)
+{
+ printf("o"); fflush(stdout);
+ for(int c = 0; c < nchannels; c++) {
+ jack_default_audio_sample_t *out =
+ (jack_default_audio_sample_t *) jack_port_get_buffer(output_port[c],
+ nframes);
+ for(int i = 0; i < nframes; i++) {
+ out[i] = channels[c][i];
+ }
+ }
+}
+
+extern "C" {
+ void *create()
+ {
+ return new JackAudio();
+ }
+
+ void destroy(void *h)
+ {
+ JackAudio *jack = (JackAudio*)h;
+ delete jack;
+ }
+
+ bool init(void *h, int cs, char *cnames[])
+ {
+ JackAudio *jack = (JackAudio*)h;
+ return jack->init(cs, cnames);
+ }
+
+ void setparm(void *h, const char *parm, const char *value)
+ {
+ JackAudio *jack = (JackAudio*)h;
+ jack->setParm(parm, value);
+ }
+
+ bool start(void *h)
+ {
+ JackAudio *jack = (JackAudio*)h;
+ return jack->start();
+ }
+
+ void stop(void *h)
+ {
+ JackAudio *jack = (JackAudio*)h;
+ jack->stop();
+ }
+
+ void pre(void *h, size_t s)
+ {
+ JackAudio *jack = (JackAudio*)h;
+ jack->pre(s);
+ }
+
+ void run(void *h, int ch, sample_t *data, size_t size)
+ {
+ JackAudio *jack = (JackAudio*)h;
+ jack->run(ch, data, size);
+ }
+
+ void post(void *h, size_t s)
+ {
+ JackAudio *jack = (JackAudio*)h;
+ jack->post(s);
+ }
+}
+
+#ifdef TEST_AUDIOINPUTENGINEJACKAUDIO
+//Additional dependency files
+//deps:
+//Required cflags (autoconf vars may be used)
+//cflags:
+//Required link options (autoconf vars may be used)
+//libs:
+#include "test.h"
+
+TEST_BEGIN;
+
+// TODO: Put some testcode here (see test.h for usable macros).
+
+TEST_END;
+
+#endif/*TEST_AUDIOINPUTENGINEJACKAUDIO*/
diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index e0be30b..cb77fd4 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -389,7 +389,7 @@ void DrumGizmo::run()
oe->start();
size_t pos = 0;
- size_t nsamples = 512;
+ size_t nsamples = 2048;
sample_t samples[nsamples];
while(run(pos, samples, nsamples) == true) {