summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2014-05-17 21:27:52 +0200
committerBent Bisballe Nyeng <deva@aasimon.org>2014-05-17 21:27:52 +0200
commit0e048dee411cc20beb2a8667e5bb339f9b7fb939 (patch)
treec9bacf6f2491f5ae6feb4f4786688ef5659f5c9b
parentb6405171c6a74a5227555a9b75c03f88a5f21ed2 (diff)
New resample feature on output channels.
-rw-r--r--configure.ac31
-rw-r--r--drumgizmo/audiooutputenginedl.cc12
-rw-r--r--drumgizmo/audiooutputenginedl.h3
-rw-r--r--drumgizmo/output/jackaudio/jackaudio.cc12
-rw-r--r--lv2/Makefile.am12
-rw-r--r--src/Makefile.am.drumgizmo2
-rw-r--r--src/audiofile.cc36
-rw-r--r--src/audiooutputengine.h7
-rw-r--r--src/drumgizmo.cc82
-rw-r--r--src/drumkit.cc6
-rw-r--r--src/drumkit.h3
-rw-r--r--src/drumkitparser.cc8
12 files changed, 158 insertions, 56 deletions
diff --git a/configure.ac b/configure.ac
index c3fc352..d8d45d4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -355,7 +355,36 @@ if test x$with_resample == xyes; then
dnl Check for libsamplerate
dnl ======================
PKG_CHECK_MODULES(SAMPLERATE, samplerate >= 0.1.7)
-fi
+
+# dnl ======================
+# dnl Check for the zitaresampler library
+# dnl ======================
+# AC_LANG_PUSH([C++])
+# tmp_CXXFLAGS="$CXXFLAGS"
+# tmp_CPPFLAGS="$CPPFLAGS"
+# tmp_CFLAGS="$CFLAGS"
+# tmp_LDFLAGS="$LDFLAGS"
+# tmp_LIBS="$LIBS"
+# CXXFLAGS=""
+# CPPFLAGS="$ZITA_CPPFLAGS"
+# CFLAGS=""
+# LDFLAGS="$ZITA_LDFLAGS"
+# LIBS=""
+# AC_CHECK_HEADER(zita-resampler/resampler.h, ,
+# AC_MSG_ERROR([*** zita-resampler header files not found! Set ZITA_CPPFLAGS to add searchpath.]))
+# AC_CHECK_LIB(zita-resampler, _Z28zita_resampler_major_versionv, ,
+# AC_MSG_ERROR([*** zita-resampler library not found! Set ZITA_LDFLAGS to add searchpath.]))
+# ZITA_CPPFLAGS="$CXXFLAGS $CPPFLAGS $CFLAGS"
+# ZITA_LIBS="$LDFLAGS $LIBS"
+# CXXFLAGS="$tmp_CXXFLAGS"
+# CPPFLAGS="$tmp_CPPFLAGS"
+# CFLAGS="$tmp_CFLAGS"
+# LDFLAGS="$tmp_LDFLAGS"
+# LIBS="$tmp_LIBS"
+# AC_SUBST(ZITA_CPPFLAGS)
+# AC_SUBST(ZITA_LIBS)
+# AC_LANG_POP([C++])
+fi
#dnl ======================
#dnl Check for zlib
diff --git a/drumgizmo/audiooutputenginedl.cc b/drumgizmo/audiooutputenginedl.cc
index 513d21b..fcedd9d 100644
--- a/drumgizmo/audiooutputenginedl.cc
+++ b/drumgizmo/audiooutputenginedl.cc
@@ -111,6 +111,12 @@ AudioOutputEngineDL::AudioOutputEngineDL(std::string name)
o_bufsize = NULL;
}
+ o_samplerate = (output_samplerate_func_t) dlsym(lib, "samplerate");
+ dlsym_error = dlerror();
+ if(dlsym_error) {
+ o_samplerate = NULL;
+ }
+
ptr = o_create();
if(is_jack_plugin) {
@@ -181,6 +187,12 @@ size_t AudioOutputEngineDL::getBufferSize()
return 1024;
}
+size_t AudioOutputEngineDL::samplerate()
+{
+ if(o_samplerate) return o_samplerate(ptr);
+ return UNKNOWN_SAMPLERATE;
+}
+
#ifdef TEST_AUDIOOUTPUTENGINEDL
//Additional dependency files
//deps:
diff --git a/drumgizmo/audiooutputenginedl.h b/drumgizmo/audiooutputenginedl.h
index 471247e..75460f3 100644
--- a/drumgizmo/audiooutputenginedl.h
+++ b/drumgizmo/audiooutputenginedl.h
@@ -46,6 +46,7 @@ typedef void (*output_pre_func_t)(void*, size_t);
typedef void (*output_run_func_t)(void*,int,sample_t*,size_t);
typedef void (*output_post_func_t)(void*, size_t);
typedef size_t (*output_bufsize_func_t)(void*);
+typedef size_t (*output_samplerate_func_t)(void*);
class AudioOutputEngineDL : public AudioOutputEngine {
public:
@@ -64,6 +65,7 @@ public:
void post(size_t nsamples);
size_t getBufferSize();
+ size_t samplerate();
private:
void *ptr;
@@ -77,6 +79,7 @@ private:
output_run_func_t o_run;
output_post_func_t o_post;
output_bufsize_func_t o_bufsize;
+ output_samplerate_func_t o_samplerate;
bool is_jack_plugin;
JackClient *jackclient;
diff --git a/drumgizmo/output/jackaudio/jackaudio.cc b/drumgizmo/output/jackaudio/jackaudio.cc
index 2afe1ea..b7fa4f9 100644
--- a/drumgizmo/output/jackaudio/jackaudio.cc
+++ b/drumgizmo/output/jackaudio/jackaudio.cc
@@ -54,6 +54,7 @@ public:
void jack_process(jack_nframes_t nframes);
size_t bufsize();
+ size_t samplerate();
private:
JackClient *jackclient;
@@ -146,6 +147,11 @@ size_t JackAudio::bufsize()
return jack_get_buffer_size(jackclient->jack_client);
}
+size_t JackAudio::samplerate()
+{
+ return jack_get_sample_rate(jackclient->jack_client);
+}
+
extern "C" {
void *create()
{
@@ -205,6 +211,12 @@ extern "C" {
JackAudio *jack = (JackAudio*)h;
return jack->bufsize();
}
+
+ size_t samplerate(void *h)
+ {
+ JackAudio *jack = (JackAudio*)h;
+ return jack->samplerate();
+ }
}
#ifdef TEST_AUDIOINPUTENGINEJACKAUDIO
diff --git a/lv2/Makefile.am b/lv2/Makefile.am
index a714dce..9939131 100644
--- a/lv2/Makefile.am
+++ b/lv2/Makefile.am
@@ -3,12 +3,6 @@ if ENABLE_LV2
include $(top_srcdir)/plugingui/Makefile.am.plugingui
include $(top_srcdir)/src/Makefile.am.drumgizmo
-AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/plugingui \
- -I$(top_srcdir)/include $(SNDFILE_CXXFLAGS) \
- $(PTHREAD_CFLAGS) $(EXPAT_CFLAGS) $(LV2_CFLAGS) \
- $(PLUGIN_GUI_CFLAGS) $(SSEFLAGS)\
- -DUSE_THREAD $(SAMPLERATE_CFLAGS)
-
plugindir = $(prefix)/lib/lv2/drumgizmo.lv2
plugin_LTLIBRARIES = drumgizmo.la
plugin_DATA = manifest.ttl drumgizmo.ttl
@@ -21,6 +15,12 @@ EXTRA_DIST = \
lv2_gui.h \
lv2_instance.h
+drumgizmo_la_CXXFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/plugingui \
+ -I$(top_srcdir)/include $(SNDFILE_CXXFLAGS) \
+ $(PTHREAD_CFLAGS) $(EXPAT_CFLAGS) $(LV2_CFLAGS) \
+ $(PLUGIN_GUI_CFLAGS) $(SSEFLAGS) $(ZITA_CPPFLAGS) \
+ -DUSE_THREAD $(SAMPLERATE_CFLAGS)
+
drumgizmo_la_SOURCES = \
$(DRUMGIZMO_SOURCES) \
$(PLUGIN_GUI_SOURCES) \
diff --git a/src/Makefile.am.drumgizmo b/src/Makefile.am.drumgizmo
index c48c478..da5d839 100644
--- a/src/Makefile.am.drumgizmo
+++ b/src/Makefile.am.drumgizmo
@@ -26,4 +26,4 @@ DRUMGIZMO_SOURCES = \
$(top_srcdir)/src/velocity.cc \
$(top_srcdir)/src/versionstr.cc
-DRUMGIZMO_LIBS = $(SNDFILE_LIBS) $(EXPAT_LIBS) $(SAMPLERATE_LIBS) \ No newline at end of file
+DRUMGIZMO_LIBS = $(ZITA_LIBS) $(SNDFILE_LIBS) $(EXPAT_LIBS) $(SAMPLERATE_LIBS) \ No newline at end of file
diff --git a/src/audiofile.cc b/src/audiofile.cc
index 874b9c5..59e0c14 100644
--- a/src/audiofile.cc
+++ b/src/audiofile.cc
@@ -34,9 +34,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <sndfile.h>
-#ifdef WITH_RESAMPLE
-#include <samplerate.h>
-#endif/*WITH_RESAMPLE*/
#include <hugin.hpp>
#include "configuration.h"
@@ -154,39 +151,6 @@ void AudioFile::load(int num_samples)
sf_close(fh);
-#ifdef WITH_RESAMPLE
-
- // Check environment to see if resample should be disabled.
- // Defaults to "1" which is 'enable'. All other values are 'disabled'.
- const char *env_res = getenv("DRUMGIZMO_RESAMPLE");
- if(env_res == NULL) env_res = "1";
-
- if( (strcmp(env_res, "1") == 0) &&
- Conf::samplerate != sf_info.samplerate) {
- // Resample data...
- size_t osize = size * ratio;
- sample_t *odata = new sample_t[osize];
-
- SRC_DATA src;
- src.data_in = data;
- src.input_frames = size;
-
- src.data_out = odata;
- src.output_frames = osize;
-
- src.src_ratio = ratio;
-
- // Do the conversion
- src_simple(&src, SRC_SINC_BEST_QUALITY, 1);
-
- delete[] data;
- data = odata;
- size = src.output_frames;
-
- DEBUG(audiofile,"Converted into %d samples %p\n", (int)size, this);
- }
-#endif/*WITH_RESAMPLE*/
-
this->data = data;
is_loaded = true;
diff --git a/src/audiooutputengine.h b/src/audiooutputengine.h
index 7f15e49..25b6ea0 100644
--- a/src/audiooutputengine.h
+++ b/src/audiooutputengine.h
@@ -33,6 +33,8 @@
#include "channel.h"
+#define UNKNOWN_SAMPLERATE 0
+
class AudioOutputEngine {
public:
virtual ~AudioOutputEngine() {}
@@ -55,6 +57,11 @@ public:
* Overload this method to force engine to use different buffer size.
*/
virtual size_t getBufferSize() { return 1024; }
+
+ /**
+ * Overload this method to report output engine samplerate.
+ */
+ virtual size_t samplerate() { return UNKNOWN_SAMPLERATE; }
};
#endif/*__DRUMGIZMO_AUDIOOUTPUTENGINE_H__*/
diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index 5d67c86..3ffcba5 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -36,6 +36,19 @@
#include <hugin.hpp>
+#include <config.h>
+
+//
+// Warning: Zita currently not working...
+//
+#ifdef WITH_RESAMPLE
+#ifdef ZITA
+#include <zita-resampler/resampler.h>
+#else
+#include <samplerate.h>
+#endif/*ZITA*/
+#endif/*WITH_RESAMPLE*/
+
#include "drumkitparser.h"
#include "audioinputenginemidi.h"
#include "configuration.h"
@@ -158,6 +171,13 @@ void DrumGizmo::handleMessage(Message *msg)
bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
{
+ double samplerate_scale = 1.0;
+#ifndef WITH_RESAMPLE
+ if(oe->samplerate() != UNKNOWN_SAMPLERATE) {
+ samplerate_scale = (double)kit.samplerate() / (double)oe->samplerate();
+ }
+#endif/*WITH_RESAMPLE*/
+
// Handle engine messages, at most one in each iteration:
handleMessages(1);
@@ -240,7 +260,7 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
} else {
//DEBUG(drumgizmo, "Adding event %d.\n", evs[e].offset);
Event *evt = new EventSample(ch.num, 1.0, af, i->group(), i);
- evt->offset = evs[e].offset + pos;
+ evt->offset = (evs[e].offset + pos) * samplerate_scale;
activeevents[ch.num].push_back(evt);
}
j++;
@@ -255,22 +275,60 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
free(evs);
-
//
// Write audio
//
for(size_t c = 0; c < kit.channels.size(); c++) {
- sample_t *buf = samples;
- bool internal = false;
- if(oe->getBuffer(c)) {
- buf = oe->getBuffer(c);
- internal = true;
- }
- if(buf) {
- memset(buf, 0, nsamples * sizeof(sample_t));
+ if(samplerate_scale == 1.0) {
+ // No resampling needed
+ sample_t *buf = samples;
+ bool internal = false;
+ if(oe->getBuffer(c)) {
+ buf = oe->getBuffer(c);
+ internal = true;
+ }
+ if(buf) {
+ memset(buf, 0, nsamples * sizeof(sample_t));
- getSamples(c, pos, buf, nsamples);
- if(!internal) oe->run(c, samples, nsamples);
+ getSamples(c, pos, buf, nsamples);
+
+ if(!internal) oe->run(c, samples, nsamples);
+ }
+ } else {
+#ifdef WITH_RESAMPLE
+ // Resampling needed
+ size_t nkitsamples = nsamples * samplerate_scale;
+ sample_t kitsamples[nkitsamples];
+
+ memset(rs, 0, nkitsamples * sizeof(sample_t));
+ getSamples(c, pos * samplerate_scale, rs, nkitsamples);
+
+#ifdef ZITA
+ Resampler resampler;
+ resampler.setup(kit.samplerate(), oe->samplerate(), 1, 96);
+
+ resampler.inp_data = kitsamples;
+ resampler.inp_count = nkitsamples;
+
+ resampler.out_data = samples;
+ resampler.out_count = nsamples;
+
+ resampler.process();
+#else
+ SRC_DATA src;
+ src.data_in = kitsamples;
+ src.input_frames = nkitsamples;
+
+ src.data_out = samples;
+ src.output_frames = nsamples;
+
+ src.src_ratio = 1.0 / samplerate_scale;
+
+ src_simple(&src, SRC_SINC_BEST_QUALITY, 1);
+#endif/*ZITA*/
+
+ oe->run(c, samples, nsamples);
+#endif/*WITH_RESAMPLE*/
}
}
diff --git a/src/drumkit.cc b/src/drumkit.cc
index c2aa221..4d75f3b 100644
--- a/src/drumkit.cc
+++ b/src/drumkit.cc
@@ -50,6 +50,7 @@ void DrumKit::clear()
_name = "";
_description = "";
+ _samplerate = 44100;
}
bool DrumKit::isValid()
@@ -72,6 +73,11 @@ std::string DrumKit::description()
return _description;
}
+size_t DrumKit::samplerate()
+{
+ return _samplerate;
+}
+
#ifdef TEST_DRUMKIT
//Additional dependency files
//deps:
diff --git a/src/drumkit.h b/src/drumkit.h
index 82fe69b..04b2c56 100644
--- a/src/drumkit.h
+++ b/src/drumkit.h
@@ -53,6 +53,8 @@ public:
bool isValid();
+ size_t samplerate();
+
private:
void *magic;
@@ -60,6 +62,7 @@ private:
std::string _name;
std::string _description;
+ size_t _samplerate;
VersionStr _version;
};
diff --git a/src/drumkitparser.cc b/src/drumkitparser.cc
index 1b7ecaf..2c21c52 100644
--- a/src/drumkitparser.cc
+++ b/src/drumkitparser.cc
@@ -60,6 +60,14 @@ void DrumKitParser::startTag(std::string name,
if(attr.find("name") != attr.end())
kit._name = attr["name"];
+ if(attr.find("samplerate") != attr.end()) {
+ kit._samplerate = atoi(attr["samplerate"].c_str());
+ } else {
+ // If 'samplerate' attribute is missing, assume 44k1Hz
+ // TODO: Ask instrument what samplerate is in the audiofiles...
+ kit._samplerate = 44100;
+ }
+
if(attr.find("description") != attr.end())
kit._description = attr["description"];