summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/Makefile.am2
-rw-r--r--test/dgreftest/Makefile.am36
-rw-r--r--test/dgreftest/compareoutputengine.cc138
-rw-r--r--test/dgreftest/compareoutputengine.h55
-rw-r--r--test/dgreftest/dgreftest.cc136
-rw-r--r--test/dgreftest/midiinputengine.cc192
-rw-r--r--test/dgreftest/midiinputengine.h64
-rw-r--r--test/dgreftest/wavfileoutputengine.cc125
-rw-r--r--test/dgreftest/wavfileoutputengine.h54
9 files changed, 802 insertions, 0 deletions
diff --git a/test/Makefile.am b/test/Makefile.am
index a3a6294..594aa0d 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,4 +1,6 @@
# Rules for the test code (use `make check` to execute)
+SUBDIRS = dgreftest
+
include $(top_srcdir)/src/Makefile.am.drumgizmo
TESTS = resource engine gui resampler lv2 configfile audiocache \
diff --git a/test/dgreftest/Makefile.am b/test/dgreftest/Makefile.am
new file mode 100644
index 0000000..cacf26a
--- /dev/null
+++ b/test/dgreftest/Makefile.am
@@ -0,0 +1,36 @@
+if ENABLE_CLI
+if HAVE_INPUT_MIDIFILE
+
+include $(top_srcdir)/src/Makefile.am.drumgizmo
+
+bin_PROGRAMS = dgreftest
+
+dgreftest_LDADD = $(DRUMGIZMO_LIBS) $(PTHREAD_LIBS) -ldl $(JACK_LIBS) \
+ $(SMF_LIBS)
+
+dgreftest_LDFLAGS =
+
+dgreftest_CXXFLAGS = $(SNDFILE_CXXFLAGS) $(PTHREAD_CFLAGS) $(EXPAT_CFLAGS) \
+ -I$(top_srcdir)/include -I$(top_srcdir)/src \
+ -I$(top_srcdir)/hugin -DWITH_HUG_MUTEX -DWITH_HUG_FILTER \
+ $(JACK_CFLAGS) $(SSEFLAGS) $(SMF_CFLAGS)
+
+dgreftest_CFLAGS = -DWITH_HUG_MUTEX -DWITH_HUG_FILTER
+
+dgreftest_SOURCES = \
+ dgreftest.cc \
+ midiinputengine.cc \
+ wavfileoutputengine.cc \
+ compareoutputengine.cc \
+ $(DRUMGIZMO_SOURCES) \
+ $(top_srcdir)/hugin/hugin.c \
+ $(top_srcdir)/hugin/hugin_filter.c
+
+endif # HAVE_INPUT_MIDIFILE
+
+EXTRA_DIST = \
+ midiinputengine.h \
+ wavfileoutputengine.h \
+ compareoutputengine.h
+
+endif # ENABLE_CLI
diff --git a/test/dgreftest/compareoutputengine.cc b/test/dgreftest/compareoutputengine.cc
new file mode 100644
index 0000000..4b13566
--- /dev/null
+++ b/test/dgreftest/compareoutputengine.cc
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * compareoutputengine.cc
+ *
+ * Sat May 14 13:27:04 CEST 2016
+ * Copyright 2016 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 Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 "compareoutputengine.h"
+
+#include <iostream>
+
+CompareOutputEngine::CompareOutputEngine()
+ : AudioOutputEngine{}
+ , info{}
+ , file{"output"}
+{
+ info.samplerate = 44100;
+ info.channels = 1;
+ info.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
+}
+
+CompareOutputEngine::~CompareOutputEngine()
+{
+ std::cout << "diff_samples: " << diff_samples << std::endl;
+ sf_close(handle);
+}
+
+bool CompareOutputEngine::init(const Channels& data)
+{
+ info.channels = data.size();
+
+ handle = sf_open(file.c_str(), SFM_READ, &info);
+ if(handle == nullptr)
+ {
+ std::cerr << "[CompareOutputEngine] Failed to open "
+ << file << " for writing.\n";
+ return false;
+ }
+
+ return true;
+}
+
+void CompareOutputEngine::setParm(const std::string& parm, const std::string& value)
+{
+ if(parm == "file")
+ {
+ // apply output filename prefix
+ file = value;
+ }
+ else if(parm == "srate")
+ {
+ // try to apply samplerate
+ try
+ {
+ info.samplerate = std::stoi(value);
+ }
+ catch(...)
+ {
+ std::cerr << "[CompareOutputEngine] Invalid samplerate " << value
+ << "\n";
+ }
+ }
+ else
+ {
+ std::cerr << "[CompareOutputEngine] Unsupported parameter '" << parm
+ << "'\n";
+ }
+}
+
+bool CompareOutputEngine::start()
+{
+ return true;
+}
+
+void CompareOutputEngine::stop()
+{
+}
+
+void CompareOutputEngine::pre(size_t nsamples)
+{
+}
+
+void CompareOutputEngine::run(int ch, sample_t* samples, size_t nsamples)
+{
+ if(ch >= info.channels)
+ {
+ std::cerr << "[CompareOutputEngine] cannot access channel #" << ch
+ << " (" << info.channels << " channels available)\n";
+ return;
+ }
+
+ for(std::size_t i = 0; i < nsamples; ++i)
+ {
+ buffer[i * info.channels + ch] = samples[i];
+ }
+}
+
+void CompareOutputEngine::post(size_t nsamples)
+{
+ sample_t ref_buffer[sizeof(buffer) / sizeof(sample_t)];
+ sf_readf_float(handle, ref_buffer, nsamples);
+
+ for(std::size_t i = 0; i < nsamples; ++i)
+ {
+ for(std::size_t ch = 0; ch < (std::size_t)info.channels; ++ch)
+ {
+ if(buffer[i * info.channels + ch] != ref_buffer[i * info.channels + ch])
+ {
+ ++diff_samples;
+ }
+ }
+ }
+
+}
+
+size_t CompareOutputEngine::getSamplerate() const
+{
+ return info.samplerate;
+}
diff --git a/test/dgreftest/compareoutputengine.h b/test/dgreftest/compareoutputengine.h
new file mode 100644
index 0000000..fb610d6
--- /dev/null
+++ b/test/dgreftest/compareoutputengine.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * compareoutputengine.h
+ *
+ * Sat May 14 13:27:04 CEST 2016
+ * Copyright 2016 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 Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+#pragma once
+
+#include <sndfile.h>
+#include <audiooutputengine.h>
+
+class CompareOutputEngine
+ : public AudioOutputEngine
+{
+public:
+ CompareOutputEngine();
+ ~CompareOutputEngine();
+
+ // based on AudioOutputEngine
+ bool init(const Channels& data) override;
+ void setParm(const std::string& parm, const std::string& value) override;
+ bool start() override;
+ void stop() override;
+ void pre(size_t nsamples) override;
+ void run(int ch, sample_t* samples, size_t nsamples) override;
+ void post(size_t nsamples) override;
+ size_t getSamplerate() const override;
+
+private:
+ SF_INFO info;
+ SNDFILE* handle;
+ std::string file;
+ sample_t buffer[4096 * 16];
+ std::size_t diff_samples{0};
+};
diff --git a/test/dgreftest/dgreftest.cc b/test/dgreftest/dgreftest.cc
new file mode 100644
index 0000000..072dcdc
--- /dev/null
+++ b/test/dgreftest/dgreftest.cc
@@ -0,0 +1,136 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * dgreftest.cc
+ *
+ * Thu May 12 17:50:08 CEST 2016
+ * Copyright 2016 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 Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 <drumgizmo.h>
+
+#include <string>
+#include <iostream>
+#include <cassert>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "compareoutputengine.h"
+#include "midiinputengine.h"
+#include "wavfileoutputengine.h"
+
+#include <cpp11fix.h> // required for c++11
+
+std::unique_ptr<AudioOutputEngine> createOutput(const std::string& name)
+{
+ struct stat sb;
+ if((stat(name.c_str(), &sb) == -1) && (errno == ENOENT))
+ {
+ // Ref file doesn't exist - create it.
+ return std::make_unique<WavfileOutputEngine>();
+ }
+ else
+ {
+ // Ref file exists, do compare.
+ return std::make_unique<CompareOutputEngine>();
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ if(argc < 4)
+ {
+ std::cerr << "Usage: " << argv[0] << " testname drumkit midimap [seed]" << std::endl;
+ return 1;
+ }
+
+ Settings settings;
+
+ std::string test = argv[1];
+ std::string kitfile = argv[2];
+ std::string midimap = argv[3];
+
+ unsigned int seed = 0;
+ if(argc == 5)
+ {
+ seed = atoi(argv[4]);
+ }
+
+ std::string midifile = test + ".mid";
+ std::string reffile = test + ".wav";
+
+ MidifileInputEngine ie;
+ ie.setParm("file", midifile.c_str());
+
+ auto oe = createOutput(reffile);
+
+ oe->setParm("file", reffile.c_str());
+ oe->setParm("srate", "44100");
+
+ DrumGizmo drumgizmo(settings, oe.get(), &ie);
+ drumgizmo.setRandomSeed(seed);
+ drumgizmo.setFreeWheel(true); // Run in-sync with disk-cache
+ drumgizmo.setFrameSize(oe->getBufferSize());
+
+// settings.enable_resampling.store(false); // Bypass resampler - BROKEN
+
+ settings.drumkit_file.store(kitfile);
+ settings.midimap_file.store(midimap);
+
+ printf("Loading drumkit, this may take a while:\n");
+
+ while(settings.drumkit_load_status.load() != LoadStatus::Done)
+ {
+ usleep(10000);
+
+ int total = settings.number_of_files.load();
+ int loaded = settings.number_of_files_loaded.load();
+
+ printf("\r%d of %d ", loaded, total);
+ fflush(stdout);
+
+ if(settings.drumkit_load_status.load() == LoadStatus::Error)
+ {
+ printf("\nFailed to load \"%s\".\n", kitfile.c_str());
+ return 1;
+ }
+
+ if(loaded == total)
+ {
+ //break;
+ }
+ }
+ printf("\ndone\n");
+
+ drumgizmo.setSamplerate(oe->getSamplerate());
+
+
+ if(!drumgizmo.init())
+ {
+ printf("Failed init engine.\n");
+ return 1;
+ }
+
+ drumgizmo.run(-1);
+
+ return 0;
+}
diff --git a/test/dgreftest/midiinputengine.cc b/test/dgreftest/midiinputengine.cc
new file mode 100644
index 0000000..bc0fa87
--- /dev/null
+++ b/test/dgreftest/midiinputengine.cc
@@ -0,0 +1,192 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * midiinputengine.cc
+ *
+ * Sat May 14 13:26:23 CEST 2016
+ * Copyright 2016 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 Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 "midiinputengine.h"
+
+#include <iostream>
+
+static int const NOTE_ON = 0x90;
+
+MidifileInputEngine::MidifileInputEngine()
+ : AudioInputEngineMidi{}
+ , smf{nullptr}
+ , current_event{nullptr}
+ , file{}
+ , speed{1.f}
+ , track{-1} // all tracks
+ , loop{false}
+ , offset{0.0}
+ , samplerate{44100.0} // todo: via ctor arg
+{
+}
+
+MidifileInputEngine::~MidifileInputEngine()
+{
+ if(smf != nullptr)
+ {
+ smf_delete(smf);
+ }
+}
+
+bool MidifileInputEngine::init(const Instruments& instruments)
+{
+ if(file == "")
+ {
+ std::cerr << "[MidifileInputEngine] Missing midi filename\n";
+ return false;
+ }
+ //if(midimap_filename == "")
+ //{
+ // std::cerr << "[MidifileInputEngine] Missing midimap filename\n";
+ // return false;
+ //}
+ smf = smf_load(file.c_str());
+ if(smf == nullptr)
+ {
+ std::cerr << "[MidifileInputEngine] Failed to load midifile '" << file
+ << "'\n";
+ return false;
+ }
+ //if(!loadMidiMap(midimap_filename, instruments))
+ //{
+ // std::cerr << "[MidifileInputEngine] Failed to parse midimap '"
+ // << midimap_filename << "'\n";
+ // return false;
+ //}
+
+ return true;
+}
+
+void MidifileInputEngine::setParm(const std::string& parm, const std::string& value)
+{
+ if(parm == "file")
+ {
+ // apply midi input filename
+ file = value;
+ }
+ else if(parm == "speed")
+ {
+ // try to apply speed
+ try
+ {
+ speed = std::stof(value);
+ }
+ catch(...)
+ {
+ std::cerr << "[MidifileInputEngine] Invalid speed " << value
+ << "\n";
+ }
+ }
+ //else if(parm == "midimap")
+ //{
+ // // apply midimap filename
+ // midimap_filename = value;
+ //}
+ else if(parm == "loop")
+ {
+ // apply looping
+ loop = true;
+ }
+ else
+ {
+ std::cerr << "[MidifileInputEngine] Unsupported parameter '" << parm
+ << "'\n";
+ }
+}
+
+bool MidifileInputEngine::start()
+{
+ return true;
+}
+
+void MidifileInputEngine::stop()
+{
+}
+
+void MidifileInputEngine::pre()
+{
+}
+
+void MidifileInputEngine::run(size_t pos, size_t len, std::vector<event_t>& events)
+{
+ assert(events.empty());
+
+ double current_max_time = (1.0 + pos + len) / (samplerate / speed);
+ current_max_time -= offset;
+
+ if(!current_event)
+ {
+ current_event = smf_get_next_event(smf);
+ }
+
+ while(current_event && current_event->time_seconds < current_max_time)
+ {
+ if(!smf_event_is_metadata(current_event))
+ {
+ if((current_event->midi_buffer_length == 3) &&
+ ((current_event->midi_buffer[0] & NOTE_ON) == NOTE_ON) &&
+ (track == -1 || current_event->track_number == track) &&
+ current_event->midi_buffer[2] > 0)
+ {
+ int key = current_event->midi_buffer[1];
+ int velocity = current_event->midi_buffer[2];
+
+ events.emplace_back();
+ auto& event = events.back();
+ event.type = TYPE_ONSET;
+ size_t evpos = current_event->time_seconds * (samplerate / speed);
+ event.offset = evpos - pos;
+
+ int i = mmap.lookup(key);
+ if(i != -1)
+ {
+ event.instrument = i;
+ event.velocity = velocity / 127.0;
+ }
+ }
+ }
+
+ current_event = smf_get_next_event(smf);
+ }
+
+ if(!current_event)
+ {
+ if(loop)
+ {
+ smf_rewind(smf);
+ offset += current_max_time;
+ }
+ else
+ {
+ assert(len >= 1);
+ events.push_back({TYPE_STOP, 0, len-1, 0.f});
+ }
+ }
+}
+
+void MidifileInputEngine::post()
+{
+}
diff --git a/test/dgreftest/midiinputengine.h b/test/dgreftest/midiinputengine.h
new file mode 100644
index 0000000..3740d44
--- /dev/null
+++ b/test/dgreftest/midiinputengine.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * midiinputengine.h
+ *
+ * Sat May 14 13:26:22 CEST 2016
+ * Copyright 2016 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 Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+#pragma once
+
+#include <audioinputenginemidi.h>
+#include <midimapper.h>
+#include <midimapparser.h>
+#include <string>
+#include <vector>
+
+#include <event.h>
+#include <smf.h>
+
+class MidifileInputEngine
+ : public AudioInputEngineMidi
+{
+public:
+ MidifileInputEngine();
+ ~MidifileInputEngine();
+
+ // based on AudioInputEngineMidi
+ bool init(const Instruments& instruments) override;
+ void setParm(const std::string& parm, const std::string& value) override;
+ bool start() override;
+ void stop() override;
+ void pre() override;
+ void run(size_t pos, size_t len, std::vector<event_t>& events) override;
+ void post() override;
+
+private:
+ smf_t* smf;
+ smf_event_t* current_event;
+
+ std::string midimap_filename;
+ std::string file;
+ float speed;
+ int track;
+ bool loop;
+ double offset, samplerate;
+};
diff --git a/test/dgreftest/wavfileoutputengine.cc b/test/dgreftest/wavfileoutputengine.cc
new file mode 100644
index 0000000..6f971ad
--- /dev/null
+++ b/test/dgreftest/wavfileoutputengine.cc
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * wavfileoutputengine.cc
+ *
+ * Sat May 14 13:26:51 CEST 2016
+ * Copyright 2016 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 Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 "wavfileoutputengine.h"
+
+#include <iostream>
+
+WavfileOutputEngine::WavfileOutputEngine()
+ : AudioOutputEngine{}
+ , info{}
+ , file{"output"}
+{
+ info.samplerate = 44100;
+ info.channels = 1;
+ info.format = SF_FORMAT_WAV | SF_FORMAT_FLOAT;
+}
+
+WavfileOutputEngine::~WavfileOutputEngine()
+{
+ sf_close(handle);
+}
+
+bool WavfileOutputEngine::init(const Channels& data)
+{
+ info.channels = data.size();
+
+ handle = sf_open(file.c_str(), SFM_WRITE, &info);
+ if(handle == nullptr)
+ {
+ std::cerr << "[WavfileOutputEngine] Failed to open "
+ << file << " for writing.\n";
+ return false;
+ }
+
+ return true;
+}
+
+void WavfileOutputEngine::setParm(const std::string& parm, const std::string& value)
+{
+ if(parm == "file")
+ {
+ // apply output filename prefix
+ file = value;
+ }
+ else if(parm == "srate")
+ {
+ // try to apply samplerate
+ try
+ {
+ info.samplerate = std::stoi(value);
+ }
+ catch(...)
+ {
+ std::cerr << "[WavfileOutputEngine] Invalid samplerate " << value
+ << "\n";
+ }
+ }
+ else
+ {
+ std::cerr << "[WavfileOutputEngine] Unsupported parameter '" << parm
+ << "'\n";
+ }
+}
+
+bool WavfileOutputEngine::start()
+{
+ return true;
+}
+
+void WavfileOutputEngine::stop()
+{
+}
+
+void WavfileOutputEngine::pre(size_t nsamples)
+{
+}
+
+void WavfileOutputEngine::run(int ch, sample_t* samples, size_t nsamples)
+{
+ if(ch >= info.channels)
+ {
+ std::cerr << "[WavfileOutputEngine] cannot access channel #" << ch
+ << " (" << info.channels << " channels available)\n";
+ return;
+ }
+
+ for(std::size_t i = 0; i < nsamples; ++i)
+ {
+ buffer[i * info.channels + ch] = samples[i];
+ }
+}
+
+void WavfileOutputEngine::post(size_t nsamples)
+{
+
+ sf_writef_float(handle, buffer, nsamples);
+}
+
+size_t WavfileOutputEngine::getSamplerate() const
+{
+ return info.samplerate;
+}
diff --git a/test/dgreftest/wavfileoutputengine.h b/test/dgreftest/wavfileoutputengine.h
new file mode 100644
index 0000000..6937ed2
--- /dev/null
+++ b/test/dgreftest/wavfileoutputengine.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * wavfileoutputengine.h
+ *
+ * Sat May 14 13:26:51 CEST 2016
+ * Copyright 2016 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 Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+#pragma once
+
+#include <sndfile.h>
+#include <audiooutputengine.h>
+
+class WavfileOutputEngine
+ : public AudioOutputEngine
+{
+public:
+ WavfileOutputEngine();
+ ~WavfileOutputEngine();
+
+ // based on AudioOutputEngine
+ bool init(const Channels& data) override;
+ void setParm(const std::string& parm, const std::string& value) override;
+ bool start() override;
+ void stop() override;
+ void pre(size_t nsamples) override;
+ void run(int ch, sample_t* samples, size_t nsamples) override;
+ void post(size_t nsamples) override;
+ size_t getSamplerate() const override;
+
+private:
+ SF_INFO info;
+ SNDFILE* handle;
+ std::string file;
+ sample_t buffer[4096 * 16];
+};