[SCM] drumgizmo/master: New upstream version 0.9.14

viccuad-guest at users.alioth.debian.org viccuad-guest at users.alioth.debian.org
Sun May 14 20:46:02 UTC 2017


The following commit has been merged in the master branch:
commit abdef5630c0db410498e96cbde6db4da53dadb03
Author: Víctor Cuadrado Juan <me at viccuad.me>
Date:   Sun May 14 20:29:18 2017 +0200

    New upstream version 0.9.14

diff --git a/ChangeLog b/ChangeLog
index a65ebce..14ece14 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,43 @@
+Version 0.9.14
+==============
+Note: LAC2017 release
+Release date: May 14th 2017
+Contributors: deva, chaot4, Muldjord, meka, Hans Petter Selasky
+Special extra thanks with a cherry on top: Robin Gareus
+
+Features:
+ - Introduced new resampler module in ui
+
+Bugfixes:
+ - CLI
+   - CLI exits right away, doesn't do anything
+   - Make ''-i midifile -I midimap=~/...'' recognize the home directory. Replace "~" by the home directory in ./drumgizmo/input/midifile.cc
+   - Properly get/set OSS buffers
+   - Add ---no-resampling option
+
+ - Engine
+   - Fix midi note on/off mask
+   - Streamer BUG: If there is a cache miss on one of the audiofiles (1 channel) in a sample that one sample will get delayed compared to the others
+   - Streamer BUG: When nodata buffer is being reallocated we need to make sure that the old buffer is not being used by one of the cache ids
+   - Resampler BUG: Fix corruption/crash when enabling/disabling resampler at run-time
+   - Update Window build environment to a more recent mingw64
+   - Remove obsolete old mingw32 thread hacks
+   - Introduce clear signal, showing if we had an underrun because of diskstreaming
+   - Fix crash on with low preload size
+   - Initial status of drumkit is "Error" on first opening the plugin
+
+ - UI
+   - Scroll-wheel on tab buttons should iterate through the tabs
+   - Refactor TextEdit. (use vector in preprocessing etc.)
+   - Fix "unexpected easter egg"
+   - Fix high CPU load of plugingui when shown in a host (All platforms/DAWs)
+   - Return handle to the newly created window in ''PluginLV2::uiInstantiate'' in the ''widget'' pointer
+   - Add bypass button for the resampler
+   - Fix redraw on changing desktops
+
+ - General
+   - Don't put .a and .la files in lv2 folder on install
+
 Version 0.9.13
 ==============
 Release date: April 23rd 2017
diff --git a/README b/README
index f75599a..1b4e8a4 100644
--- a/README
+++ b/README
@@ -41,6 +41,7 @@ $ make install
 Compiling from git sources
 --------------------------
 $ git clone http://git.drumgizmo.org/drumgizmo.git
+$ cd drumgizmo
 $ git submodule init
 $ git submodule update
 $ ./autogen.sh
@@ -68,4 +69,4 @@ plugin dir (usually /usr/lib/lv2) or create a symbolic link to the directory
 $ ln -s [dg path]/install/lib/lv2/drumgizmo.lv2 /usr/lib/lv2/drumgizmo.lv2
 
 You need to be root to do this. Keep in mind that the lv2 directory differs from
-distro to distro, so do a search for it in order to verify the correct location.
\ No newline at end of file
+distro to distro, so do a search for it in order to verify the correct location.
diff --git a/configure b/configure
index cd7f6f3..e6ab017 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for drumgizmo 0.9.13.
+# Generated by GNU Autoconf 2.69 for drumgizmo 0.9.14.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='drumgizmo'
 PACKAGE_TARNAME='drumgizmo'
-PACKAGE_VERSION='0.9.13'
-PACKAGE_STRING='drumgizmo 0.9.13'
+PACKAGE_VERSION='0.9.14'
+PACKAGE_STRING='drumgizmo 0.9.14'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1440,7 +1440,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures drumgizmo 0.9.13 to adapt to many kinds of systems.
+\`configure' configures drumgizmo 0.9.14 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1510,7 +1510,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of drumgizmo 0.9.13:";;
+     short | recursive ) echo "Configuration of drumgizmo 0.9.14:";;
    esac
   cat <<\_ACEOF
 
@@ -1678,7 +1678,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-drumgizmo configure 0.9.13
+drumgizmo configure 0.9.14
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2202,7 +2202,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by drumgizmo $as_me 0.9.13, which was
+It was created by drumgizmo $as_me 0.9.14, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3066,7 +3066,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='drumgizmo'
- VERSION='0.9.13'
+ VERSION='0.9.14'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -16371,7 +16371,7 @@ $as_echo "Auto setting gui based on host: $host_os" >&6; }
     enable_gui="cocoa" ;; #(
   linux*|*bsd*) :
     enable_gui="x11" ;; #(
-  mingw*|windows*|winnt|cygwin) :
+  msys|mingw*|windows*|winnt|cygwin) :
     enable_gui="win32" ;; #(
   *) :
     as_fn_error $? "Your platform is not currently supported" "$LINENO" 5
@@ -16874,7 +16874,7 @@ if test "x$enable_vst" = "xyes"; then :
       ;; #(
   linux*|*bsd*) :
     VST_CPPFLAGS="$VST_CPPFLAGS -D__cdecl=" ;; #(
-  mingw*|windows*|winnt|cygwin) :
+  msys|mingw*|windows*|winnt|cygwin) :
       ;; #(
   *) :
     as_fn_error $? "Your platform is not currently supported" "$LINENO" 5
@@ -18702,7 +18702,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by drumgizmo $as_me 0.9.13, which was
+This file was extended by drumgizmo $as_me 0.9.14, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -18768,7 +18768,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-drumgizmo config.status 0.9.13
+drumgizmo config.status 0.9.14
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index c2c17ef..5de59b9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -143,7 +143,7 @@ AS_IF([test "x$enable_gui" = "xauto"],
 	     AS_CASE([$host_os],
 		      [darwin*], [enable_gui="cocoa"],
 		      [linux*|*bsd*], [enable_gui="x11"],
-		      [mingw*|windows*|winnt|cygwin], [enable_gui="win32"],
+		      [msys|mingw*|windows*|winnt|cygwin], [enable_gui="win32"],
 
 		      AC_MSG_ERROR([Your platform is not currently supported])
 	     )]
@@ -251,7 +251,7 @@ AS_IF(
 	AS_CASE([$host_os],
 		[darwin*], [ ],
 		[linux*|*bsd*], [VST_CPPFLAGS="$VST_CPPFLAGS -D__cdecl="],
-		[mingw*|windows*|winnt|cygwin], [ ],
+		[msys|mingw*|windows*|winnt|cygwin], [ ],
 		AC_MSG_ERROR([Your platform is not currently supported])
 	)
 
diff --git a/drumgizmo/drumgizmoc.cc b/drumgizmo/drumgizmoc.cc
index c8de8b8..6244125 100644
--- a/drumgizmo/drumgizmoc.cc
+++ b/drumgizmo/drumgizmoc.cc
@@ -32,8 +32,10 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <sstream>
+#include <chrono>
+#include <thread>
+#include <wordexp.h>
 
 #include <hugin.hpp>
 
@@ -47,13 +49,13 @@
 static const char version_str[] = "DrumGizmo v" VERSION "\n";
 
 static const char copyright_str[] =
-    "Copyright (C) 2008-2011 Bent Bisballe Nyeng - Aasimon.org.\n"
-    "This is free software.  You may redistribute copies of it under the terms "
-    "of\n"
-    "the GNU Lesser General Public License <http://www.gnu.org/licenses/gpl.html>.\n"
-    "There is NO WARRANTY, to the extent permitted by law.\n"
-    "\n"
-    "Written by Bent Bisballe Nyeng (deva at aasimon.org)\n";
+	"Copyright (C) 2008-2011 Bent Bisballe Nyeng - Aasimon.org.\n"
+	"This is free software.  You may redistribute copies of it under the terms "
+	"of\n"
+	"the GNU Lesser General Public License <http://www.gnu.org/licenses/gpl.html>.\n"
+	"There is NO WARRANTY, to the extent permitted by law.\n"
+	"\n"
+	"Written by Bent Bisballe Nyeng (deva at aasimon.org)\n";
 
 static const char usage_str[] =
     "Usage: %s [options] drumkitfile\n"
@@ -71,6 +73,7 @@ static const char usage_str[] =
     "  -D, --debug ddd        Enable debug messages on 'ddd'; see hugin "
     "documentation for details\n"
 #endif /*DISABLE_HUGIN*/
+    "  -r, --no-resampling    Disable resampling.\n"
     "  -s, --streaming        Enable streaming.\n"
     "  -S, --streamingparms   Streaming options.\n"
     "  -v, --version          Print version information and exit.\n"
@@ -140,11 +143,12 @@ int main(int argc, char* argv[])
 		{"streamingparams", required_argument, 0, 'S'},
 		{"version", no_argument, 0, 'v'},
 		{"help", no_argument, 0, 'h'},
+		{"no-resample", no_argument, 0, 'r'},
 		{0, 0, 0, 0}
 	};
 	while(1)
 	{
-		c = getopt_long(argc, argv, "hvpo:O:i:I:e:asS:"
+		c = getopt_long(argc, argv, "hvpo:O:i:I:e:arsS:"
 #ifndef DISABLE_HUGIN
 		                "D:"
 #endif /*DISABLE_HUGIN*/
@@ -219,6 +223,10 @@ int main(int argc, char* argv[])
 			printf("%s", copyright_str);
 			return 0;
 
+		case 'r':
+			settings.enable_resampling = false;
+			break;
+
 		case 's':
 			settings.disk_cache_enable = true;
 			break;
@@ -260,11 +268,19 @@ int main(int argc, char* argv[])
 		std::string parm;
 		std::string val;
 		bool inval = false;
+		wordexp_t exp_result;
 		for(size_t i = 0; i < iparms.size(); ++i)
 		{
 			if(iparms[i] == ',')
 			{
-				ie->setParm(parm, val);
+				int error = wordexp(val.data(), &exp_result, 0);
+				if(error)
+				{
+					std::cerr << "Wrong argument: ";
+					std::cerr << parm << " = " << val << std::endl;
+					return 1;
+				}
+				ie->setParm(parm, exp_result.we_wordv[0]);
 				parm = "";
 				val = "";
 				inval = false;
@@ -288,7 +304,14 @@ int main(int argc, char* argv[])
 		}
 		if(parm != "")
 		{
-			ie->setParm(parm, val);
+			int error = wordexp(val.data(), &exp_result, 0);
+			if(error)
+			{
+				std::cerr << "Wrong argument: ";
+				std::cerr << parm << " = " << val << std::endl;
+				return 1;
+			}
+			ie->setParm(parm, exp_result.we_wordv[0]);
 		}
 	}
 
@@ -339,7 +362,6 @@ int main(int argc, char* argv[])
 				}
 			}
 		}
-		return 0;
 	}
 
 	if(outputengine == "")
@@ -422,6 +444,7 @@ int main(int argc, char* argv[])
 	gizmo.setFrameSize(oe->getBufferSize());
 
 	settings.drumkit_file.store(kitfile);
+	settings.reload_counter++;
 
 	printf("Loading drumkit, this may take a while:\n");
 
@@ -429,11 +452,7 @@ int main(int argc, char* argv[])
 	{
 		while(settings.drumkit_load_status.load() != LoadStatus::Done)
 		{
-#ifdef WIN32
-			SleepEx(10, FALSE);
-#else
-			usleep(10000);
-#endif /*WIN32*/
+			std::this_thread::sleep_for(std::chrono::milliseconds(10));
 
 			int total = settings.number_of_files.load();
 			int loaded =  settings.number_of_files_loaded.load();
diff --git a/drumgizmo/input/jackmidi.cc b/drumgizmo/input/jackmidi.cc
index 7c5cf1c..8f8d5cb 100644
--- a/drumgizmo/input/jackmidi.cc
+++ b/drumgizmo/input/jackmidi.cc
@@ -31,6 +31,7 @@
 #include "jackmidi.h"
 
 static int const NOTE_ON = 0x90;
+static int const NOTE_MASK = 0xF0;
 
 JackMidiInputEngine::JackMidiInputEngine(JackClient& client)
 	: AudioInputEngineMidi{}
@@ -122,7 +123,7 @@ void JackMidiInputEngine::process(jack_nframes_t num_frames)
 		{
 			continue;
 		}
-		if((event.buffer[0] & NOTE_ON) != NOTE_ON)
+		if((event.buffer[0] & NOTE_MASK) != NOTE_ON)
 		{
 			continue;
 		}
diff --git a/drumgizmo/input/midifile.cc b/drumgizmo/input/midifile.cc
index 89ffa6b..c3bd8ae 100644
--- a/drumgizmo/input/midifile.cc
+++ b/drumgizmo/input/midifile.cc
@@ -30,6 +30,7 @@
 #include "midifile.h"
 
 static int const NOTE_ON = 0x90;
+static int const NOTE_MASK = 0xF0;
 
 MidifileInputEngine::MidifileInputEngine()
 	: AudioInputEngineMidi{}
@@ -147,7 +148,7 @@ void MidifileInputEngine::run(size_t pos, size_t len, std::vector<event_t>& even
 		if(!smf_event_is_metadata(current_event))
 		{
 			if((current_event->midi_buffer_length == 3) &&
-			    ((current_event->midi_buffer[0] & NOTE_ON) == NOTE_ON) &&
+			    ((current_event->midi_buffer[0] & NOTE_MASK) == NOTE_ON) &&
 			    (track == -1 || current_event->track_number == track) &&
 			    current_event->midi_buffer[2] > 0)
 			{
diff --git a/drumgizmo/output/oss.cc b/drumgizmo/output/oss.cc
index ee13a84..80d8d2b 100644
--- a/drumgizmo/output/oss.cc
+++ b/drumgizmo/output/oss.cc
@@ -40,6 +40,7 @@ OSSOutputEngine::OSSOutputEngine()
 	, data{}
 	, max_fragments{4}
 	, fragment_size{8}
+	, buffer_size{1024}
 {
 	data.clear();
 	data.resize(1024 * num_channels);
@@ -47,7 +48,7 @@ OSSOutputEngine::OSSOutputEngine()
 
 bool OSSOutputEngine::init(const Channels& channels)
 {
-	int tmp, mode = O_WRONLY, fragments;
+	std::size_t tmp, mode = O_WRONLY, fragments;
 	num_channels = channels.size();
 
 	if((fd = open(dev.data(), mode, 0)) == -1)
@@ -58,12 +59,30 @@ bool OSSOutputEngine::init(const Channels& channels)
 
 	fragments = max_fragments << 16 | fragment_size;
 	tmp = fragments;
-	if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1 || tmp != fragments)
+	if(ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &tmp) == -1)
 	{
-		perror("SNDCTL_DSP_SETFRAGMENT");
-		exit(-1);
+		std::cerr << "Can not set buffer size: ";
+		std::cerr << std::strerror(errno) << std::endl;
+		return false;
+	}
+	if(tmp != fragments)
+	{
+		std::size_t real_fragment_size = fragments & 0xffff;
+		std::size_t real_max_fragments = (fragments - real_fragment_size) >> 16;
+		std::cerr << "Values corrected to:" << std::endl;
+		std::cerr << "  fragment_size: " << real_fragment_size << std::endl;
+		std::cerr << "  max_fragments: " << real_max_fragments << std::endl;
 	}
 
+	audio_buf_info info;
+	if(ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) == -1)
+	{
+		std::cerr << "Can not get buffer info: ";
+		std::cerr << std::strerror(errno) << std::endl;
+		return false;
+	}
+	buffer_size = info.bytes / sizeof(decltype (data)::value_type);
+
 	tmp = format;
 	if(ioctl(fd, SNDCTL_DSP_SETFMT, &tmp) == -1 || tmp != format)
 	{
@@ -140,11 +159,19 @@ void OSSOutputEngine::setParm(const std::string& parm, const std::string& value)
 		}
 		if(fragment_size < 4)
 		{
-			std::cerr << "[OSSoutputEngine] fragment_size must be at least 4\n";
-			std::cerr << "Setting fragment_size to 4 (";
 			fragment_size = 4;
-			auto fragment_byte_size = 1 << fragment_size;
-			std::cerr << fragment_byte_size << "Bytes)" << std::endl;
+			std::cerr << "[OSSoutputEngine] fragment_size must be at least ";
+			std::cerr << fragment_size << std::endl;
+			std::cerr << "Setting fragment_size to ";
+			std::cerr << fragment_size << std::endl;
+		}
+		else if(fragment_size > 0xffff)
+		{
+			fragment_size = 0xffff;
+			std::cerr << "[OSSoutputEngine] fragment_size must be at most ";
+			std::cerr << fragment_size << std::endl;
+			std::cerr << "Setting fragment_size to ";
+			std::cerr << fragment_size << std::endl;
 		}
 	}
 	else
@@ -195,7 +222,7 @@ void OSSOutputEngine::post(size_t nsamples)
 
 std::size_t OSSOutputEngine::getBufferSize() const
 {
-	return data.size() / num_channels;
+	return buffer_size;
 }
 
 std::size_t OSSOutputEngine::getSamplerate() const
diff --git a/drumgizmo/output/oss.h b/drumgizmo/output/oss.h
index 889021f..880ab9c 100644
--- a/drumgizmo/output/oss.h
+++ b/drumgizmo/output/oss.h
@@ -52,7 +52,8 @@ private:
 	std::size_t num_channels;
 	unsigned int srate;
 	unsigned int format;
-	unsigned int max_fragments;
-	unsigned int fragment_size;
+	std::size_t max_fragments;
+	std::size_t fragment_size;
+	std::size_t buffer_size;
 	std::vector<std::int32_t> data;
 };
diff --git a/plugin/Makefile.am b/plugin/Makefile.am
index 2b4ff3e..91c3215 100644
--- a/plugin/Makefile.am
+++ b/plugin/Makefile.am
@@ -12,6 +12,7 @@ endif
 
 drumgizmo_la_CXXFLAGS = -DLV2 -DLV2_PLUGIN_URI=\"http://drumgizmo.org/lv2\" \
 	$(LV2_CFLAGS) \
+	$(SNDFILE_CFLAGS) \
 	-I$(top_srcdir)/include \
 	-I$(top_srcdir)/plugin/plugingizmo \
 	-I$(top_srcdir)/plugingui \
@@ -40,6 +41,7 @@ vstplugin_DATA =
 endif
 
 drumgizmo_vst_la_CXXFLAGS = -DVST \
+	$(SNDFILE_CFLAGS) \
 	-I$(top_srcdir)/include \
 	-I$(top_srcdir)/plugin/plugingizmo \
 	-I$(top_srcdir)/plugingui \
@@ -59,9 +61,9 @@ drumgizmo_vst_la_LIBADD = vst/libvstsdk.la \
 	$(top_srcdir)/src/libdg.la
 
 
-install-exec-hook:
-	rm -f $(DESTDIR)$(libdir)/lv2/drumgizmo.lv2/drumgizmo.la
-	rm -f $(DESTDIR)$(libdir)/vst/drumgizmo_vst.la
+install-data-hook:
+	rm -f $(lv2plugindir)/drumgizmo.la
+	rm -f $(vstplugindir)/drumgizmo_vst.la
 
 
 EXTRA_DIST = \
diff --git a/plugin/Makefile.in b/plugin/Makefile.in
index 8ac4ab0..13ae593 100644
--- a/plugin/Makefile.in
+++ b/plugin/Makefile.in
@@ -440,6 +440,7 @@ SUBDIRS = vst
 @ENABLE_LV2_TRUE at lv2plugin_DATA = manifest.ttl drumgizmo.ttl
 drumgizmo_la_CXXFLAGS = -DLV2 -DLV2_PLUGIN_URI=\"http://drumgizmo.org/lv2\" \
 	$(LV2_CFLAGS) \
+	$(SNDFILE_CFLAGS) \
 	-I$(top_srcdir)/include \
 	-I$(top_srcdir)/plugin/plugingizmo \
 	-I$(top_srcdir)/plugingui \
@@ -465,6 +466,7 @@ drumgizmo_la_LIBADD = $(LV2_LIBS) \
 @ENABLE_VST_TRUE at vstplugin_LTLIBRARIES = drumgizmo_vst.la
 @ENABLE_VST_TRUE at vstplugin_DATA = 
 drumgizmo_vst_la_CXXFLAGS = -DVST \
+	$(SNDFILE_CFLAGS) \
 	-I$(top_srcdir)/include \
 	-I$(top_srcdir)/plugin/plugingizmo \
 	-I$(top_srcdir)/plugingui \
@@ -976,14 +978,14 @@ info-am:
 
 install-data-am: install-lv2pluginDATA install-lv2pluginLTLIBRARIES \
 	install-vstpluginDATA install-vstpluginLTLIBRARIES
-
+	@$(NORMAL_INSTALL)
+	$(MAKE) $(AM_MAKEFLAGS) install-data-hook
 install-dvi: install-dvi-recursive
 
 install-dvi-am:
 
 install-exec-am:
-	@$(NORMAL_INSTALL)
-	$(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+
 install-html: install-html-recursive
 
 install-html-am:
@@ -1025,7 +1027,7 @@ ps-am:
 uninstall-am: uninstall-lv2pluginDATA uninstall-lv2pluginLTLIBRARIES \
 	uninstall-vstpluginDATA uninstall-vstpluginLTLIBRARIES
 
-.MAKE: $(am__recursive_targets) install-am install-exec-am \
+.MAKE: $(am__recursive_targets) install-am install-data-am \
 	install-strip
 
 .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
@@ -1034,8 +1036,8 @@ uninstall-am: uninstall-lv2pluginDATA uninstall-lv2pluginLTLIBRARIES \
 	cscopelist-am ctags ctags-am distclean distclean-compile \
 	distclean-generic distclean-libtool distclean-tags distdir dvi \
 	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-dvi install-dvi-am \
-	install-exec install-exec-am install-exec-hook install-html \
+	install-data install-data-am install-data-hook install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
 	install-html-am install-info install-info-am \
 	install-lv2pluginDATA install-lv2pluginLTLIBRARIES install-man \
 	install-pdf install-pdf-am install-ps install-ps-am \
@@ -1049,9 +1051,9 @@ uninstall-am: uninstall-lv2pluginDATA uninstall-lv2pluginLTLIBRARIES \
 	uninstall-vstpluginLTLIBRARIES
 
 
-install-exec-hook:
-	rm -f $(DESTDIR)$(libdir)/lv2/drumgizmo.lv2/drumgizmo.la
-	rm -f $(DESTDIR)$(libdir)/vst/drumgizmo_vst.la
+install-data-hook:
+	rm -f $(lv2plugindir)/drumgizmo.la
+	rm -f $(vstplugindir)/drumgizmo_vst.la
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/plugin/Makefile.mingw32.in b/plugin/Makefile.mingw32.in
index 5f588f9..77f43e1 100644
--- a/plugin/Makefile.mingw32.in
+++ b/plugin/Makefile.mingw32.in
@@ -32,7 +32,6 @@ DG_SRC = \
 	@top_srcdir@/src/memchecker.cc \
 	@top_srcdir@/src/midimapparser.cc \
 	@top_srcdir@/src/midimapper.cc \
-	@top_srcdir@/src/mutex.cc \
 	@top_srcdir@/src/path.cc \
 	@top_srcdir@/src/powerlist.cc \
 	@top_srcdir@/src/random.cc \
@@ -80,6 +79,7 @@ GUI_SRC = \
 	@top_srcdir@/plugingui/pluginconfig.cc \
 	@top_srcdir@/plugingui/powerbutton.cc \
 	@top_srcdir@/plugingui/progressbar.cc \
+	@top_srcdir@/plugingui/resamplingframecontent.cc \
 	@top_srcdir@/plugingui/resource.cc \
 	@top_srcdir@/plugingui/resource_data.cc \
 	@top_srcdir@/plugingui/scrollbar.cc \
@@ -160,7 +160,7 @@ all:
 	(cd @top_srcdir@/plugingui; ./rcgen $(RES) > resource_data.cc)
 	gcc $(DBG_CFLAGS) @top_srcdir@/hugin/hugin.c -c
 	gcc $(DBG_CFLAGS) @top_srcdir@/hugin/hugin_syslog.c -c
-	g++ $(CXXFLAGS) -std=c++11 -static -static-libgcc -O2 -g -Wall $(DBG_CFLAGS) $(DG_CFLAGS) $(DG_LIBS) $(VST_CFLAGS) hugin.o hugin_syslog.o $(DG_SRC) $(VST_SRC) ${SRC} ${GUI_SRC} ${GUI_CPPFLAGS} $(GUI_LIBS) $(EXPAT_CFLAGS) $(SRC_CFLAGS) $(ZITA_CXXFLAGS) $(EXPAT_LIBS) $(SNDFILE_CFLAGS) $(SNDFILE_LIBS) $(SRC_LIBS) $(ZITA_LIBS) -shared -o drumgizmo_vst.dll -Wl,--out-implib,libdrumgizmo_vst.a
+	g++ $(CXXFLAGS) -std=c++11 -static -static-libgcc -O2 -g -Wall $(DBG_CFLAGS) $(DG_CFLAGS) $(DG_LIBS) $(VST_CFLAGS) hugin.o hugin_syslog.o $(DG_SRC) $(VST_SRC) ${SRC} ${GUI_SRC} ${GUI_CPPFLAGS} $(GUI_LIBS) $(EXPAT_CFLAGS) $(SRC_CFLAGS) $(ZITA_CXXFLAGS) $(EXPAT_LIBS) $(SNDFILE_CFLAGS) $(SNDFILE_LIBS) $(SRC_LIBS) $(ZITA_LIBS) -latomic -shared -o drumgizmo_vst.dll -Wl,--out-implib,libdrumgizmo_vst.a
 
 clean:
 	del -f drumgizmo_vst.dll libdrumgizmo_vst.a
diff --git a/plugin/drumgizmo_plugin.cc b/plugin/drumgizmo_plugin.cc
index b1ad17c..168eb58 100644
--- a/plugin/drumgizmo_plugin.cc
+++ b/plugin/drumgizmo_plugin.cc
@@ -259,11 +259,13 @@ bool DrumGizmoPlugin::hasGUI()
 	return true;
 }
 
-void DrumGizmoPlugin::createWindow(void *parent)
+void* DrumGizmoPlugin::createWindow(void *parent)
 {
 	plugin_gui = std::make_shared<GUI::MainWindow>(settings, parent);
 	resizeWindow(width, height);
 	onShowWindow();
+
+	return plugin_gui->getNativeWindowHandle();
 }
 
 void DrumGizmoPlugin::onDestroyWindow()
@@ -517,6 +519,8 @@ std::string DrumGizmoPlugin::ConfigStringIO::get()
 		bool2str(settings.enable_velocity_randomiser.load()) + "</value>\n"
 		"  <value name=\"velocity_randomiser_weight\">" +
 		float2str(settings.velocity_randomiser_weight.load()) + "</value>\n"
+		"  <value name=\"enable_resampling\">" +
+		bool2str(settings.enable_resampling.load()) + "</value>\n"
 		"  <value name=\"disk_cache_upper_limit\">" +
 		int2str(settings.disk_cache_upper_limit.load()) + "</value>\n"
 		"  <value name=\"disk_cache_chunk_size\">" +
diff --git a/plugin/drumgizmo_plugin.h b/plugin/drumgizmo_plugin.h
index 7734051..98c6c26 100644
--- a/plugin/drumgizmo_plugin.h
+++ b/plugin/drumgizmo_plugin.h
@@ -100,7 +100,7 @@ public:
 	// GUI
 	//
 	bool hasGUI() override;
-	void createWindow(void *parent) override;
+	void* createWindow(void *parent) override;
 	void onDestroyWindow() override;
 	void onShowWindow() override;
 	void onHideWindow() override;
diff --git a/plugin/plugingizmo/plugin.h b/plugin/plugingizmo/plugin.h
index b7f683f..f541255 100644
--- a/plugin/plugingizmo/plugin.h
+++ b/plugin/plugingizmo/plugin.h
@@ -177,7 +177,7 @@ public:
 	}
 
 	//! Create new window.
-	virtual void createWindow(void *parent) {}
+	virtual void* createWindow(void *parent) { return nullptr; }
 
 	//! Destroy window.
 	virtual void onDestroyWindow() {}
diff --git a/plugin/plugingizmo/pluginlv2.cc b/plugin/plugingizmo/pluginlv2.cc
index 0d9a50b..515d434 100644
--- a/plugin/plugingizmo/pluginlv2.cc
+++ b/plugin/plugingizmo/pluginlv2.cc
@@ -542,7 +542,7 @@ LV2UI_Handle PluginLV2::uiInstantiate(const struct _LV2UI_Descriptor*descriptor,
 
 	plugin_lv2->resize = resize;
 
-	plugin_lv2->createWindow(parent);
+	*widget = plugin_lv2->createWindow(parent);
 
 	return plugin_lv2;
 }
diff --git a/plugin/plugingizmo/pluginlv2.h b/plugin/plugingizmo/pluginlv2.h
index 1677fbf..86a661e 100644
--- a/plugin/plugingizmo/pluginlv2.h
+++ b/plugin/plugingizmo/pluginlv2.h
@@ -161,7 +161,7 @@ public:
 	}
 
 	//! Create new window.
-	virtual void createWindow(void *parent) override {}
+	virtual void* createWindow(void *parent) override { return nullptr; }
 
 	//! Destroy window.
 	virtual void onDestroyWindow() override {}
diff --git a/plugin/plugingizmo/pluginvst.h b/plugin/plugingizmo/pluginvst.h
index ca140d1..63bdefe 100644
--- a/plugin/plugingizmo/pluginvst.h
+++ b/plugin/plugingizmo/pluginvst.h
@@ -153,7 +153,7 @@ public:
 	}
 
 	//! Create new window.
-	virtual void createWindow(void *parent) override {}
+	virtual void* createWindow(void *parent) override { return nullptr; }
 
 	//! Destroy window.
 	virtual void onDestroyWindow() override {}
diff --git a/plugingui/Makefile.am b/plugingui/Makefile.am
index a7ee485..dd36783 100644
--- a/plugingui/Makefile.am
+++ b/plugingui/Makefile.am
@@ -79,6 +79,7 @@ nodist_libdggui_la_SOURCES = \
 	pluginconfig.cc \
 	powerbutton.cc \
 	progressbar.cc \
+	resamplingframecontent.cc \
 	resource.cc \
 	resource_data.cc \
 	scrollbar.cc \
@@ -175,6 +176,7 @@ EXTRA_DIST = \
 	pluginconfig.h \
 	powerbutton.h \
 	progressbar.h \
+	resamplingframecontent.h \
 	resource.h \
 	resource_data.h \
 	scrollbar.h \
diff --git a/plugingui/Makefile.in b/plugingui/Makefile.in
index 5ac6007..bfa45d9 100644
--- a/plugingui/Makefile.in
+++ b/plugingui/Makefile.in
@@ -125,16 +125,16 @@ nodist_libdggui_la_OBJECTS = libdggui_la-abouttab.lo \
 	libdggui_la-mainwindow.lo libdggui_la-painter.lo \
 	libdggui_la-pixelbuffer.lo libdggui_la-pluginconfig.lo \
 	libdggui_la-powerbutton.lo libdggui_la-progressbar.lo \
-	libdggui_la-resource.lo libdggui_la-resource_data.lo \
-	libdggui_la-scrollbar.lo libdggui_la-slider.lo \
-	libdggui_la-stackedwidget.lo libdggui_la-statusframecontent.lo \
-	libdggui_la-tabbutton.lo libdggui_la-tabwidget.lo \
-	libdggui_la-textedit.lo libdggui_la-texture.lo \
-	libdggui_la-texturedbox.lo libdggui_la-toggle.lo \
-	libdggui_la-utf8.lo libdggui_la-verticalline.lo \
-	libdggui_la-widget.lo libdggui_la-window.lo \
-	libdggui_la-lodepng.lo $(am__objects_1) $(am__objects_2) \
-	$(am__objects_3)
+	libdggui_la-resamplingframecontent.lo libdggui_la-resource.lo \
+	libdggui_la-resource_data.lo libdggui_la-scrollbar.lo \
+	libdggui_la-slider.lo libdggui_la-stackedwidget.lo \
+	libdggui_la-statusframecontent.lo libdggui_la-tabbutton.lo \
+	libdggui_la-tabwidget.lo libdggui_la-textedit.lo \
+	libdggui_la-texture.lo libdggui_la-texturedbox.lo \
+	libdggui_la-toggle.lo libdggui_la-utf8.lo \
+	libdggui_la-verticalline.lo libdggui_la-widget.lo \
+	libdggui_la-window.lo libdggui_la-lodepng.lo $(am__objects_1) \
+	$(am__objects_2) $(am__objects_3)
 libdggui_la_OBJECTS = $(nodist_libdggui_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
@@ -446,12 +446,12 @@ nodist_libdggui_la_SOURCES = abouttab.cc button.cc button_base.cc \
 	label.cc layout.cc led.cc lineedit.cc listbox.cc \
 	listboxbasic.cc listboxthin.cc maintab.cc mainwindow.cc \
 	painter.cc pixelbuffer.cc pluginconfig.cc powerbutton.cc \
-	progressbar.cc resource.cc resource_data.cc scrollbar.cc \
-	slider.cc stackedwidget.cc statusframecontent.cc tabbutton.cc \
-	tabwidget.cc textedit.cc texture.cc texturedbox.cc toggle.cc \
-	utf8.cc verticalline.cc widget.cc window.cc \
-	lodepng/lodepng.cpp $(am__append_1) $(am__append_2) \
-	$(am__append_3)
+	progressbar.cc resamplingframecontent.cc resource.cc \
+	resource_data.cc scrollbar.cc slider.cc stackedwidget.cc \
+	statusframecontent.cc tabbutton.cc tabwidget.cc textedit.cc \
+	texture.cc texturedbox.cc toggle.cc utf8.cc verticalline.cc \
+	widget.cc window.cc lodepng/lodepng.cpp $(am__append_1) \
+	$(am__append_2) $(am__append_3)
 
 #if ENABLE_COCOA
 #nodist_libdggui_la_SOURCES += \
@@ -511,6 +511,7 @@ EXTRA_DIST = \
 	pluginconfig.h \
 	powerbutton.h \
 	progressbar.h \
+	resamplingframecontent.h \
 	resource.h \
 	resource_data.h \
 	scrollbar.h \
@@ -638,6 +639,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdggui_la-powerbutton.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdggui_la-progressbar.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdggui_la-pugl_x11.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdggui_la-resamplingframecontent.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdggui_la-resource.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdggui_la-resource_data.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdggui_la-scrollbar.Plo at am__quote@
@@ -945,6 +947,13 @@ libdggui_la-progressbar.lo: progressbar.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdggui_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdggui_la-progressbar.lo `test -f 'progressbar.cc' || echo '$(srcdir)/'`progressbar.cc
 
+libdggui_la-resamplingframecontent.lo: resamplingframecontent.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdggui_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdggui_la-resamplingframecontent.lo -MD -MP -MF $(DEPDIR)/libdggui_la-resamplingframecontent.Tpo -c -o libdggui_la-resamplingframecontent.lo `test -f 'resamplingframecontent.cc' || echo '$(srcdir)/'`resamplingframecontent.cc
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libdggui_la-resamplingframecontent.Tpo $(DEPDIR)/libdggui_la-resamplingframecontent.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='resamplingframecontent.cc' object='libdggui_la-resamplingframecontent.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdggui_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdggui_la-resamplingframecontent.lo `test -f 'resamplingframecontent.cc' || echo '$(srcdir)/'`resamplingframecontent.cc
+
 libdggui_la-resource.lo: resource.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdggui_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdggui_la-resource.lo -MD -MP -MF $(DEPDIR)/libdggui_la-resource.Tpo -c -o libdggui_la-resource.lo `test -f 'resource.cc' || echo '$(srcdir)/'`resource.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libdggui_la-resource.Tpo $(DEPDIR)/libdggui_la-resource.Plo
diff --git a/plugingui/directory.cc b/plugingui/directory.cc
index 96ed5b7..083c8e4 100644
--- a/plugingui/directory.cc
+++ b/plugingui/directory.cc
@@ -32,6 +32,7 @@
 #include <algorithm>
 #include <vector>
 #include <string.h>
+#include <unistd.h>
 
 #include <platform.h>
 
@@ -51,7 +52,8 @@
 #define SEP "/"
 #endif
 
-namespace GUI {
+namespace GUI
+{
 
 Directory::Directory(std::string path)
 {
diff --git a/plugingui/directory.h b/plugingui/directory.h
index 1acc0bf..100204a 100644
--- a/plugingui/directory.h
+++ b/plugingui/directory.h
@@ -33,7 +33,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
 
 #define DIRECTORY_HIDDEN 1
 
diff --git a/plugingui/drumkitframecontent.cc b/plugingui/drumkitframecontent.cc
index 3752cc3..f90f346 100644
--- a/plugingui/drumkitframecontent.cc
+++ b/plugingui/drumkitframecontent.cc
@@ -147,7 +147,7 @@ void DrumkitframeContent::resize(std::size_t width, std::size_t height)
 
 void DrumkitframeContent::kitBrowseClick()
 {
-	std::string path = drumkit_file.getLineEdit().text();
+	std::string path = drumkit_file.getLineEdit().getText();
 	if(path == "")
 	{
 		path = config.lastkit;
@@ -155,7 +155,7 @@ void DrumkitframeContent::kitBrowseClick()
 
 	if(path == "")
 	{
-		path = midimap_file.getLineEdit().text();
+		path = midimap_file.getLineEdit().getText();
 	}
 
 	file_browser.setPath(path);
@@ -166,7 +166,7 @@ void DrumkitframeContent::kitBrowseClick()
 
 void DrumkitframeContent::midimapBrowseClick()
 {
-	std::string path = midimap_file.getLineEdit().text();
+	std::string path = midimap_file.getLineEdit().getText();
 	if(path == "")
 	{
 		path = config.lastmidimap;
@@ -174,7 +174,7 @@ void DrumkitframeContent::midimapBrowseClick()
 
 	if(path == "")
 	{
-		path = drumkit_file.getLineEdit().text();
+		path = drumkit_file.getLineEdit().getText();
 	}
 
 	file_browser.setPath(path);
diff --git a/plugingui/eventhandler.cc b/plugingui/eventhandler.cc
index 4200d49..696b242 100644
--- a/plugingui/eventhandler.cc
+++ b/plugingui/eventhandler.cc
@@ -88,7 +88,6 @@ void EventHandler::processEvents()
 
 		switch(event->type()) {
 		case EventType::repaint:
-			window.redraw();
 			break;
 
 		case EventType::move:
diff --git a/plugingui/filebrowser.cc b/plugingui/filebrowser.cc
index 76a2744..8854f6e 100644
--- a/plugingui/filebrowser.cc
+++ b/plugingui/filebrowser.cc
@@ -37,7 +37,6 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
 
 #include <platform.h>
 #include <hugin.hpp>
@@ -158,7 +157,7 @@ void FileBrowser::handleKeyEvent()
 {
 	listbox.clearSelectedValue();
 
-	std::string value = lineedit.text();
+	std::string value = lineedit.getText();
 	if((value.size() > 1) && (value[0] == '@'))
 	{
 		DEBUG(filebrowser, "Selecting ref-file '%s'\n", value.c_str());
@@ -166,7 +165,7 @@ void FileBrowser::handleKeyEvent()
 		return;
 	}
 
-	dir.setPath(lineedit.text());
+	dir.setPath(lineedit.getText());
 	changeDir();
 }
 
diff --git a/plugingui/lineedit.cc b/plugingui/lineedit.cc
index d2e9dea..96bf56f 100644
--- a/plugingui/lineedit.cc
+++ b/plugingui/lineedit.cc
@@ -65,7 +65,7 @@ void LineEdit::setText(const std::string& text)
 	textChanged();
 }
 
-std::string LineEdit::text()
+std::string LineEdit::getText()
 {
 	return _text;
 }
diff --git a/plugingui/lineedit.h b/plugingui/lineedit.h
index dd37776..86ad986 100644
--- a/plugingui/lineedit.h
+++ b/plugingui/lineedit.h
@@ -45,7 +45,7 @@ public:
 
 	bool isFocusable() override { return true; }
 
-	std::string text();
+	std::string getText();
 	void setText(const std::string& text);
 
 	void setReadOnly(bool readonly);
diff --git a/plugingui/maintab.cc b/plugingui/maintab.cc
index 73bae48..aeb34b6 100644
--- a/plugingui/maintab.cc
+++ b/plugingui/maintab.cc
@@ -38,6 +38,7 @@ MainTab::MainTab(Widget* parent,
 	, statusframe_content{this, settings_notifier}
 	, humanizerframe_content{this, settings, settings_notifier}
 	, diskstreamingframe_content{this, settings, settings_notifier}
+	, resamplingframe_content{this, settings_notifier}
 	, settings(settings)
 	, settings_notifier(settings_notifier)
 {
@@ -48,36 +49,47 @@ MainTab::MainTab(Widget* parent,
 	layout.addItem(&status_frame);
 	layout.addItem(&humanizer_frame);
 	layout.addItem(&diskstreaming_frame);
+	layout.addItem(&resampling_frame);
 
 	auto h1 = 20;
 	auto h2 = 22;
 	auto h3 = 13;
 	auto h4 = 11;
+	auto h5 = 14;
 	auto drumkit_range = GridLayout::GridRange{0, 1, 0, h1};
 	auto status_range = GridLayout::GridRange{0, 1, h1, h1 + h2};
 	auto humanizer_range = GridLayout::GridRange{1, 2, 0, h3};
 	auto diskstreaming_range = GridLayout::GridRange{1, 2, h3, h3 + h4};
+	auto resampling_range = GridLayout::GridRange{1, 2, h3 + h4, h3 + h4 + h5};
 	layout.setPosition(&drumkit_frame, drumkit_range);
 	layout.setPosition(&status_frame, status_range);
 	layout.setPosition(&humanizer_frame, humanizer_range);
 	layout.setPosition(&diskstreaming_frame, diskstreaming_range);
+	layout.setPosition(&resampling_frame, resampling_range);
 
 	drumkit_frame.setTitle("Drumkit");
 	status_frame.setTitle("Status");
 	humanizer_frame.setTitle("Humanizer");
 	diskstreaming_frame.setTitle("Disk streaming");
+	resampling_frame.setTitle("Resampling");
 
 	drumkit_frame.setContent(&drumkitframe_content);
 	status_frame.setContent(&statusframe_content);
 	humanizer_frame.setContent(&humanizerframe_content);
 	diskstreaming_frame.setContent(&diskstreamingframe_content);
+	resampling_frame.setContent(&resamplingframe_content);
 
 	humanizer_frame.setOnSwitch(settings.enable_velocity_modifier);
+	resampling_frame.setOnSwitch(settings.enable_resampling);
 
 	CONNECT(this, settings_notifier.enable_velocity_modifier,
 	        &humanizer_frame, &FrameWidget::setOnSwitch);
+	CONNECT(this, settings_notifier.enable_resampling,
+	        &resampling_frame, &FrameWidget::setOnSwitch);
 	CONNECT(&humanizer_frame, onSwitchChangeNotifier,
 	        this, &MainTab::humanizerOnChange);
+	CONNECT(&resampling_frame, onSwitchChangeNotifier,
+	        this, &MainTab::resamplingOnChange);
 }
 
 void MainTab::resize(std::size_t width, std::size_t height)
@@ -86,6 +98,7 @@ void MainTab::resize(std::size_t width, std::size_t height)
 
 	// DrumGizmo logo
 	Painter painter(*this);
+	painter.clear();
 	painter.drawImage(width - logo.width(), height - logo.height(), logo);
 }
 
@@ -94,4 +107,9 @@ void MainTab::humanizerOnChange(bool on)
 	settings.enable_velocity_modifier.store(on);
 }
 
+void MainTab::resamplingOnChange(bool on)
+{
+	settings.enable_resampling.store(on);
+}
+
 } // GUI::
diff --git a/plugingui/maintab.h b/plugingui/maintab.h
index 62b3f82..ab7e760 100644
--- a/plugingui/maintab.h
+++ b/plugingui/maintab.h
@@ -33,6 +33,7 @@
 #include "statusframecontent.h"
 #include "humanizerframecontent.h"
 #include "diskstreamingframecontent.h"
+#include "resamplingframecontent.h"
 
 struct Settings;
 class SettingsNotifier;
@@ -55,6 +56,7 @@ public:
 
 private:
 	void humanizerOnChange(bool on);
+	void resamplingOnChange(bool on);
 
 	Image logo{":resources/logo.png"};
 
@@ -64,11 +66,13 @@ private:
 	FrameWidget status_frame{this, false};
 	FrameWidget humanizer_frame{this, true};
 	FrameWidget diskstreaming_frame{this, false};
+	FrameWidget resampling_frame{this, true};
 
 	DrumkitframeContent drumkitframe_content;
 	StatusframeContent statusframe_content;
 	HumanizerframeContent humanizerframe_content;
 	DiskstreamingframeContent diskstreamingframe_content;
+	ResamplingframeContent resamplingframe_content;
 
 	Settings& settings;
 	SettingsNotifier& settings_notifier;
diff --git a/plugingui/nativewindow_x11.cc b/plugingui/nativewindow_x11.cc
index ae8ad2c..bc9091d 100644
--- a/plugingui/nativewindow_x11.cc
+++ b/plugingui/nativewindow_x11.cc
@@ -316,6 +316,13 @@ void NativeWindowX11::translateXMessage(XEvent& xevent)
 			repaintEvent->width = xevent.xexpose.width;
 			repaintEvent->height = xevent.xexpose.height;
 			event_queue.push_back(repaintEvent);
+
+			if(image)
+			{
+				// Redraw the entire window.
+				Rect rect{0, 0, window.wpixbuf.width, window.wpixbuf.height};
+				redraw(rect);
+			}
 		}
 		break;
 
diff --git a/plugingui/resamplingframecontent.cc b/plugingui/resamplingframecontent.cc
new file mode 100644
index 0000000..92102e3
--- /dev/null
+++ b/plugingui/resamplingframecontent.cc
@@ -0,0 +1,91 @@
+/* -*- Mode: c++ -*- */
+/***************************************************************************
+ *            resamplingframecontent.cc
+ *
+ *  Fri May  5 23:43:28 CEST 2017
+ *  Copyright 2017 André Nusser
+ *  andre.nusser at googlemail.com
+ ****************************************************************************/
+
+/*
+ *  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 "resamplingframecontent.h"
+
+#include <settings.h>
+
+namespace GUI
+{
+
+ResamplingframeContent::ResamplingframeContent(
+    Widget* parent, SettingsNotifier& settings_notifier)
+    : Widget(parent)
+	, settings_notifier(settings_notifier)
+{
+	CONNECT(this, settings_notifier.drumkit_samplerate,
+	        this, &ResamplingframeContent::updateDrumkitSamplerate);
+	CONNECT(this, settings_notifier.samplerate,
+	        this, &ResamplingframeContent::updateSessionSamplerate);
+	CONNECT(this, settings_notifier.resamplig_recommended,
+	        this, &ResamplingframeContent::updateResamplingRecommended);
+
+	text_field.move(0, 0);
+	text_field.setReadOnly(true);
+
+	updateContent();
+	text_field.show();
+}
+
+void ResamplingframeContent::resize(std::size_t width, std::size_t height)
+{
+	Widget::resize(width, height);
+	text_field.resize(width, height);
+}
+
+void ResamplingframeContent::updateContent()
+{
+	text_field.setText(
+		"Session samplerate:   " + session_samplerate + "\n"
+		"Drumkit samplerate:   " + drumkit_samplerate + "\n"
+		"Resampling recommended:   " + resamplig_recommended + "\n"
+	);
+}
+
+void ResamplingframeContent::updateDrumkitSamplerate(std::size_t drumkit_samplerate)
+{
+	this->drumkit_samplerate = drumkit_samplerate == 0
+		? ""
+		: std::to_string(drumkit_samplerate);
+
+	updateContent();
+}
+
+void ResamplingframeContent::updateSessionSamplerate(double samplerate)
+{
+	this->session_samplerate = std::to_string((std::size_t)samplerate);
+
+	updateContent();
+}
+
+void ResamplingframeContent::updateResamplingRecommended(bool resamplig_recommended)
+{
+	this->resamplig_recommended = resamplig_recommended ? "Yes" : "No";
+
+	updateContent();
+}
+
+} // GUI::
diff --git a/plugingui/abouttab.h b/plugingui/resamplingframecontent.h
similarity index 63%
copy from plugingui/abouttab.h
copy to plugingui/resamplingframecontent.h
index 556b5bb..b45f1ee 100644
--- a/plugingui/abouttab.h
+++ b/plugingui/resamplingframecontent.h
@@ -1,8 +1,8 @@
 /* -*- Mode: c++ -*- */
 /***************************************************************************
- *            abouttab.h
+ *            resamplingframecontent.h
  *
- *  Fri Apr 21 18:51:13 CEST 2017
+ *  Fri May  5 23:43:28 CEST 2017
  *  Copyright 2017 André Nusser
  *  andre.nusser at googlemail.com
  ****************************************************************************/
@@ -27,32 +27,36 @@
 #pragma once
 
 #include "widget.h"
-#include "resource.h"
 #include "textedit.h"
 
-#include <string>
+class SettingsNotifier;
 
 namespace GUI
 {
 
-class AboutTab
+class ResamplingframeContent
 	: public Widget
 {
 public:
-	AboutTab(Widget* parent);
+	ResamplingframeContent(Widget* parent, SettingsNotifier& settings_notifier);
 
-	// From Widget:
-	void resize(std::size_t width, std::size_t height) override;
+	// From Widget
+	virtual void resize(std::size_t width, std::size_t height) override;
+
+	void updateContent();
+
+	void updateDrumkitSamplerate(std::size_t drumkit_samplerate);
+	void updateSessionSamplerate(double samplerate);
+	void updateResamplingRecommended(bool resamplig_recommended);
 
 private:
-	std::string getAboutText();
+	TextEdit text_field{this};
 
-	TextEdit text_edit{this};
-	std::size_t margin{10};
+	SettingsNotifier& settings_notifier;
 
-	Resource about{":../ABOUT"};
-	Resource authors{":../AUTHORS"};
-	Resource gpl{":../COPYING"};
+	std::string drumkit_samplerate;
+	std::string session_samplerate;
+	std::string resamplig_recommended;
 };
 
 } // GUI::
diff --git a/plugingui/stackedwidget.cc b/plugingui/stackedwidget.cc
index 069e80b..05f8f3c 100644
--- a/plugingui/stackedwidget.cc
+++ b/plugingui/stackedwidget.cc
@@ -93,6 +93,51 @@ void StackedWidget::setCurrentWidget(Widget *widget)
 	currentChanged(currentWidget);
 }
 
+Widget* StackedWidget::getWidgetAfter(Widget* widget)
+{
+	bool found_it{false};
+
+	for(auto w : widgets)
+	{
+		if(found_it)
+		{
+			return w;
+		}
+
+		if(w == widget)
+		{
+			found_it = true;
+		}
+	}
+
+	if(found_it)
+	{
+		// widget was the last in the list.
+		return nullptr;
+	}
+
+	// The Widget pointed to by 'widget' was not in the list...
+	return nullptr;
+}
+
+Widget* StackedWidget::getWidgetBefore(Widget* widget)
+{
+	Widget* last{nullptr};
+
+	for(auto w : widgets)
+	{
+		if(w == widget)
+		{
+			return last;
+		}
+
+		last = w;
+	}
+
+	// The Widget pointed to by 'widget' was not in the list...
+	return nullptr;
+}
+
 void StackedWidget::sizeChanged(int width, int height)
 {
 	// Propagate size change to child:
diff --git a/plugingui/stackedwidget.h b/plugingui/stackedwidget.h
index 13d764b..24213f7 100644
--- a/plugingui/stackedwidget.h
+++ b/plugingui/stackedwidget.h
@@ -42,21 +42,29 @@ class StackedWidget
 	: public Widget
 {
 public:
-	StackedWidget(Widget *parent);
+	StackedWidget(Widget* parent);
 	~StackedWidget();
 
 	//! Add a widget to the stack.
-	void addWidget(Widget *widget);
+	void addWidget(Widget* widget);
 
 	//! Remove a widget from the stack.
-	void removeWidget(Widget *widget);
+	void removeWidget(Widget* widget);
 
 	//! Get currently visible widget.
-	Widget *getCurrentWidget() const;
+	Widget* getCurrentWidget() const;
 
 	//! Show widget. Hide all the others.
 	//! If widget is not in the stack nothing happens.
-	void setCurrentWidget(Widget *widget);
+	void setCurrentWidget(Widget* widget);
+
+	//! Returns a pointer to the Widget after the one referenced by 'widget' or
+	//! nullptr if 'widget' is the last in the list.
+	Widget* getWidgetAfter(Widget* widget);
+
+	//! Returns a pointer to the Widget beforer the one referenced by 'widget' or
+	//! nullptr if 'widget' is the first in the list.
+	Widget* getWidgetBefore(Widget* widget);
 
 	//! Reports whn a new widget is shown.
 	Notifier<Widget*> currentChanged;
diff --git a/plugingui/statusframecontent.cc b/plugingui/statusframecontent.cc
index 731c7b7..34903e8 100644
--- a/plugingui/statusframecontent.cc
+++ b/plugingui/statusframecontent.cc
@@ -41,16 +41,10 @@ StatusframeContent::StatusframeContent(
 	        this, &StatusframeContent::updateDrumkitDescription);
 	CONNECT(this, settings_notifier.drumkit_version,
 	        this, &StatusframeContent::updateDrumkitVersion);
-	CONNECT(this, settings_notifier.drumkit_samplerate,
-	        this, &StatusframeContent::updateDrumkitSamplerate);
 	CONNECT(this, settings_notifier.midimap_load_status,
 	        this, &StatusframeContent::updateMidimapLoadStatus);
-	CONNECT(this, settings_notifier.samplerate,
-	        this, &StatusframeContent::updateSamplerate);
-	CONNECT(this, settings_notifier.enable_resampling,
-	        this, &StatusframeContent::updateResamplingEnabled);
-	CONNECT(this, settings_notifier.resampling_active,
-	        this, &StatusframeContent::updateResamplingActive);
+	CONNECT(this, settings_notifier.buffer_size,
+	        this, &StatusframeContent::updateBufferSize);
 	CONNECT(this, settings_notifier.number_of_underruns,
 	        this, &StatusframeContent::updateNumberOfUnderruns);
 
@@ -75,11 +69,8 @@ void StatusframeContent::updateContent()
 		"Drumkit name:   " + drumkit_name + "\n"
 		"Drumkit description:   " + drumkit_description + "\n"
 		// "Drumkit version:   " + drumkit_version + "\n"
-		"Drumkit samplerate:   " + drumkit_samplerate + "\n"
-		"Session samplerate:   " + samplerate + "\n"
-		// "Resampling enabled: " + resampling_enabled + "\n"
-		"Resampling active:   " + resampling_active + "\n"
-		// "Number of underruns: " + number_of_underruns + "\n"
+		"Session buffer size:   " + buffer_size + "\n"
+		"Number of underruns: " + number_of_underruns + "\n"
 	);
 }
 
@@ -125,15 +116,6 @@ void StatusframeContent::updateDrumkitVersion(std::string const& drumkit_version
 	updateContent();
 }
 
-void StatusframeContent::updateDrumkitSamplerate(std::size_t drumkit_samplerate)
-{
-	this->drumkit_samplerate = drumkit_samplerate == 0
-		? ""
-		: std::to_string(drumkit_samplerate);
-
-	updateContent();
-}
-
 void StatusframeContent::updateMidimapLoadStatus(LoadStatus load_status)
 {
 	switch(load_status)
@@ -155,29 +137,14 @@ void StatusframeContent::updateMidimapLoadStatus(LoadStatus load_status)
 	updateContent();
 }
 
-void StatusframeContent::updateSamplerate(double samplerate)
-{
-	this->samplerate = std::to_string((std::size_t)samplerate);
-
-	updateContent();
-}
-
-void StatusframeContent::updateResamplingEnabled(bool enable_resampling)
-{
-	this->resampling_enabled = enable_resampling ? "Yes" : "No";
-
-	updateContent();
-}
-
-void StatusframeContent::updateResamplingActive(bool resampling_active)
+void StatusframeContent::updateBufferSize(std::size_t buffer_size)
 {
-	this->resampling_active = resampling_active ? "Yes" : "No";
+	this->buffer_size = std::to_string(buffer_size);
 
 	updateContent();
 }
 
-void StatusframeContent::updateNumberOfUnderruns(
-    std::size_t number_of_underruns)
+void StatusframeContent::updateNumberOfUnderruns(std::size_t number_of_underruns)
 {
 	this->number_of_underruns = std::to_string(number_of_underruns);
 
diff --git a/plugingui/statusframecontent.h b/plugingui/statusframecontent.h
index 20fbfd9..4ca4f63 100644
--- a/plugingui/statusframecontent.h
+++ b/plugingui/statusframecontent.h
@@ -49,11 +49,8 @@ public:
 	void updateDrumkitName(std::string const& drumkit_name);
 	void updateDrumkitDescription(std::string const& drumkit_description);
 	void updateDrumkitVersion(std::string const& drumkit_version);
-	void updateDrumkitSamplerate(std::size_t drumkit_samplerate);
 	void updateMidimapLoadStatus(LoadStatus load_status);
-	void updateSamplerate(double samplerate);
-	void updateResamplingEnabled(bool enable_resampling);
-	void updateResamplingActive(bool resampling_active);
+	void updateBufferSize(std::size_t buffer_size);
 	void updateNumberOfUnderruns(std::size_t number_of_underruns);
 
 private:
@@ -65,11 +62,8 @@ private:
 	std::string drumkit_name;
 	std::string drumkit_description;
 	std::string drumkit_version;
-	std::string drumkit_samplerate;
 	std::string midimap_load_status;
-	std::string samplerate;
-	std::string resampling_enabled;
-	std::string resampling_active;
+	std::string buffer_size;
 	std::string number_of_underruns;
 };
 
diff --git a/plugingui/tabbutton.cc b/plugingui/tabbutton.cc
index f46daa4..845dedb 100644
--- a/plugingui/tabbutton.cc
+++ b/plugingui/tabbutton.cc
@@ -106,6 +106,11 @@ void TabButton::repaintEvent(RepaintEvent* e)
 	p.drawText(x, y, font, text, true);
 }
 
+void TabButton::scrollEvent(ScrollEvent* scroll_event)
+{
+	scrollNotifier(scroll_event->delta);
+}
+
 void TabButton::clickHandler()
 {
 	switchTabNotifier(tab_widget);
diff --git a/plugingui/tabbutton.h b/plugingui/tabbutton.h
index 1c4d84b..29e6e05 100644
--- a/plugingui/tabbutton.h
+++ b/plugingui/tabbutton.h
@@ -35,6 +35,8 @@
 namespace GUI
 {
 
+class ScrollEvent;
+
 class TabButton
 	: public ButtonBase
 {
@@ -48,10 +50,12 @@ public:
 	void setActive(bool active);
 
 	Notifier<Widget*> switchTabNotifier;
+	Notifier<float> scrollNotifier; // float delta
 
 protected:
 	// From Widget:
 	virtual void repaintEvent(RepaintEvent* e) override;
+	virtual void scrollEvent(ScrollEvent* scroll_event) override;
 
 private:
 	void clickHandler();
diff --git a/plugingui/tabwidget.cc b/plugingui/tabwidget.cc
index 06e7425..dde2137 100644
--- a/plugingui/tabwidget.cc
+++ b/plugingui/tabwidget.cc
@@ -46,6 +46,7 @@ void TabWidget::addTab(const std::string& title, Widget* widget)
 	button.setText(title);
 	stack.addWidget(widget);
 	CONNECT(&button, switchTabNotifier, this, &TabWidget::switchTab);
+	CONNECT(&button, scrollNotifier, this, &TabWidget::rotateTab);
 	sizeChanged(width(), height());
 }
 
@@ -54,6 +55,24 @@ std::size_t TabWidget::getBarHeight() const
 	return topbar.height();
 }
 
+void TabWidget::rotateTab(float delta)
+{
+	Widget* widget{nullptr};
+	if(delta > 0.0f)
+	{
+		widget = stack.getWidgetAfter(stack.getCurrentWidget());
+	}
+	else
+	{
+		widget = stack.getWidgetBefore(stack.getCurrentWidget());
+	}
+
+	if(widget)
+	{
+		switchTab(widget);
+	}
+}
+
 void TabWidget::switchTab(Widget* tabWidget)
 {
 	stack.setCurrentWidget(tabWidget);
diff --git a/plugingui/tabwidget.h b/plugingui/tabwidget.h
index ca96dc2..3f0e041 100644
--- a/plugingui/tabwidget.h
+++ b/plugingui/tabwidget.h
@@ -52,6 +52,8 @@ private:
 	void sizeChanged(int width, int height);
 
 private:
+	//! Switch to the next tab if delta is > 0 or previous tab if delta is <= 0.
+	void rotateTab(float delta);
 	void switchTab(Widget* tabWidget);
 	void setActiveButtons(Widget* current_widget);
 
diff --git a/plugingui/testmain.cc b/plugingui/testmain.cc
index d6c3220..5231205 100644
--- a/plugingui/testmain.cc
+++ b/plugingui/testmain.cc
@@ -24,13 +24,8 @@
  *  along with DrumGizmo; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
-#include <platform.h>
-
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-#include <unistd.h>
+#include <chrono>
+#include <thread>
 
 #include <hugin.hpp>
 #include <settings.h>
@@ -63,11 +58,7 @@ int main()
 			break;
 		}
 
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-		SleepEx(50, FALSE);
-#else
-		usleep(50000);
-#endif
+		std::this_thread::sleep_for(std::chrono::milliseconds(50));
 	}
 
 	return 0;
diff --git a/plugingui/textedit.cc b/plugingui/textedit.cc
index 4de6e52..ebe8d32 100644
--- a/plugingui/textedit.cc
+++ b/plugingui/textedit.cc
@@ -26,14 +26,7 @@
  */
 #include "textedit.h"
 
-#include "window.h"
-
-#include <assert.h>
-#include <hugin.hpp>
-#include <list>
-#include <stdio.h>
-
-#define BORDER 10
+#include "painter.h"
 
 namespace GUI
 {
@@ -42,7 +35,7 @@ TextEdit::TextEdit(Widget* parent) : Widget(parent), scroll(this)
 {
 	setReadOnly(true);
 
-	scroll.move(width() - 23, 1);
+	scroll.move(width() - 2*x_border - 3, y_border - 1);
 	scroll.resize(16, 100);
 	CONNECT(&scroll, valueChangeNotifier, this, &TextEdit::scrolled);
 }
@@ -56,8 +49,8 @@ void TextEdit::resize(std::size_t width, std::size_t height)
 	Widget::resize(width, height);
 
 	needs_preprocessing = true;
-	scroll.resize(scroll.width(), height - 14);
-	scroll.move(width - 23, 7);
+	scroll.move(width - 2*x_border - 3, y_border - 1);
+	scroll.resize(scroll.width(), height - 2*(y_border - 1));
 }
 
 void TextEdit::setReadOnly(bool readonly)
@@ -72,75 +65,71 @@ bool TextEdit::readOnly()
 
 void TextEdit::setText(const std::string& text)
 {
-	_text = text;
+	this->text = text;
 
 	needs_preprocessing = true;
 	redraw();
 	textChangedNotifier();
 }
 
-std::string TextEdit::text()
+std::string TextEdit::getText()
 {
-	return _text;
+	return text;
 }
 
 void TextEdit::preprocessText()
 {
-	preprocessedtext.clear();
-	std::string text = _text;
+	std::vector<std::string> lines;
+
+	preprocessed_text.clear();
+	std::string text = this->text;
 
-	{ // Handle tab characters
-		for(size_t i = 0; i < text.length(); ++i)
+	// Handle tab characters
+	for(std::size_t i = 0; i < text.length(); ++i)
+	{
+		char ch = text.at(i);
+		if(ch == '\t')
 		{
-			char ch = text.at(i);
-			if(ch == '\t')
-			{
-				text.erase(i, 1);
-				text.insert(i, 4, ' ');
-			}
+			text.erase(i, 1);
+			text.insert(i, 4, ' ');
 		}
 	}
 
-	{ // Handle "\r"
-		for(size_t i = 0; i < text.length(); ++i)
+	// Handle "\r"
+	for(std::size_t i = 0; i < text.length(); ++i)
+	{
+		char ch = text.at(i);
+		if(ch == '\r')
 		{
-			char ch = text.at(i);
-			if(ch == '\r')
-			{
-				text.erase(i, 1);
-			}
+			text.erase(i, 1);
 		}
 	}
 
-	std::list<std::string> lines;
-	{ // Handle new line characters
-		size_t pos = 0;
-		do
-		{
-			pos = text.find("\n");
-			lines.push_back(text.substr(0, pos));
-			text = text.substr(pos + 1);
-		} while(pos != std::string::npos);
-	}
+	// Handle new line characters
+	std::size_t pos = 0;
+	do
+	{
+		pos = text.find("\n");
+		lines.push_back(text.substr(0, pos));
+		text = text.substr(pos + 1);
+	} while(pos != std::string::npos);
 
-	{ // Wrap long lines
-		std::list<std::string>::iterator it;
-		for(it = lines.begin(); it != lines.end(); ++it)
-		{
-			std::string line = *it;
+	// Wrap long lines
+	for(auto it = lines.begin(); it != lines.end(); ++it)
+	{
+		auto line = *it;
 
-			for(size_t i = 0; i < line.length(); ++i)
+		for(std::size_t i = 0; i < line.length(); ++i)
+		{
+			auto linewidth = font.textWidth(line.substr(0, i));
+			if(linewidth >= width() - 2*x_border - 10 - scroll.width())
 			{
-				size_t linewidth = font.textWidth(line.substr(0, i));
-				if(linewidth >= width() - BORDER - 20 - scroll.width())
-				{
-					preprocessedtext.push_back(line.substr(0, i));
-					line = line.substr(i);
-					i = 0;
-				}
+				preprocessed_text.push_back(line.substr(0, i));
+				line = line.substr(i);
+				i = 0;
 			}
-			preprocessedtext.push_back(line);
 		}
+		preprocessed_text.push_back(line);
 	}
 }
 
@@ -155,44 +144,30 @@ void TextEdit::repaintEvent(RepaintEvent* repaintEvent)
 
 	// update values of scroll bar
 	scroll.setRange(height() / font.textHeight());
-	scroll.setMaximum(preprocessedtext.size());
+	scroll.setMaximum(preprocessed_text.size());
 
-	int w = width();
-	int h = height();
-	if((w == 0) || (h == 0))
+	if((width() == 0) || (height() == 0))
 	{
 		return;
 	}
 
-	box.setSize(w, h);
+	box.setSize(width(), height());
 	p.drawImage(0, 0, box);
-
 	p.setColour(Colour(183.0 / 255.0, 219.0 / 255.0, 255.0 / 255.0, 1));
 
-	int skip = scroll.value();
-
-	int ypos = font.textHeight() + 5 + 1 + 1 + 1;
-	std::list<std::string>::iterator it;
-	it = preprocessedtext.begin();
-
-	int c = 0;
-	for(; c < skip; c++)
-	{
-		++it;
-	}
+	int ypos = font.textHeight() + y_border;
 
-	c = 0;
-	for(; it != preprocessedtext.end(); it++)
+	auto scroll_value = scroll.value();
+	for(std::size_t i = 0; i < preprocessed_text.size() - scroll_value; ++i)
 	{
-		if((c * font.textHeight()) >= (height() - 8 - font.textHeight()))
+		if(i * font.textHeight() >= (height() - y_border - font.textHeight()))
 		{
 			break;
 		}
 
-		std::string line = *it;
-		p.drawText(BORDER - 4 + 3, ypos, font, line);
+		auto const& line = preprocessed_text[scroll_value + i];
+		p.drawText(x_border, ypos, font, line);
 		ypos += font.textHeight();
-		++c;
 	}
 }
 
diff --git a/plugingui/textedit.h b/plugingui/textedit.h
index 5959ae9..6ce59b6 100644
--- a/plugingui/textedit.h
+++ b/plugingui/textedit.h
@@ -27,27 +27,32 @@
 #pragma once
 
 #include <string>
-#include <list>
+#include <vector>
 
-#include "widget.h"
 #include "font.h"
-#include "painter.h"
+#include "notifier.h"
 #include "scrollbar.h"
 #include "texturedbox.h"
-#include "notifier.h"
+#include "widget.h"
 
-namespace GUI {
+namespace GUI
+{
 
-class TextEdit : public Widget {
+class TextEdit
+	: public Widget
+{
 public:
-	TextEdit(Widget *parent);
+	TextEdit(Widget* parent);
 	virtual ~TextEdit();
 
 	// From Widget
-	bool isFocusable() override { return true; }
+	bool isFocusable() override
+	{
+		return true;
+	}
 	void resize(std::size_t width, std::size_t height) override;
 
-	std::string text();
+	std::string getText();
 	void setText(const std::string& text);
 
 	void setReadOnly(bool readonly);
@@ -65,20 +70,23 @@ protected:
 private:
 	void scrolled(int value);
 
-	TexturedBox box{getImageCache(), ":resources/widget.png",
-			0, 0, // atlas offset (x, y)
-			7, 1, 7, // dx1, dx2, dx3
-			7, 63, 7}; // dy1, dy2, dy3
+	TexturedBox box{getImageCache(), ":resources/widget.png", 0,
+	    0,         // atlas offset (x, y)
+	    7, 1, 7,   // dx1, dx2, dx3
+	    7, 63, 7}; // dy1, dy2, dy3
+	
+	static constexpr std::size_t x_border{10};
+	static constexpr std::size_t y_border{8};
 
 	ScrollBar scroll;
 	Font font;
 
-	std::string _text;
+	std::string text;
 
 	bool readonly{true};
 	bool needs_preprocessing{false};
 
-	std::list< std::string > preprocessedtext;
+	std::vector<std::string> preprocessed_text;
 };
 
 } // GUI::
diff --git a/src/Makefile.am b/src/Makefile.am
index d0ede77..f50acc6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -36,7 +36,6 @@ nodist_libdg_la_SOURCES = \
 	memchecker.cc \
 	midimapparser.cc \
 	midimapper.cc \
-	mutex.cc \
 	path.cc \
 	powerlist.cc \
 	random.cc \
@@ -80,7 +79,6 @@ EXTRA_DIST = \
 	memchecker.h \
 	midimapparser.h \
 	midimapper.h \
-	mutex.h \
 	nolocale.h \
 	notifier.h \
 	path.h \
diff --git a/src/Makefile.in b/src/Makefile.in
index 914432b..13a2f13 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -107,10 +107,10 @@ nodist_libdg_la_OBJECTS = libdg_la-audiocachefile.lo \
 	libdg_la-instrument.lo libdg_la-instrumentparser.lo \
 	libdg_la-latencyfilter.lo libdg_la-memchecker.lo \
 	libdg_la-midimapparser.lo libdg_la-midimapper.lo \
-	libdg_la-mutex.lo libdg_la-path.lo libdg_la-powerlist.lo \
-	libdg_la-random.lo libdg_la-sample.lo libdg_la-semaphore.lo \
-	libdg_la-saxparser.lo libdg_la-staminafilter.lo \
-	libdg_la-thread.lo libdg_la-versionstr.lo
+	libdg_la-path.lo libdg_la-powerlist.lo libdg_la-random.lo \
+	libdg_la-sample.lo libdg_la-semaphore.lo libdg_la-saxparser.lo \
+	libdg_la-staminafilter.lo libdg_la-thread.lo \
+	libdg_la-versionstr.lo
 libdg_la_OBJECTS = $(nodist_libdg_la_OBJECTS)
 AM_V_lt = $(am__v_lt_ at AM_V@)
 am__v_lt_ = $(am__v_lt_ at AM_DEFAULT_V@)
@@ -377,7 +377,6 @@ nodist_libdg_la_SOURCES = \
 	memchecker.cc \
 	midimapparser.cc \
 	midimapper.cc \
-	mutex.cc \
 	path.cc \
 	powerlist.cc \
 	random.cc \
@@ -421,7 +420,6 @@ EXTRA_DIST = \
 	memchecker.h \
 	midimapparser.h \
 	midimapper.h \
-	mutex.h \
 	nolocale.h \
 	notifier.h \
 	path.h \
@@ -517,7 +515,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdg_la-memchecker.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdg_la-midimapparser.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdg_la-midimapper.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdg_la-mutex.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdg_la-path.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdg_la-powerlist.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdg_la-random.Plo at am__quote@
@@ -717,13 +714,6 @@ libdg_la-midimapper.lo: midimapper.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdg_la-midimapper.lo `test -f 'midimapper.cc' || echo '$(srcdir)/'`midimapper.cc
 
-libdg_la-mutex.lo: mutex.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdg_la-mutex.lo -MD -MP -MF $(DEPDIR)/libdg_la-mutex.Tpo -c -o libdg_la-mutex.lo `test -f 'mutex.cc' || echo '$(srcdir)/'`mutex.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libdg_la-mutex.Tpo $(DEPDIR)/libdg_la-mutex.Plo
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='mutex.cc' object='libdg_la-mutex.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdg_la-mutex.lo `test -f 'mutex.cc' || echo '$(srcdir)/'`mutex.cc
-
 libdg_la-path.lo: path.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdg_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdg_la-path.lo -MD -MP -MF $(DEPDIR)/libdg_la-path.Tpo -c -o libdg_la-path.lo `test -f 'path.cc' || echo '$(srcdir)/'`path.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/libdg_la-path.Tpo $(DEPDIR)/libdg_la-path.Plo
diff --git a/src/atomic.h b/src/atomic.h
index 55ec7e5..7ca5d1e 100644
--- a/src/atomic.h
+++ b/src/atomic.h
@@ -30,7 +30,6 @@
 #include <atomic>
 
 #include <mutex>
-#include "mutex.h"
 
 template <typename T, typename = void>
 class Atomic;
diff --git a/src/audiocache.cc b/src/audiocache.cc
index b01d752..2e9eaf8 100644
--- a/src/audiocache.cc
+++ b/src/audiocache.cc
@@ -72,6 +72,7 @@ sample_t* AudioCache::open(const AudioFile& file,
 
 	if(!file.isValid())
 	{
+		settings.number_of_underruns.fetch_add(1);
 		// File preload not yet ready - skip this sample.
 		id = CACHE_DUMMYID;
 		assert(nodata);
@@ -84,6 +85,7 @@ sample_t* AudioCache::open(const AudioFile& file,
 	// If we are out of available ids we get CACHE_DUMMYID
 	if(id == CACHE_DUMMYID)
 	{
+		settings.number_of_underruns.fetch_add(1);
 		// Use nodata buffer instead.
 		assert(nodata);
 		return nodata;
@@ -98,6 +100,7 @@ sample_t* AudioCache::open(const AudioFile& file,
 	// Next call to 'next()' will read from this point.
 	c.localpos = initial_samples_needed;
 
+	c.ready = false;
 	c.front = nullptr; // This is allocated when needed.
 	c.back = nullptr; // This is allocated when needed.
 
@@ -153,6 +156,7 @@ sample_t* AudioCache::next(cacheid_t id, std::size_t& size)
 
 	if(id == CACHE_DUMMYID)
 	{
+		settings.number_of_underruns.fetch_add(1);
 		assert(nodata);
 		return nodata;
 	}
@@ -186,6 +190,15 @@ sample_t* AudioCache::next(cacheid_t id, std::size_t& size)
 		// We are playing from cache:
 		if(c.localpos < chunk_size)
 		{
+			if(c.front == nullptr)
+			{
+				// Just return silence.
+				settings.number_of_underruns.fetch_add(1);
+				c.localpos += framesize; // Skip these samples so we don't loose sync.
+				assert(nodata);
+				return nodata;
+			}
+
 			sample_t* s = c.front + c.localpos;
 			c.localpos += framesize;
 			return s;
@@ -197,6 +210,8 @@ sample_t* AudioCache::next(cacheid_t id, std::size_t& size)
 	{
 		// Just return silence.
 		settings.number_of_underruns.fetch_add(1);
+		c.localpos += framesize; // Skip these samples so we don't loose sync.
+		assert(nodata);
 		return nodata;
 	}
 
@@ -262,7 +277,10 @@ void AudioCache::setFrameSize(std::size_t framesize)
 
 	if(framesize > nodata_framesize)
 	{
-		delete[] nodata;
+		if(nodata)
+		{
+			nodata_dirty.emplace_back(std::move(nodata)); // Store for later deletion.
+		}
 		nodata = new sample_t[framesize];
 		nodata_framesize = framesize;
 
diff --git a/src/audiocache.h b/src/audiocache.h
index 54abcf7..9c6fa53 100644
--- a/src/audiocache.h
+++ b/src/audiocache.h
@@ -29,6 +29,7 @@
 #include <string>
 #include <list>
 #include <vector>
+#include <memory>
 
 #include "audiotypes.h"
 #include "audiofile.h"
@@ -106,6 +107,7 @@ private:
 	sample_t* nodata{nullptr};
 	std::size_t nodata_framesize{0};
 	std::size_t chunk_size{0};
+	std::list<std::unique_ptr<sample_t[]>> nodata_dirty;
 
 	AudioCacheIDManager id_manager;
 	AudioCacheEventHandler event_handler{id_manager};
diff --git a/src/audiocacheeventhandler.h b/src/audiocacheeventhandler.h
index 7d4ed58..e1e60a9 100644
--- a/src/audiocacheeventhandler.h
+++ b/src/audiocacheeventhandler.h
@@ -32,7 +32,6 @@
 
 #include "thread.h"
 #include "semaphore.h"
-#include "mutex.h"
 
 #include "audiocachefile.h"
 #include "audiocacheidmanager.h"
diff --git a/src/audiocachefile.h b/src/audiocachefile.h
index 01625a7..66a6529 100644
--- a/src/audiocachefile.h
+++ b/src/audiocachefile.h
@@ -30,16 +30,15 @@
 #include <list>
 #include <map>
 #include <vector>
-
 #include <mutex>
-#include "mutex.h"
 
 #include <sndfile.h>
 
 #include <audiotypes.h>
 
 //! Channel data container in the cache world.
-class CacheChannel {
+class CacheChannel
+{
 public:
 	size_t channel; //< Channel number
 	sample_t* samples; //< Sample buffer pointer.
@@ -52,7 +51,8 @@ using CacheChannels = std::list<CacheChannel>;
 //! This class is used to encapsulate reading from a single file source.
 //! The access is ref counted so that the file is only opened once and closed
 //! when it is no longer required.
-class AudioCacheFile {
+class AudioCacheFile
+{
 	friend class AudioCacheFiles;
 	friend class TestableAudioCacheFiles;
 public:
@@ -82,7 +82,8 @@ private:
 	std::vector<sample_t>& read_buffer;
 };
 
-class AudioCacheFiles {
+class AudioCacheFiles
+{
 public:
 	//! Get the CacheAudioFile object corresponding to filename.
 	//! If it does not exist it will be created.
diff --git a/src/audiocacheidmanager.h b/src/audiocacheidmanager.h
index a5a9755..0aa40e3 100644
--- a/src/audiocacheidmanager.h
+++ b/src/audiocacheidmanager.h
@@ -33,7 +33,6 @@
 #include <audiotypes.h>
 
 #include <mutex>
-#include "mutex.h"
 
 class AudioCacheFile;
 
@@ -42,7 +41,8 @@ class AudioCacheFile;
 
 typedef int cacheid_t;
 
-typedef struct {
+struct cache_t
+{
 	cacheid_t id{CACHE_NOID}; //< Current id of this cache_t. CACHE_NOID means not in use.
 
 	AudioCacheFile* afile{nullptr};
@@ -55,9 +55,10 @@ typedef struct {
 
 	sample_t* preloaded_samples{nullptr}; // nullptr means preload buffer not active.
 	size_t preloaded_samples_size{0};
-} cache_t;
+};
 
-class AudioCacheIDManager {
+class AudioCacheIDManager
+{
 	friend class AudioCacheEventHandler;
 public:
 	AudioCacheIDManager() = default;
diff --git a/src/audiofile.cc b/src/audiofile.cc
index 93b2e4f..e274e61 100644
--- a/src/audiofile.cc
+++ b/src/audiofile.cc
@@ -29,11 +29,6 @@
 #include "audiofile.h"
 
 #include <cassert>
-
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-
 #include <sndfile.h>
 
 #include <config.h>
@@ -62,7 +57,7 @@ bool AudioFile::isValid() const
 void AudioFile::unload()
 {
 	// Make sure we don't unload the object while loading it...
-	MutexAutolock l(mutex);
+	std::lock_guard<std::mutex> guard(mutex);
 
 	is_loaded = false;
 
@@ -77,7 +72,7 @@ void AudioFile::unload()
 void AudioFile::load(std::size_t sample_limit)
 {
 	// Make sure we don't unload the object while loading it...
-	MutexAutolock l(mutex);
+	std::lock_guard<std::mutex> guard(mutex);
 
 	if(this->data) // already loaded
 	{
diff --git a/src/audiofile.h b/src/audiofile.h
index 07b40dd..e393511 100644
--- a/src/audiofile.h
+++ b/src/audiofile.h
@@ -30,10 +30,10 @@
 #include <map>
 #include <vector>
 #include <limits>
+#include <mutex>
 
 #include <sndfile.h>
 
-#include "mutex.h"
 #include "audio.h"
 
 class AudioFile
@@ -55,7 +55,7 @@ public:
 
 	bool isValid() const;
 
-	Mutex mutex;
+	std::mutex mutex;
 
 	std::size_t filechannel;
 
diff --git a/src/configfile.cc b/src/configfile.cc
index 71496a0..731d3aa 100644
--- a/src/configfile.cc
+++ b/src/configfile.cc
@@ -30,7 +30,6 @@
 #include <errno.h>
 #include <string.h>
 #include <stdlib.h>
-#include <unistd.h>
 
 #include <sys/stat.h>
 #include <sys/types.h>
diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index 592fa20..5fa2097 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -30,6 +30,7 @@
 #include <cstdio>
 #include <cassert>
 #include <cstring>
+#include <mutex>
 
 #include <event.h>
 #include <audiotypes.h>
@@ -48,6 +49,7 @@ DrumGizmo::DrumGizmo(Settings& settings,
 	, audio_cache(settings)
 	, input_processor(settings, kit, activeevents)
 	, settings(settings)
+	, settings_getter(settings)
 {
 	audio_cache.init(10000); // start thread
 	events.reserve(1000);
@@ -77,8 +79,10 @@ bool DrumGizmo::init()
 
 void DrumGizmo::setFrameSize(size_t framesize)
 {
+	settings.buffer_size.store(framesize);
+
 	// If we are resampling override the frame size.
-	if(resamplers.isActive())
+	if(resamplers.isActive() && enable_resampling)
 	{
 		framesize = RESAMPLER_INPUT_BUFFER;
 	}
@@ -89,6 +93,12 @@ void DrumGizmo::setFrameSize(size_t framesize)
 
 		this->framesize = framesize;
 
+		// Remove all active events as they are cached using the old framesize.
+		for(std::size_t ch = 0; ch < MAX_NUM_CHANNELS; ++ch)
+		{
+			activeevents[ch].clear();
+		}
+
 		// Update framesize in drumkitloader and cachemanager:
 		loader.setFrameSize(framesize);
 		audio_cache.setFrameSize(framesize);
@@ -110,6 +120,11 @@ void DrumGizmo::setRandomSeed(unsigned int seed)
 
 bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
 {
+	if(settings_getter.enable_resampling.hasChanged())
+	{
+		enable_resampling = settings_getter.enable_resampling.getValue();
+	}
+
 	setFrameSize(nsamples);
 	setFreeWheel(ie.isFreewheeling() && oe.isFreewheeling());
 
@@ -124,6 +139,10 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
 	ie.run(pos, nsamples, events);
 
 	double resample_ratio = resamplers.getRatio();
+	if(enable_resampling == false)
+	{
+		resample_ratio = 1.0;
+	}
 	bool active_events_left =
 		input_processor.process(events, pos, resample_ratio);
 
@@ -138,8 +157,7 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
 	// Write audio
 	//
 #ifdef WITH_RESAMPLER
-	if((settings.enable_resampling.load() == false) ||
-	   (!resamplers.isActive())) // No resampling needed
+	if(!enable_resampling || !resamplers.isActive()) // No resampling needed
 	{
 #endif
 		for(size_t c = 0; c < kit.channels.size(); ++c)
@@ -265,7 +283,7 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t* s, size_t sz)
 				}
 
 				{
-					MutexAutolock l(af.mutex);
+					std::lock_guard<std::mutex> guard(af.mutex);
 
 					size_t n = 0; // default start point is 0.
 
@@ -375,7 +393,13 @@ void DrumGizmo::stop()
 
 std::size_t DrumGizmo::getLatency() const
 {
-	return input_processor.getLatency() + resamplers.getLatency();
+	auto latency = input_processor.getLatency();
+	if(enable_resampling)
+	{
+		latency += resamplers.getLatency();
+	}
+
+	return latency;
 }
 
 int DrumGizmo::samplerate()
@@ -393,10 +417,5 @@ void DrumGizmo::setSamplerate(int samplerate)
 
 #ifdef WITH_RESAMPLER
 	resamplers.setup(kit.getSamplerate(), settings.samplerate.load());
-
-	if(resamplers.isActive())
-	{
-		setFrameSize(RESAMPLER_INPUT_BUFFER);
-	}
 #endif/*WITH_RESAMPLER*/
 }
diff --git a/src/drumgizmo.h b/src/drumgizmo.h
index e74d1b5..562e2ba 100644
--- a/src/drumgizmo.h
+++ b/src/drumgizmo.h
@@ -37,7 +37,6 @@
 #include "drumkit.h"
 #include "drumkitloader.h"
 #include "audiocache.h"
-#include "mutex.h"
 #include "chresampler.h"
 #include "settings.h"
 #include "inputprocessor.h"
@@ -79,8 +78,6 @@ private:
 protected:
 	DrumKitLoader loader;
 
-	Mutex mutex;
-
 	AudioOutputEngine& oe;
 	AudioInputEngine& ie;
 
@@ -89,6 +86,7 @@ protected:
 	Resamplers resamplers;
 	sample_t resampler_output_buffer[MAX_NUM_CHANNELS][RESAMPLER_OUTPUT_BUFFER];
 	sample_t resampler_input_buffer[MAX_NUM_CHANNELS][RESAMPLER_INPUT_BUFFER];
+	bool enable_resampling{true};
 
 	std::map<std::string, AudioFile *> audiofiles;
 
@@ -101,6 +99,7 @@ protected:
 
 	std::vector<event_t> events;
 	Settings& settings;
+	SettingsGetter settings_getter;
 
 	Random rand;
 };
diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc
index eed5a33..6f0521b 100644
--- a/src/drumkitloader.cc
+++ b/src/drumkitloader.cc
@@ -85,11 +85,14 @@ bool DrumKitLoader::loadkit(const std::string& file)
 
 	if(file == "")
 	{
-		settings.drumkit_load_status.store(LoadStatus::Error);
+		if (getter.reload_counter.getValue() != 0)
+		{
+			settings.drumkit_load_status.store(LoadStatus::Error);
 
-		// Show a full bar
-		settings.number_of_files.store(1);
-		settings.number_of_files_loaded.store(1);
+			// Show a full bar
+			settings.number_of_files.store(1);
+			settings.number_of_files_loaded.store(1);
+		}
 
 		return false;
 	}
@@ -136,7 +139,7 @@ bool DrumKitLoader::loadkit(const std::string& file)
 #ifdef WITH_RESAMPLER
 	resamplers.setup(kit.getSamplerate(), settings.samplerate.load());
 #endif/*WITH_RESAMPLER*/
-	settings.resampling_active.store(resamplers.isActive());
+	settings.resamplig_recommended.store(resamplers.isActive());
 
 	DEBUG(loadkit, "loadkit: Success\n");
 
@@ -252,8 +255,11 @@ void DrumKitLoader::thread_main()
 		if(getter.midimap_file.hasChanged() || newKit)
 		{
 			auto ie_midi = dynamic_cast<AudioInputEngineMidi*>(&ie);
-			std::cout << "ie_midi: " << (void*)ie_midi << std::endl;
-			if(ie_midi)
+
+			// if there's a midi engine and this is not just the default midimap
+			// name which is set.
+			if(ie_midi && (getter.midimap_file.getValue() != "" ||
+						   getter.reload_counter.getValue() != 0))
 			{
 				settings.midimap_load_status.store(LoadStatus::Loading);
 				bool ret = ie_midi->loadMidiMap(getter.midimap_file.getValue(),
diff --git a/src/drumkitloader.h b/src/drumkitloader.h
index 22fa310..09177fa 100644
--- a/src/drumkitloader.h
+++ b/src/drumkitloader.h
@@ -29,7 +29,6 @@
 #include <string>
 #include <list>
 #include <mutex>
-#include "mutex.h"
 
 #include "thread.h"
 #include "semaphore.h"
diff --git a/src/events.cc b/src/events.cc
index a7ce715..1acbc11 100644
--- a/src/events.cc
+++ b/src/events.cc
@@ -28,14 +28,14 @@
 
 void EventQueue::post(Event* event, timepos_t time)
 {
-	MutexAutolock lock(mutex);
+	std::lock_guard<std::mutex> guard(mutex);
 	event->offset = time;
 	queue.insert(std::pair<timepos_t, Event*>(time, event));
 }
 
 Event* EventQueue::take(timepos_t time)
 {
-	MutexAutolock lock(mutex);
+	std::lock_guard<std::mutex> guard(mutex);
 	std::multimap<timepos_t, Event*>::iterator i = queue.find(time);
 	if(i == queue.end())
 		return NULL;
@@ -46,6 +46,6 @@ Event* EventQueue::take(timepos_t time)
 
 bool EventQueue::hasEvent(timepos_t time)
 {
-	MutexAutolock lock(mutex);
+	std::lock_guard<std::mutex> guard(mutex);
 	return queue.find(time) != queue.end();
 }
diff --git a/src/events.h b/src/events.h
index bbbb7ea..b0ca6cf 100644
--- a/src/events.h
+++ b/src/events.h
@@ -29,11 +29,12 @@
 #include <map>
 #include <stdio.h>
 #include <string>
+#include <mutex>
+
 #include <sndfile.h>
 
 #include "audiofile.h"
 #include "audio.h"
-#include "mutex.h"
 #include "audiocache.h"
 
 typedef unsigned int timepos_t;
@@ -105,6 +106,6 @@ public:
 
 private:
 	std::multimap<timepos_t, Event*> queue;
-	Mutex mutex;
+	std::mutex mutex;
 };
 
diff --git a/src/midimapper.h b/src/midimapper.h
index ea836e3..fc3faec 100644
--- a/src/midimapper.h
+++ b/src/midimapper.h
@@ -29,7 +29,6 @@
 #include <map>
 #include <string>
 #include <mutex>
-#include "mutex.h"
 
 typedef std::map<int, std::string> midimap_t;
 typedef std::map<std::string, int> instrmap_t;
diff --git a/src/mutex.cc b/src/mutex.cc
deleted file mode 100644
index b90132d..0000000
--- a/src/mutex.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set et sw=2 ts=2: */
-/***************************************************************************
- *            mutex.cc
- *
- *  Thu Nov 12 10:51:32 CET 2009
- *  Copyright 2009 Bent Bisballe Nyeng
- *  deva at 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 "mutex.h"
-
-#include <hugin.hpp>
-#include "platform.h"
-
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-#include <windows.h>
-#else
-#include <pthread.h>
-#include <errno.h>
-#endif
-
-struct mutex_private_t {
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-	HANDLE mutex;
-#else
-	pthread_mutex_t mutex;
-#endif
-};
-
-Mutex::Mutex()
-{
-	prv = new struct mutex_private_t();
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-	prv->mutex = CreateMutex(nullptr,  // default security attributes
-	                         FALSE, // initially not owned
-	                         nullptr); // unnamed mutex
-#else
-	pthread_mutex_init (&prv->mutex, nullptr);
-#endif
-}
-
-Mutex::~Mutex()
-{
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-	CloseHandle(prv->mutex);
-#else
-	pthread_mutex_destroy(&prv->mutex);
-#endif
-
-	if(prv)
-	{
-	  delete prv;
-	}
-}
-
-//! \return true if the function succeeds in locking the mutex for the thread.
-//! false otherwise.
-bool Mutex::try_lock()
-{
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-	DEBUG(mutex, "%s\n", __PRETTY_FUNCTION__);
-
-	DWORD result = WaitForSingleObject(prv->mutex, 0);
-
-	DEBUG(mutex, "WAIT_OBJECT_0: %lu, WAIT_TIMEOUT: %lu, result: %lu\n",
-	      WAIT_OBJECT_0, WAIT_TIMEOUT, result);
-
-	return result != WAIT_TIMEOUT;
-#else
-	return pthread_mutex_trylock(&prv->mutex) != EBUSY;
-#endif
-}
-
-void Mutex::lock()
-{
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-	WaitForSingleObject(prv->mutex, // handle to mutex
-	                    INFINITE);  // no time-out interval
-#else
-	pthread_mutex_lock(&prv->mutex);
-#endif
-}
-
-void Mutex::unlock()
-{
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-	ReleaseMutex(prv->mutex);
-#else
-	pthread_mutex_unlock(&prv->mutex);
-#endif
-}
-
-MutexAutolock::MutexAutolock(Mutex &m)
-	: mutex(m)
-{
-	mutex.lock();
-}
-
-MutexAutolock::~MutexAutolock()
-{
-	mutex.unlock();
-}
diff --git a/src/mutex.h b/src/mutex.h
deleted file mode 100644
index 067a4db..0000000
--- a/src/mutex.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set et sw=2 ts=2: */
-/***************************************************************************
- *            mutex.h
- *
- *  Thu Nov 12 10:51:32 CET 2009
- *  Copyright 2009 Bent Bisballe Nyeng
- *  deva at 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 "platform.h"
-
-struct mutex_private_t;
-
-class Mutex {
-public:
-	Mutex();
-	~Mutex();
-
-	bool try_lock();
-	void lock();
-	void unlock();
-
-private:
-	struct mutex_private_t* prv;
-};
-
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-// Hack: mingw doesn't have std::mutex
-namespace std {
-	class mutex : public Mutex {};
-}
-#endif
-
-class MutexAutolock {
-public:
-	MutexAutolock(Mutex &mutex);
-	~MutexAutolock();
-
-private:
-	Mutex &mutex;
-};
diff --git a/src/sample.cc b/src/sample.cc
index ced8a47..9d28a17 100644
--- a/src/sample.cc
+++ b/src/sample.cc
@@ -26,9 +26,6 @@
  */
 #include "sample.h"
 
-#include <stdlib.h>
-#include <unistd.h>
-
 #include <sndfile.h>
 
 Sample::Sample(const std::string& name, float power)
diff --git a/src/settings.h b/src/settings.h
index 61f92e7..6d094ea 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -78,9 +78,10 @@ struct Settings
 	Atomic<float> velocity_randomiser_weight{0.1f};
 
 	Atomic<double> samplerate{44100.0};
+	Atomic<std::size_t> buffer_size{1024}; // Only used to show in the UI.
 
 	Atomic<bool> enable_resampling{true};
-	Atomic<bool> resampling_active{false};
+	Atomic<bool> resamplig_recommended{false};
 
 	Atomic<std::size_t> number_of_files{0};
 	Atomic<std::size_t> number_of_files_loaded{0};
@@ -114,9 +115,10 @@ struct SettingsGetter
 	SettingRef<float> velocity_randomiser_weight;
 
 	SettingRef<double> samplerate;
+	SettingRef<std::size_t> buffer_size;
 
 	SettingRef<bool> enable_resampling;
-	SettingRef<bool> resampling_active;
+	SettingRef<bool> resamplig_recommended;
 
 	SettingRef<std::size_t> number_of_files;
 	SettingRef<std::size_t> number_of_files_loaded;
@@ -142,8 +144,9 @@ struct SettingsGetter
 		, enable_velocity_randomiser{settings.enable_velocity_randomiser}
 		, velocity_randomiser_weight{settings.velocity_randomiser_weight}
 		, samplerate{settings.samplerate}
+		, buffer_size(settings.buffer_size)
 		, enable_resampling{settings.enable_resampling}
-		, resampling_active{settings.resampling_active}
+		, resamplig_recommended{settings.resamplig_recommended}
 		, number_of_files{settings.number_of_files}
 		, number_of_files_loaded{settings.number_of_files_loaded}
 		, current_file{settings.current_file}
@@ -179,9 +182,10 @@ public:
 	Notifier<float> velocity_randomiser_weight;
 
 	Notifier<double> samplerate;
+	Notifier<std::size_t> buffer_size;
 
 	Notifier<bool> enable_resampling;
-	Notifier<bool> resampling_active;
+	Notifier<bool> resamplig_recommended;
 
 	Notifier<std::size_t> number_of_files;
 	Notifier<std::size_t> number_of_files_loaded;
@@ -215,9 +219,10 @@ public:
 		EVAL(velocity_randomiser_weight);
 
 		EVAL(samplerate);
+		EVAL(buffer_size);
 
 		EVAL(enable_resampling);
-		EVAL(resampling_active);
+		EVAL(resamplig_recommended);
 
 		EVAL(number_of_files);
 		EVAL(number_of_files_loaded);
diff --git a/test/Makefile.am b/test/Makefile.am
index 027b022..08ef4fa 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -37,7 +37,6 @@ audiocache_SOURCES = \
 	$(top_srcdir)/src/audiocachefile.cc \
 	$(top_srcdir)/src/audiocacheidmanager.cc \
 	$(top_srcdir)/src/thread.cc \
-	$(top_srcdir)/src/mutex.cc \
 	$(top_srcdir)/src/semaphore.cc \
 	$(top_srcdir)/src/audiofile.cc \
 	$(top_srcdir)/src/random.cc \
@@ -52,7 +51,6 @@ audiocachefile_LDFLAGS = $(PTHREAD_LIBS) $(CPPUNIT_LIBS) $(SNDFILE_LIBS)
 audiocachefile_SOURCES = \
 	$(top_srcdir)/src/audiocachefile.cc \
 	$(top_srcdir)/src/thread.cc \
-	$(top_srcdir)/src/mutex.cc \
 	$(top_srcdir)/src/semaphore.cc \
 	$(top_srcdir)/src/audiofile.cc \
 	$(top_srcdir)/src/random.cc \
@@ -79,7 +77,6 @@ audiocacheeventhandler_SOURCES = \
 	$(top_srcdir)/src/audiocacheeventhandler.cc \
 	$(top_srcdir)/src/audiocacheidmanager.cc \
 	$(top_srcdir)/src/audiocachefile.cc \
-	$(top_srcdir)/src/mutex.cc \
 	$(top_srcdir)/src/thread.cc \
 	$(top_srcdir)/src/semaphore.cc \
 	test.cc \
diff --git a/test/Makefile.in b/test/Makefile.in
index bc6010f..836d4ae 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -134,17 +134,15 @@ am__audiocache_SOURCES_DIST = $(top_srcdir)/src/audiocache.cc \
 	$(top_srcdir)/src/audiocacheeventhandler.cc \
 	$(top_srcdir)/src/audiocachefile.cc \
 	$(top_srcdir)/src/audiocacheidmanager.cc \
-	$(top_srcdir)/src/thread.cc $(top_srcdir)/src/mutex.cc \
-	$(top_srcdir)/src/semaphore.cc $(top_srcdir)/src/audiofile.cc \
-	$(top_srcdir)/src/random.cc test.cc drumkit_creator.cc \
-	audiocachetest.cc
+	$(top_srcdir)/src/thread.cc $(top_srcdir)/src/semaphore.cc \
+	$(top_srcdir)/src/audiofile.cc $(top_srcdir)/src/random.cc \
+	test.cc drumkit_creator.cc audiocachetest.cc
 @ENABLE_TESTS_TRUE at am_audiocache_OBJECTS =  \
 @ENABLE_TESTS_TRUE@	audiocache-audiocache.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocache-audiocacheeventhandler.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocache-audiocachefile.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocache-audiocacheidmanager.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocache-thread.$(OBJEXT) \
- at ENABLE_TESTS_TRUE@	audiocache-mutex.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocache-semaphore.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocache-audiofile.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocache-random.$(OBJEXT) \
@@ -159,13 +157,12 @@ audiocache_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
 am__audiocacheeventhandler_SOURCES_DIST =  \
 	$(top_srcdir)/src/audiocacheeventhandler.cc \
 	$(top_srcdir)/src/audiocacheidmanager.cc \
-	$(top_srcdir)/src/audiocachefile.cc $(top_srcdir)/src/mutex.cc \
+	$(top_srcdir)/src/audiocachefile.cc \
 	$(top_srcdir)/src/thread.cc $(top_srcdir)/src/semaphore.cc \
 	test.cc audiocacheeventhandlertest.cc
 @ENABLE_TESTS_TRUE at am_audiocacheeventhandler_OBJECTS = audiocacheeventhandler-audiocacheeventhandler.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocacheeventhandler-audiocacheidmanager.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocacheeventhandler-audiocachefile.$(OBJEXT) \
- at ENABLE_TESTS_TRUE@	audiocacheeventhandler-mutex.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocacheeventhandler-thread.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocacheeventhandler-semaphore.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocacheeventhandler-test.$(OBJEXT) \
@@ -177,14 +174,12 @@ audiocacheeventhandler_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
 	$(audiocacheeventhandler_CXXFLAGS) $(CXXFLAGS) \
 	$(audiocacheeventhandler_LDFLAGS) $(LDFLAGS) -o $@
 am__audiocachefile_SOURCES_DIST = $(top_srcdir)/src/audiocachefile.cc \
-	$(top_srcdir)/src/thread.cc $(top_srcdir)/src/mutex.cc \
-	$(top_srcdir)/src/semaphore.cc $(top_srcdir)/src/audiofile.cc \
-	$(top_srcdir)/src/random.cc test.cc drumkit_creator.cc \
-	audiocachefiletest.cc
+	$(top_srcdir)/src/thread.cc $(top_srcdir)/src/semaphore.cc \
+	$(top_srcdir)/src/audiofile.cc $(top_srcdir)/src/random.cc \
+	test.cc drumkit_creator.cc audiocachefiletest.cc
 @ENABLE_TESTS_TRUE at am_audiocachefile_OBJECTS =  \
 @ENABLE_TESTS_TRUE@	audiocachefile-audiocachefile.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocachefile-thread.$(OBJEXT) \
- at ENABLE_TESTS_TRUE@	audiocachefile-mutex.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocachefile-semaphore.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocachefile-audiofile.$(OBJEXT) \
 @ENABLE_TESTS_TRUE@	audiocachefile-random.$(OBJEXT) \
@@ -892,7 +887,6 @@ SUBDIRS = dgreftest uitests
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/audiocachefile.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/audiocacheidmanager.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/thread.cc \
- at ENABLE_TESTS_TRUE@	$(top_srcdir)/src/mutex.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/semaphore.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/audiofile.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/random.cc \
@@ -908,7 +902,6 @@ SUBDIRS = dgreftest uitests
 @ENABLE_TESTS_TRUE at audiocachefile_SOURCES = \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/audiocachefile.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/thread.cc \
- at ENABLE_TESTS_TRUE@	$(top_srcdir)/src/mutex.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/semaphore.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/audiofile.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/random.cc \
@@ -937,7 +930,6 @@ SUBDIRS = dgreftest uitests
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/audiocacheeventhandler.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/audiocacheidmanager.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/audiocachefile.cc \
- at ENABLE_TESTS_TRUE@	$(top_srcdir)/src/mutex.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/thread.cc \
 @ENABLE_TESTS_TRUE@	$(top_srcdir)/src/semaphore.cc \
 @ENABLE_TESTS_TRUE@	test.cc \
@@ -1211,7 +1203,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocache-audiocachetest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocache-audiofile.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocache-drumkit_creator.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocache-mutex.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocache-random.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocache-semaphore.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocache-test.Po at am__quote@
@@ -1220,7 +1211,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocacheeventhandler-audiocacheeventhandlertest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocacheeventhandler-audiocachefile.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocacheeventhandler-audiocacheidmanager.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocacheeventhandler-mutex.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocacheeventhandler-semaphore.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocacheeventhandler-test.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocacheeventhandler-thread.Po at am__quote@
@@ -1228,7 +1218,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocachefile-audiocachefiletest.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocachefile-audiofile.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocachefile-drumkit_creator.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocachefile-mutex.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocachefile-random.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocachefile-semaphore.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/audiocachefile-test.Po at am__quote@
@@ -1434,20 +1423,6 @@ audiocache-thread.obj: $(top_srcdir)/src/thread.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocache_CXXFLAGS) $(CXXFLAGS) -c -o audiocache-thread.obj `if test -f '$(top_srcdir)/src/thread.cc'; then $(CYGPATH_W) '$(top_srcdir)/src/thread.cc'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/thread.cc'; fi`
 
-audiocache-mutex.o: $(top_srcdir)/src/mutex.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocache_CXXFLAGS) $(CXXFLAGS) -MT audiocache-mutex.o -MD -MP -MF $(DEPDIR)/audiocache-mutex.Tpo -c -o audiocache-mutex.o `test -f '$(top_srcdir)/src/mutex.cc' || echo '$(srcdir)/'`$(top_srcdir)/src/mutex.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/audiocache-mutex.Tpo $(DEPDIR)/audiocache-mutex.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$(top_srcdir)/src/mutex.cc' object='audiocache-mutex.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocache_CXXFLAGS) $(CXXFLAGS) -c -o audiocache-mutex.o `test -f '$(top_srcdir)/src/mutex.cc' || echo '$(srcdir)/'`$(top_srcdir)/src/mutex.cc
-
-audiocache-mutex.obj: $(top_srcdir)/src/mutex.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocache_CXXFLAGS) $(CXXFLAGS) -MT audiocache-mutex.obj -MD -MP -MF $(DEPDIR)/audiocache-mutex.Tpo -c -o audiocache-mutex.obj `if test -f '$(top_srcdir)/src/mutex.cc'; then $(CYGPATH_W) '$(top_srcdir)/src/mutex.cc'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mutex.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/audiocache-mutex.Tpo $(DEPDIR)/audiocache-mutex.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$(top_srcdir)/src/mutex.cc' object='audiocache-mutex.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocache_CXXFLAGS) $(CXXFLAGS) -c -o audiocache-mutex.obj `if test -f '$(top_srcdir)/src/mutex.cc'; then $(CYGPATH_W) '$(top_srcdir)/src/mutex.cc'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mutex.cc'; fi`
-
 audiocache-semaphore.o: $(top_srcdir)/src/semaphore.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocache_CXXFLAGS) $(CXXFLAGS) -MT audiocache-semaphore.o -MD -MP -MF $(DEPDIR)/audiocache-semaphore.Tpo -c -o audiocache-semaphore.o `test -f '$(top_srcdir)/src/semaphore.cc' || echo '$(srcdir)/'`$(top_srcdir)/src/semaphore.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/audiocache-semaphore.Tpo $(DEPDIR)/audiocache-semaphore.Po
@@ -1574,20 +1549,6 @@ audiocacheeventhandler-audiocachefile.obj: $(top_srcdir)/src/audiocachefile.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocacheeventhandler_CXXFLAGS) $(CXXFLAGS) -c -o audiocacheeventhandler-audiocachefile.obj `if test -f '$(top_srcdir)/src/audiocachefile.cc'; then $(CYGPATH_W) '$(top_srcdir)/src/audiocachefile.cc'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/audiocachefile.cc'; fi`
 
-audiocacheeventhandler-mutex.o: $(top_srcdir)/src/mutex.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocacheeventhandler_CXXFLAGS) $(CXXFLAGS) -MT audiocacheeventhandler-mutex.o -MD -MP -MF $(DEPDIR)/audiocacheeventhandler-mutex.Tpo -c -o audiocacheeventhandler-mutex.o `test -f '$(top_srcdir)/src/mutex.cc' || echo '$(srcdir)/'`$(top_srcdir)/src/mutex.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/audiocacheeventhandler-mutex.Tpo $(DEPDIR)/audiocacheeventhandler-mutex.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$(top_srcdir)/src/mutex.cc' object='audiocacheeventhandler-mutex.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocacheeventhandler_CXXFLAGS) $(CXXFLAGS) -c -o audiocacheeventhandler-mutex.o `test -f '$(top_srcdir)/src/mutex.cc' || echo '$(srcdir)/'`$(top_srcdir)/src/mutex.cc
-
-audiocacheeventhandler-mutex.obj: $(top_srcdir)/src/mutex.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocacheeventhandler_CXXFLAGS) $(CXXFLAGS) -MT audiocacheeventhandler-mutex.obj -MD -MP -MF $(DEPDIR)/audiocacheeventhandler-mutex.Tpo -c -o audiocacheeventhandler-mutex.obj `if test -f '$(top_srcdir)/src/mutex.cc'; then $(CYGPATH_W) '$(top_srcdir)/src/mutex.cc'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mutex.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/audiocacheeventhandler-mutex.Tpo $(DEPDIR)/audiocacheeventhandler-mutex.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$(top_srcdir)/src/mutex.cc' object='audiocacheeventhandler-mutex.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocacheeventhandler_CXXFLAGS) $(CXXFLAGS) -c -o audiocacheeventhandler-mutex.obj `if test -f '$(top_srcdir)/src/mutex.cc'; then $(CYGPATH_W) '$(top_srcdir)/src/mutex.cc'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mutex.cc'; fi`
-
 audiocacheeventhandler-thread.o: $(top_srcdir)/src/thread.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocacheeventhandler_CXXFLAGS) $(CXXFLAGS) -MT audiocacheeventhandler-thread.o -MD -MP -MF $(DEPDIR)/audiocacheeventhandler-thread.Tpo -c -o audiocacheeventhandler-thread.o `test -f '$(top_srcdir)/src/thread.cc' || echo '$(srcdir)/'`$(top_srcdir)/src/thread.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/audiocacheeventhandler-thread.Tpo $(DEPDIR)/audiocacheeventhandler-thread.Po
@@ -1672,20 +1633,6 @@ audiocachefile-thread.obj: $(top_srcdir)/src/thread.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocachefile_CXXFLAGS) $(CXXFLAGS) -c -o audiocachefile-thread.obj `if test -f '$(top_srcdir)/src/thread.cc'; then $(CYGPATH_W) '$(top_srcdir)/src/thread.cc'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/thread.cc'; fi`
 
-audiocachefile-mutex.o: $(top_srcdir)/src/mutex.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocachefile_CXXFLAGS) $(CXXFLAGS) -MT audiocachefile-mutex.o -MD -MP -MF $(DEPDIR)/audiocachefile-mutex.Tpo -c -o audiocachefile-mutex.o `test -f '$(top_srcdir)/src/mutex.cc' || echo '$(srcdir)/'`$(top_srcdir)/src/mutex.cc
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/audiocachefile-mutex.Tpo $(DEPDIR)/audiocachefile-mutex.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$(top_srcdir)/src/mutex.cc' object='audiocachefile-mutex.o' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocachefile_CXXFLAGS) $(CXXFLAGS) -c -o audiocachefile-mutex.o `test -f '$(top_srcdir)/src/mutex.cc' || echo '$(srcdir)/'`$(top_srcdir)/src/mutex.cc
-
-audiocachefile-mutex.obj: $(top_srcdir)/src/mutex.cc
- at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocachefile_CXXFLAGS) $(CXXFLAGS) -MT audiocachefile-mutex.obj -MD -MP -MF $(DEPDIR)/audiocachefile-mutex.Tpo -c -o audiocachefile-mutex.obj `if test -f '$(top_srcdir)/src/mutex.cc'; then $(CYGPATH_W) '$(top_srcdir)/src/mutex.cc'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mutex.cc'; fi`
- at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/audiocachefile-mutex.Tpo $(DEPDIR)/audiocachefile-mutex.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$(top_srcdir)/src/mutex.cc' object='audiocachefile-mutex.obj' libtool=no @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocachefile_CXXFLAGS) $(CXXFLAGS) -c -o audiocachefile-mutex.obj `if test -f '$(top_srcdir)/src/mutex.cc'; then $(CYGPATH_W) '$(top_srcdir)/src/mutex.cc'; else $(CYGPATH_W) '$(srcdir)/$(top_srcdir)/src/mutex.cc'; fi`
-
 audiocachefile-semaphore.o: $(top_srcdir)/src/semaphore.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(audiocachefile_CXXFLAGS) $(CXXFLAGS) -MT audiocachefile-semaphore.o -MD -MP -MF $(DEPDIR)/audiocachefile-semaphore.Tpo -c -o audiocachefile-semaphore.o `test -f '$(top_srcdir)/src/semaphore.cc' || echo '$(srcdir)/'`$(top_srcdir)/src/semaphore.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/audiocachefile-semaphore.Tpo $(DEPDIR)/audiocachefile-semaphore.Po
diff --git a/test/audiocachetest.cc b/test/audiocachetest.cc
index 0e3db10..c03bee4 100644
--- a/test/audiocachetest.cc
+++ b/test/audiocachetest.cc
@@ -26,10 +26,12 @@
  */
 #include <cppunit/extensions/HelperMacros.h>
 
+#include <thread>
+#include <chrono>
+
 #include <audiofile.h>
 #include <audiocache.h>
 #include <settings.h>
-#include <unistd.h>
 
 #include "drumkit_creator.h"
 
@@ -108,7 +110,7 @@ public:
 					int timeout = 1000;
 					while(!audio_cache.isReady(id))
 					{
-						usleep(1000);
+						std::this_thread::sleep_for(std::chrono::milliseconds(1));
 						if(--timeout == 0)
 						{
 							CPPUNIT_ASSERT(false); // timeout
diff --git a/test/dgreftest/dgreftest.cc b/test/dgreftest/dgreftest.cc
index f9eef03..ea38091 100644
--- a/test/dgreftest/dgreftest.cc
+++ b/test/dgreftest/dgreftest.cc
@@ -29,7 +29,8 @@
 #include <string>
 #include <iostream>
 #include <cassert>
-#include <unistd.h>
+#include <thread>
+#include <chrono>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -99,7 +100,7 @@ int main(int argc, char* argv[])
 
 	while(settings.drumkit_load_status.load() != LoadStatus::Done)
 	{
-		usleep(10000);
+		std::this_thread::sleep_for(std::chrono::milliseconds(10));
 
 		int total = settings.number_of_files.load();
 		int loaded = settings.number_of_files_loaded.load();
diff --git a/test/dgreftest/midiinputengine.cc b/test/dgreftest/midiinputengine.cc
index aba726f..84f4cc6 100644
--- a/test/dgreftest/midiinputengine.cc
+++ b/test/dgreftest/midiinputengine.cc
@@ -29,6 +29,7 @@
 #include <iostream>
 
 static int const NOTE_ON = 0x90;
+static int const NOTE_MASK = 0xF0;
 
 MidifileInputEngine::MidifileInputEngine()
 	: AudioInputEngineMidi{}
@@ -147,7 +148,7 @@ void MidifileInputEngine::run(size_t pos, size_t len, std::vector<event_t>& even
 		if(!smf_event_is_metadata(current_event))
 		{
 			if((current_event->midi_buffer_length == 3) &&
-			    ((current_event->midi_buffer[0] & NOTE_ON) == NOTE_ON) &&
+			    ((current_event->midi_buffer[0] & NOTE_MASK) == NOTE_ON) &&
 			    (track == -1 || current_event->track_number == track) &&
 			    current_event->midi_buffer[2] > 0)
 			{
diff --git a/test/enginetest.cc b/test/enginetest.cc
index 5e33fe2..ad4315d 100644
--- a/test/enginetest.cc
+++ b/test/enginetest.cc
@@ -26,8 +26,10 @@
  */
 #include <cppunit/extensions/HelperMacros.h>
 
+#include <thread>
+#include <chrono>
+
 #include <drumgizmo.h>
-#include <unistd.h>
 
 #include "drumkit_creator.h"
 
@@ -100,18 +102,18 @@ public:
 		for(int i = 0; i < 100; ++i)
 		{
 			settings.drumkit_file.store(kit1_file);
-			usleep(100);
+			std::this_thread::sleep_for(std::chrono::microseconds(100));
 			settings.drumkit_file.store(kit2_file);
-			usleep(100);
+			std::this_thread::sleep_for(std::chrono::microseconds(100));
 		}
 
 		// Switch kits with bigger delay giving the loader time to finish
 		for(int i = 0; i < 100; ++i)
 		{
 			settings.drumkit_file.store(kit1_file);
-			usleep(10000);
+			std::this_thread::sleep_for(std::chrono::milliseconds(10));
 			settings.drumkit_file.store(kit2_file);
-			usleep(10000);
+			std::this_thread::sleep_for(std::chrono::milliseconds(10));
 		}
 	}
 };
diff --git a/test/lv2.cc b/test/lv2.cc
index 78bf342..4fd197e 100644
--- a/test/lv2.cc
+++ b/test/lv2.cc
@@ -26,7 +26,8 @@
  */
 #include <cppunit/extensions/HelperMacros.h>
 
-#include <unistd.h>
+#include <thread>
+#include <chrono>
 #include <memory.h>
 #include <stdio.h>
 #include <arpa/inet.h>
@@ -139,7 +140,7 @@ public:
 		// run for 1 samples to trigger kit loading
 		res = h.run(1);
 		CPPUNIT_ASSERT_EQUAL(0, res);
-		usleep(1000); // wait for kit to get loaded (async),
+		std::this_thread::sleep_for(std::chrono::milliseconds(1)); // wait for kit to get loaded (async),
 
 		res = h.run(100);
 		CPPUNIT_ASSERT_EQUAL(0, res);
@@ -217,7 +218,7 @@ public:
 		// run for 1 samples to trigger kit loading
 		res = h.run(1);
 		CPPUNIT_ASSERT_EQUAL(0, res);
-		usleep(1000); // wait for kit to get loaded (async),
+		std::this_thread::sleep_for(std::chrono::milliseconds(1)); // wait for kit to get loaded (async),
 
 		seq.addMidiNote(5, 1, 127);
 		res = h.run(100);
@@ -307,13 +308,13 @@ public:
 		// run for 1 samples to trigger kit loading
 		res = h.run(1);
 		CPPUNIT_ASSERT_EQUAL(0, res);
-		sleep(1); // wait for kit to get loaded (async),
+		std::this_thread::sleep_for(std::chrono::seconds(1));  // wait for kit to get loaded (async),
 
 		seq.addMidiNote(5, 1, 127);
 		for(int i = 0; i < 10; i++)
 		{
 			res = h.run(10);
-			usleep(1000);
+			std::this_thread::sleep_for(std::chrono::milliseconds(1));
 			CPPUNIT_ASSERT_EQUAL(0, res);
 
 			//printf("Iteration:\n");
@@ -330,7 +331,7 @@ public:
 
 		seq.addMidiNote(5, 1, 127);
 		res = h.run(10);
-		usleep(1000);
+		std::this_thread::sleep_for(std::chrono::milliseconds(1));
 		CPPUNIT_ASSERT_EQUAL(0, res);
 
 		/*
diff --git a/test/resampler.cc b/test/resampler.cc
index fa52cbf..2b6862d 100644
--- a/test/resampler.cc
+++ b/test/resampler.cc
@@ -27,7 +27,6 @@
 #include <cppunit/extensions/HelperMacros.h>
 
 #include "../src/chresampler.h"
-#include <unistd.h>
 
 #define BUFSZ 500
 
diff --git a/test/uitests/filebrowsertest.cc b/test/uitests/filebrowsertest.cc
index c558fab..5f78921 100644
--- a/test/uitests/filebrowsertest.cc
+++ b/test/uitests/filebrowsertest.cc
@@ -25,14 +25,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include <iostream>
-
-#include <platform.h>
-
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-#include <unistd.h>
+#include <chrono>
+#include <thread>
 
 #include <hugin.hpp>
 #include <window.h>
@@ -135,11 +129,7 @@ int main()
 
 	while(test_window.processEvents())
 	{
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-		SleepEx(50, FALSE);
-#else
-		usleep(50000);
-#endif
+		std::this_thread::sleep_for(std::chrono::milliseconds(50));
 	}
 
 	return 0;
diff --git a/test/uitests/framewidgettest.cc b/test/uitests/framewidgettest.cc
index 2b94688..a2a24db 100644
--- a/test/uitests/framewidgettest.cc
+++ b/test/uitests/framewidgettest.cc
@@ -25,14 +25,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include <iostream>
-
-#include <platform.h>
-
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-#include <unistd.h>
+#include <chrono>
+#include <thread>
 
 #include <button.h>
 #include <checkbox.h>
@@ -180,11 +174,7 @@ int main()
 
 	while(test_window.processEvents())
 	{
-#ifdef WIN32
-		SleepEx(50, FALSE);
-#else
-		usleep(50000);
-#endif
+		std::this_thread::sleep_for(std::chrono::milliseconds(50));
 	}
 
 	return 0;
diff --git a/test/uitests/resizetest.cc b/test/uitests/resizetest.cc
index f5ba01b..5ede2b6 100644
--- a/test/uitests/resizetest.cc
+++ b/test/uitests/resizetest.cc
@@ -25,14 +25,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include <iostream>
-
-#include <platform.h>
-
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-#include <unistd.h>
+#include <chrono>
+#include <thread>
 
 #include <hugin.hpp>
 #include <window.h>
@@ -135,11 +129,7 @@ int main()
 
 	while(test_window.processEvents())
 	{
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-		SleepEx(50, FALSE);
-#else
-		usleep(50000);
-#endif
+		std::this_thread::sleep_for(std::chrono::milliseconds(50));
 	}
 
 	return 0;
diff --git a/test/uitests/tabwidgettest.cc b/test/uitests/tabwidgettest.cc
index 292991c..722dc02 100644
--- a/test/uitests/tabwidgettest.cc
+++ b/test/uitests/tabwidgettest.cc
@@ -25,14 +25,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
  */
 #include <iostream>
-
-#include <platform.h>
-
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#endif
-#include <unistd.h>
+#include <chrono>
+#include <thread>
 
 #include <hugin.hpp>
 #include <window.h>
@@ -156,11 +150,7 @@ int main()
 
 	while(test_window.processEvents())
 	{
-#if DG_PLATFORM == DG_PLATFORM_WINDOWS
-		SleepEx(50, FALSE);
-#else
-		usleep(50000);
-#endif
+		std::this_thread::sleep_for(std::chrono::milliseconds(50));
 	}
 
 	return 0;
diff --git a/version.h b/version.h
index 26e6bd0..7ad65a3 100644
--- a/version.h
+++ b/version.h
@@ -1 +1 @@
-#define VERSION "0.9.13"
+#define VERSION "0.9.14"

-- 
drumgizmo packaging



More information about the pkg-multimedia-commits mailing list