From 0e048dee411cc20beb2a8667e5bb339f9b7fb939 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sat, 17 May 2014 21:27:52 +0200 Subject: New resample feature on output channels. --- src/Makefile.am.drumgizmo | 2 +- src/audiofile.cc | 36 --------------------- src/audiooutputengine.h | 7 ++++ src/drumgizmo.cc | 82 ++++++++++++++++++++++++++++++++++++++++------- src/drumkit.cc | 6 ++++ src/drumkit.h | 3 ++ src/drumkitparser.cc | 8 +++++ 7 files changed, 95 insertions(+), 49 deletions(-) (limited to 'src') 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 #include #include -#ifdef WITH_RESAMPLE -#include -#endif/*WITH_RESAMPLE*/ #include #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 +#include + +// +// Warning: Zita currently not working... +// +#ifdef WITH_RESAMPLE +#ifdef ZITA +#include +#else +#include +#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"]; -- cgit v1.2.3