diff --git a/configure.ac b/configure.ac
index 5e6bca434027409290ad216c979847dee5a640c9..9b12d4b8b7173324e2f217f3ba5754a3e53c8abf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -351,10 +351,6 @@ AM_CONDITIONAL(HAVE_PORTAUDIO, test "x$with_portaudio" = "xyes")
 AC_DEFINE_UNQUOTED([HAVE_JACK], `if test "x$have_jack" = "xyes"; then echo 1; else echo 0; fi`, [Define if you have jack])
 AM_CONDITIONAL(BUILD_JACK, test "x$have_jack" = "xyes")
 
-dnl Check for the samplerate development package - name: libsamplerate0-dev
-LIBSAMPLERATE_MIN_VERSION=0.1.2
-PKG_CHECK_MODULES(SAMPLERATE, samplerate >= ${LIBSAMPLERATE_MIN_VERSION},, AC_MSG_ERROR([Missing libsamplerate development files]))
-
 dnl Coverage is default-disabled
 AC_ARG_ENABLE([coverage], AS_HELP_STRING([--enable-coverage], [Enable coverage]))
 
diff --git a/contrib/src/samplerate/SHA512SUMS b/contrib/src/samplerate/SHA512SUMS
deleted file mode 100644
index 0d9ad4088d25bfa6ec97683e32fb7c7f39a0aa40..0000000000000000000000000000000000000000
--- a/contrib/src/samplerate/SHA512SUMS
+++ /dev/null
@@ -1 +0,0 @@
-85d93df24d9d62e7803a5d0ac5d268b2085214adcb160e32fac316b12ee8a0ce36ccfb433a3c0a08f6e3ec418a5962bdb84f8a11262286a9b347436983029a7d  libsamplerate-0.1.8.tar.gz
diff --git a/contrib/src/samplerate/carbon.patch b/contrib/src/samplerate/carbon.patch
deleted file mode 100644
index a6980af016fc7f4af083b1f1034b38b83e593a39..0000000000000000000000000000000000000000
--- a/contrib/src/samplerate/carbon.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/examples/audio_out.c.orig	2014-06-26 21:09:44.000000000 -0400
-+++ b/examples/audio_out.c	2014-06-26 21:09:58.000000000 -0400
-@@ -172,7 +172,6 @@
- 
- #if (defined (__MACH__) && defined (__APPLE__)) /* MacOSX */
- 
--#include <Carbon.h>
- #include <CoreAudio/AudioHardware.h>
- 
- #define	MACOSX_MAGIC	MAKE_MAGIC ('M', 'a', 'c', ' ', 'O', 'S', ' ', 'X')
diff --git a/contrib/src/samplerate/disable_assembler.patch b/contrib/src/samplerate/disable_assembler.patch
deleted file mode 100644
index e329d48225521430d159920b9f8d32906a53fd49..0000000000000000000000000000000000000000
--- a/contrib/src/samplerate/disable_assembler.patch
+++ /dev/null
@@ -1,50 +0,0 @@
---- a/src/float_cast.h	2011-01-19 05:39:36.000000000 -0500
-+++ b/src/float_cast.h	2016-05-30 17:09:20.000000000 -0400
-@@ -230,38 +230,12 @@
- 	#undef lrint
- 	#undef lrintf
-
--	#define lrint	double2int
--	#define lrintf	float2int
-+	#warning "Don't have the functions lrint() and lrintf()."
-+	#warning "Replacing these functions with a standard C cast."
-
--	inline static long
--	float2int (register float in)
--	{	int res [2] ;
--
--		__asm__ __volatile__
--		(	"fctiw	%1, %1\n\t"
--			"stfd	%1, %0"
--			: "=m" (res)	/* Output */
--			: "f" (in)		/* Input */
--			: "memory"
--			) ;
--
--		return res [1] ;
--	} /* lrintf */
--
--	inline static long
--	double2int (register double in)
--	{	int res [2] ;
--
--		__asm__ __volatile__
--		(	"fctiw	%1, %1\n\t"
--			"stfd	%1, %0"
--			: "=m" (res)	/* Output */
--			: "f" (in)		/* Input */
--			: "memory"
--			) ;
-+	#define	lrint(dbl)		((long) (dbl))
-+	#define	lrintf(flt)		((long) (flt))
-
--		return res [1] ;
--	} /* lrint */
-
- #else
- 	#ifndef __sgi
-@@ -278,4 +252,3 @@
-
-
- #endif /* FLOAT_CAST_HEADER */
--
diff --git a/contrib/src/samplerate/disable_tests.patch b/contrib/src/samplerate/disable_tests.patch
deleted file mode 100644
index 1833a0402fad073156216b092f570f9eca59373e..0000000000000000000000000000000000000000
--- a/contrib/src/samplerate/disable_tests.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 4188b5b9e553911f562e2ae147c8d2ae17bc2500 Mon Sep 17 00:00:00 2001
-From: Adrien Beraud <adrien.beraud@savoirfairelinux.com>
-Date: Wed, 2 Aug 2017 16:42:36 -0400
-Subject: [PATCH] don't build example, doc, tests
-
----
- Makefile.am | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/Makefile.am b/Makefile.am
-index 1295c92..47bd97d 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -2,7 +2,7 @@
- 
- DISTCHECK_CONFIGURE_FLAGS = --enable-gcc-werror
- 
--SUBDIRS = M4 src doc examples tests
-+SUBDIRS = M4 src
- DIST_SUBDIRS = Win32 $(SUBDIRS)
- 
- EXTRA_DIST = autogen.sh libsamplerate.spec.in samplerate.pc.in Make.bat
--- 
-2.11.0
-
diff --git a/contrib/src/samplerate/fetch_and_patch.bat b/contrib/src/samplerate/fetch_and_patch.bat
deleted file mode 100644
index 713a637e1b63c90c8b9fffc13c46ecb2324f9d0e..0000000000000000000000000000000000000000
--- a/contrib/src/samplerate/fetch_and_patch.bat
+++ /dev/null
@@ -1,22 +0,0 @@
-set BUILD=%SRC%..\build
-
-set SAMPLERATE_VERSION=0.1.8
-set SAMPLERATE_URL="http://www.mega-nerd.com/SRC/libsamplerate-%SAMPLERATE_VERSION%.tar.gz"
-
-mkdir %BUILD%
-
-if %USE_CACHE%==1 (
-    copy %CACHE_DIR%\libsamplerate-%SAMPLERATE_VERSION%.tar.gz %cd%
-) else (
-    %WGET_CMD% %SAMPLERATE_URL%
-)
-
-7z -y e libsamplerate-%SAMPLERATE_VERSION%.tar.gz  && 7z -y x libsamplerate-%SAMPLERATE_VERSION%.tar -o%BUILD%
-del libsamplerate-%SAMPLERATE_VERSION%.tar && del libsamplerate-%SAMPLERATE_VERSION%.tar.gz
-rename %BUILD%\libsamplerate-%SAMPLERATE_VERSION% libsamplerate
-
-cd %BUILD%\libsamplerate
-
-%APPLY_CMD% %SRC%\samplerate\samplerate-vs2017.patch
-
-cd %SRC%
\ No newline at end of file
diff --git a/contrib/src/samplerate/rules.mak b/contrib/src/samplerate/rules.mak
deleted file mode 100644
index dcfe8f7064df7e73725849834c3afdb49b900794..0000000000000000000000000000000000000000
--- a/contrib/src/samplerate/rules.mak
+++ /dev/null
@@ -1,32 +0,0 @@
-# SAMPLERATE
-SAMPLERATE_VERSION := 0.1.8
-SAMPLERATE_URL := http://www.mega-nerd.com/SRC/libsamplerate-$(SAMPLERATE_VERSION).tar.gz
-
-PKGS += samplerate
-ifeq ($(call need_pkg,"samplerate"),)
-PKGS_FOUND += samplerate
-endif
-
-$(TARBALLS)/libsamplerate-$(SAMPLERATE_VERSION).tar.gz:
-	$(call download,$(SAMPLERATE_URL))
-
-.sum-samplerate: libsamplerate-$(SAMPLERATE_VERSION).tar.gz
-
-samplerate: libsamplerate-$(SAMPLERATE_VERSION).tar.gz .sum-samplerate
-	$(UNPACK)
-	$(APPLY) $(SRC)/samplerate/disable_tests.patch
-	$(APPLY) $(SRC)/samplerate/soundcard.patch
-	$(APPLY) $(SRC)/samplerate/carbon.patch
-ifdef HAVE_IOS
-ifeq ($(IOS_TARGET_PLATFORM),iPhoneSimulator)
-#warning assembler double / int conversion disabled
-	$(APPLY) $(SRC)/samplerate/disable_assembler.patch
-endif
-endif
-	$(UPDATE_AUTOCONFIG) && cd $(UNPACK_DIR) && mv config.guess config.sub Cfg
-	$(MOVE)
-
-.samplerate: samplerate
-	cd $< && $(HOSTVARS) ./configure $(HOSTCONF)
-	cd $< && $(MAKE) install
-	touch $@
diff --git a/contrib/src/samplerate/samplerate-vs2017.patch b/contrib/src/samplerate/samplerate-vs2017.patch
deleted file mode 100644
index 47d89d5ccb99a8affa40711ee20e1d6069c2f1ae..0000000000000000000000000000000000000000
--- a/contrib/src/samplerate/samplerate-vs2017.patch
+++ /dev/null
@@ -1,218 +0,0 @@
---- /dev/null
-+++ b/msvc/libsamplerate.vcxproj
-@@ -0,0 +1,211 @@
-+<?xml version="1.0" encoding="utf-8"?>
-+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-+  <ItemGroup Label="ProjectConfigurations">
-+    <ProjectConfiguration Include="Debug|Win32">
-+      <Configuration>Debug</Configuration>
-+      <Platform>Win32</Platform>
-+    </ProjectConfiguration>
-+    <ProjectConfiguration Include="Release|Win32">
-+      <Configuration>Release</Configuration>
-+      <Platform>Win32</Platform>
-+    </ProjectConfiguration>
-+    <ProjectConfiguration Include="Debug|x64">
-+      <Configuration>Debug</Configuration>
-+      <Platform>x64</Platform>
-+    </ProjectConfiguration>
-+    <ProjectConfiguration Include="Release|x64">
-+      <Configuration>Release</Configuration>
-+      <Platform>x64</Platform>
-+    </ProjectConfiguration>
-+  </ItemGroup>
-+  <PropertyGroup Label="Globals">
-+    <ProjectGuid>{0DC9504B-4FF5-4590-97B3-FFD4C04F2893}</ProjectGuid>
-+    <RootNamespace>libsamplerate</RootNamespace>
-+    <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
-+  </PropertyGroup>
-+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-+    <ConfigurationType>StaticLibrary</ConfigurationType>
-+    <UseDebugLibraries>true</UseDebugLibraries>
-+    <PlatformToolset>v141</PlatformToolset>
-+    <CharacterSet>MultiByte</CharacterSet>
-+  </PropertyGroup>
-+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-+    <ConfigurationType>StaticLibrary</ConfigurationType>
-+    <UseDebugLibraries>false</UseDebugLibraries>
-+    <PlatformToolset>v141</PlatformToolset>
-+    <WholeProgramOptimization>true</WholeProgramOptimization>
-+    <CharacterSet>MultiByte</CharacterSet>
-+  </PropertyGroup>
-+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-+    <ConfigurationType>StaticLibrary</ConfigurationType>
-+    <UseDebugLibraries>true</UseDebugLibraries>
-+    <PlatformToolset>v141</PlatformToolset>
-+    <CharacterSet>MultiByte</CharacterSet>
-+  </PropertyGroup>
-+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-+    <ConfigurationType>StaticLibrary</ConfigurationType>
-+    <UseDebugLibraries>false</UseDebugLibraries>
-+    <PlatformToolset>v141</PlatformToolset>
-+    <WholeProgramOptimization>true</WholeProgramOptimization>
-+    <CharacterSet>MultiByte</CharacterSet>
-+  </PropertyGroup>
-+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-+  <ImportGroup Label="ExtensionSettings">
-+  </ImportGroup>
-+  <ImportGroup Label="Shared">
-+  </ImportGroup>
-+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-+  </ImportGroup>
-+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-+  </ImportGroup>
-+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-+  </ImportGroup>
-+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-+  </ImportGroup>
-+  <PropertyGroup Label="UserMacros" />
-+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-+    <TargetExt>.lib</TargetExt>
-+    <TargetName>$(ProjectName)d</TargetName>
-+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
-+    <IntDir>$(Platform)\$(Configuration)\</IntDir>
-+  </PropertyGroup>
-+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-+    <TargetExt>.lib</TargetExt>
-+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
-+    <IntDir>$(Platform)\$(Configuration)\</IntDir>
-+  </PropertyGroup>
-+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-+    <TargetExt>.lib</TargetExt>
-+    <TargetName>$(ProjectName)d</TargetName>
-+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
-+  </PropertyGroup>
-+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-+    <TargetExt>.lib</TargetExt>
-+    <OutDir>$(ProjectDir)..\..\..\msvc\</OutDir>
-+  </PropertyGroup>
-+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-+    <ClCompile>
-+      <WarningLevel>Level3</WarningLevel>
-+      <Optimization>Disabled</Optimization>
-+      <SDLCheck>true</SDLCheck>
-+      <DisableSpecificWarnings>4244;4305;</DisableSpecificWarnings>
-+      <ProgramDataBaseFileName>$(OutDir)lib\x86\$(ProjectName).pdb</ProgramDataBaseFileName>
-+    </ClCompile>
-+    <PreBuildEvent>
-+      <Command>copy /y $(ProjectDir)..\Win32\config.h $(ProjectDir)..\src\config.h
-+copy /y $(ProjectDir)..\Win32\unistd.h $(ProjectDir)..\examples\unistd.h</Command>
-+    </PreBuildEvent>
-+    <PostBuildEvent>
-+      <Command>mkdir "$(OutDir)"include
-+
-+xcopy /s /y $(ProjectDir)..\src\*.h "$(OutDir)"include
-+</Command>
-+    </PostBuildEvent>
-+    <Lib>
-+      <OutputFile>$(OutDir)lib\x86\$(TargetName)$(TargetExt)</OutputFile>
-+    </Lib>
-+  </ItemDefinitionGroup>
-+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-+    <ClCompile>
-+      <WarningLevel>Level3</WarningLevel>
-+      <Optimization>Disabled</Optimization>
-+      <SDLCheck>true</SDLCheck>
-+      <DisableSpecificWarnings>4244;4305;</DisableSpecificWarnings>
-+      <ProgramDataBaseFileName>$(OutDir)lib\x64\$(ProjectName).pdb</ProgramDataBaseFileName>
-+    </ClCompile>
-+    <PreBuildEvent>
-+      <Command>copy /y $(ProjectDir)..\Win32\config.h $(ProjectDir)..\src\config.h
-+copy /y $(ProjectDir)..\Win32\unistd.h $(ProjectDir)..\examples\unistd.h</Command>
-+    </PreBuildEvent>
-+    <PostBuildEvent>
-+      <Command>mkdir "$(OutDir)"include
-+
-+xcopy /s /y $(ProjectDir)..\src\*.h "$(OutDir)"include
-+</Command>
-+    </PostBuildEvent>
-+    <Lib>
-+      <OutputFile>$(OutDir)lib\x64\$(TargetName)$(TargetExt)</OutputFile>
-+    </Lib>
-+  </ItemDefinitionGroup>
-+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-+    <ClCompile>
-+      <WarningLevel>Level3</WarningLevel>
-+      <Optimization>MaxSpeed</Optimization>
-+      <FunctionLevelLinking>true</FunctionLevelLinking>
-+      <IntrinsicFunctions>true</IntrinsicFunctions>
-+      <SDLCheck>true</SDLCheck>
-+      <DisableSpecificWarnings>4244;4305;</DisableSpecificWarnings>
-+      <WholeProgramOptimization>false</WholeProgramOptimization>
-+      <ProgramDataBaseFileName>$(OutDir)lib\x86\$(ProjectName).pdb</ProgramDataBaseFileName>
-+    </ClCompile>
-+    <Link>
-+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-+      <OptimizeReferences>true</OptimizeReferences>
-+    </Link>
-+    <PostBuildEvent>
-+      <Command>mkdir "$(OutDir)"include
-+
-+xcopy /s /y $(ProjectDir)..\src\*.h "$(OutDir)"include
-+</Command>
-+    </PostBuildEvent>
-+    <PreBuildEvent>
-+      <Command>copy /y $(ProjectDir)..\Win32\config.h $(ProjectDir)..\src\config.h
-+copy /y $(ProjectDir)..\Win32\unistd.h $(ProjectDir)..\examples\unistd.h</Command>
-+    </PreBuildEvent>
-+    <Lib>
-+      <OutputFile>$(OutDir)lib\x86\$(TargetName)$(TargetExt)</OutputFile>
-+    </Lib>
-+  </ItemDefinitionGroup>
-+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-+    <ClCompile>
-+      <WarningLevel>Level3</WarningLevel>
-+      <Optimization>MaxSpeed</Optimization>
-+      <FunctionLevelLinking>true</FunctionLevelLinking>
-+      <IntrinsicFunctions>true</IntrinsicFunctions>
-+      <SDLCheck>true</SDLCheck>
-+      <DisableSpecificWarnings>4244;4305;</DisableSpecificWarnings>
-+      <WholeProgramOptimization>false</WholeProgramOptimization>
-+      <ProgramDataBaseFileName>$(OutDir)lib\x64\$(ProjectName).pdb</ProgramDataBaseFileName>
-+    </ClCompile>
-+    <Link>
-+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-+      <OptimizeReferences>true</OptimizeReferences>
-+    </Link>
-+    <PostBuildEvent>
-+      <Command>mkdir "$(OutDir)"include
-+
-+xcopy /s /y $(ProjectDir)..\src\*.h "$(OutDir)"include
-+</Command>
-+    </PostBuildEvent>
-+    <PreBuildEvent>
-+      <Command>copy /y $(ProjectDir)..\Win32\config.h $(ProjectDir)..\src\config.h
-+copy /y $(ProjectDir)..\Win32\unistd.h $(ProjectDir)..\examples\unistd.h</Command>
-+    </PreBuildEvent>
-+    <Lib>
-+      <OutputFile>$(OutDir)lib\x64\$(TargetName)$(TargetExt)</OutputFile>
-+    </Lib>
-+  </ItemDefinitionGroup>
-+  <ItemGroup>
-+    <ClCompile Include="..\src\samplerate.c" />
-+    <ClCompile Include="..\src\src_linear.c" />
-+    <ClCompile Include="..\src\src_sinc.c" />
-+    <ClCompile Include="..\src\src_zoh.c" />
-+  </ItemGroup>
-+  <ItemGroup>
-+    <ClInclude Include="..\src\common.h" />
-+    <ClInclude Include="..\src\config.h" />
-+    <ClInclude Include="..\src\fastest_coeffs.h" />
-+    <ClInclude Include="..\src\float_cast.h" />
-+    <ClInclude Include="..\src\high_qual_coeffs.h" />
-+    <ClInclude Include="..\src\mid_qual_coeffs.h" />
-+    <ClInclude Include="..\src\samplerate.h" />
-+  </ItemGroup>
-+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-+  <ImportGroup Label="ExtensionTargets">
-+  </ImportGroup>
-+</Project>
-\ No newline at end of file
--- 
-2.10.2.windows.1
-
diff --git a/contrib/src/samplerate/soundcard.patch b/contrib/src/samplerate/soundcard.patch
deleted file mode 100644
index af2de623aa0333fa821685caa667661d635923a1..0000000000000000000000000000000000000000
--- a/contrib/src/samplerate/soundcard.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- a/examples/audio_out.c.orig	2014-06-18 16:52:04.269479958 -0400
-+++ b/examples/audio_out.c	2014-06-18 16:52:36.789478998 -0400
-@@ -44,7 +44,11 @@
- 
- #include <fcntl.h>
- #include <sys/ioctl.h>
-+#if defined (__ANDROID__)
-+#include <linux/soundcard.h>
-+#else
- #include <sys/soundcard.h>
-+#endif
- 
- #define	LINUX_MAGIC		MAKE_MAGIC ('L', 'i', 'n', 'u', 'x', 'O', 'S', 'S')
- 
diff --git a/docker/Dockerfile_ubuntu_16.04 b/docker/Dockerfile_ubuntu_16.04
index 488626fa66ea5951e2b2fa994a1cd326e935bd96..bbe82bce7328d668a73795a9d7ad93a0dd62460f 100644
--- a/docker/Dockerfile_ubuntu_16.04
+++ b/docker/Dockerfile_ubuntu_16.04
@@ -26,7 +26,6 @@ RUN apt-get update && \
         autotools-dev \
         gettext \
         libpulse-dev \
-        libsamplerate0-dev \
         libasound2-dev \
         libexpat1-dev \
         libpcre3-dev \
diff --git a/src/Makefile.am b/src/Makefile.am
index 82e8c894ea409a3b35dd77e6e688bbdf6a475e6c..6b27a5ea822b2a7cd5a2c645c7c1eedff7fec60d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -49,7 +49,6 @@ libring_la_LDFLAGS = \
 		@PJPROJECT_LIBS@ \
 		@ALSA_LIBS@ \
 		@PULSEAUDIO_LIBS@ \
-		@SAMPLERATE_LIBS@ \
 		@YAMLCPP_LIBS@ \
 		@JSONCPP_LIBS@ \
 		@SPEEXDSP_LIBS@ \
@@ -77,7 +76,6 @@ libring_la_CFLAGS = \
 		@PJPROJECT_CFLAGS@ \
 		@ALSA_CFLAGS@ \
 		@PULSEAUDIO_CFLAGS@ \
-		@SAMPLERATE_CFLAGS@ \
 		@LIBUPNP_CFLAGS@ \
 		@SPEEXDSP_CFLAGS@ \
 		@PORTAUDIO_CFLAGS@ \
diff --git a/src/media/audio/resampler.cpp b/src/media/audio/resampler.cpp
index 23ec14f30f57c92c85d4fa8255dda32b68924db9..c02285f6c30e79b7b4ffac13e775d5f8bc74b244 100644
--- a/src/media/audio/resampler.cpp
+++ b/src/media/audio/resampler.cpp
@@ -19,109 +19,82 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
  */
 
-#include "resampler.h"
 #include "logger.h"
+#include "media_filter.h"
+#include "media_stream.h"
+#include "resampler.h"
 #include "ring_types.h"
 
-#include <samplerate.h>
-
 namespace ring {
 
-class SrcState {
-    public:
-        SrcState(int nb_channels, bool high_quality = false)
-        {
-            int err;
-            state_ = src_new(high_quality ? SRC_SINC_BEST_QUALITY : SRC_LINEAR, nb_channels, &err);
-        }
-
-        ~SrcState()
-        {
-            src_delete(state_);
-        }
-
-        void process(SRC_DATA *src_data)
-        {
-            src_process(state_, src_data);
-        }
-
-    private:
-        SRC_STATE *state_ {nullptr};
-};
-
-Resampler::Resampler(AudioFormat format, bool quality) : floatBufferIn_(),
-    floatBufferOut_(), scratchBuffer_(), samples_(0), format_(format), high_quality_(quality), src_state_()
+Resampler::Resampler(AudioFormat format)
+    : format_(format)
 {
-    setFormat(format, quality);
+    setFormat(format);
 }
 
-Resampler::Resampler(unsigned sample_rate, unsigned channels, bool quality) : floatBufferIn_(),
-    floatBufferOut_(), scratchBuffer_(), samples_(0), format_(sample_rate, channels), high_quality_(quality), src_state_()
+Resampler::Resampler(unsigned sample_rate, unsigned channels)
+    : format_(sample_rate, channels)
 {
-    setFormat(format_, quality);
+    setFormat(format_);
 }
 
 Resampler::~Resampler() = default;
 
 void
-Resampler::setFormat(AudioFormat format, bool quality)
+Resampler::reinitFilter(const MediaStream& inputParams)
 {
-    format_ = format;
-    samples_ = (format.nb_channels * format.sample_rate * 20) / 1000; // start with 20 ms buffers
-    floatBufferIn_.resize(samples_);
-    floatBufferOut_.resize(samples_);
-    scratchBuffer_.resize(samples_);
+    filter_.reset(new MediaFilter());
+    std::stringstream aformat;
+    aformat << "aformat=sample_fmts=s16:channel_layouts="
+        << av_get_default_channel_layout(format_.nb_channels)
+        << ":sample_rates=" << format_.sample_rate;
+    if (filter_->initialize(aformat.str(), inputParams) < 0) {
+        RING_ERR() << "Failed to initialize resampler";
+        filter_.reset();
+    }
+}
 
-    src_state_.reset(new SrcState(format.nb_channels, quality));
+void
+Resampler::setFormat(AudioFormat format)
+{
+    format_ = format;
+    if (filter_)
+        reinitFilter(filter_->getInputParams());
 }
 
-void Resampler::resample(const AudioBuffer &dataIn, AudioBuffer &dataOut)
+void
+Resampler::resample(const AudioBuffer& dataIn, AudioBuffer& dataOut)
 {
-    const double inputFreq = dataIn.getSampleRate();
-    const double outputFreq = dataOut.getSampleRate();
-    const double sampleFactor = outputFreq / inputFreq;
+    auto input = dataIn.toAVFrame();
+    MediaStream currentParams("resampler", static_cast<AVSampleFormat>(input->format),
+        0, input->sample_rate, input->channels);
+    if (filter_) {
+        const auto& ms = filter_->getInputParams();
+        if (ms.sampleRate != input->sample_rate || ms.nbChannels != input->channels) {
+            RING_WARN() << "Resampler settings changed, reinitializing";
+            reinitFilter(currentParams);
+        }
+    } else {
+        reinitFilter(currentParams);
+    }
 
-    if (sampleFactor == 1.0)
+    auto frame = filter_->apply(input);
+    av_frame_free(&input);
+    if (!frame) {
+        RING_ERR() << "Resampling failed, this may produce a glitch in the audio";
         return;
-
-    const size_t nbFrames = dataIn.frames();
-    const size_t nbChans = dataIn.channels();
-
-    if (nbChans != format_.nb_channels) {
-        // change channel num if needed
-        src_state_.reset(new SrcState(nbChans, high_quality_));
-        format_.nb_channels = nbChans;
-        RING_DBG("SRC channel number changed.");
-    }
-    if (nbChans != dataOut.channels()) {
-        RING_DBG("Output buffer had the wrong number of channels (in: %zu, out: %u).", nbChans, dataOut.channels());
-        dataOut.setChannelNum(nbChans);
     }
 
-    size_t inSamples = nbChans * nbFrames;
-    size_t outSamples = inSamples * sampleFactor;
-
-    // grow buffer if needed
-    floatBufferIn_.resize(inSamples);
-    floatBufferOut_.resize(outSamples);
-    scratchBuffer_.resize(outSamples);
-
-    SRC_DATA src_data;
-    src_data.data_in = floatBufferIn_.data();
-    src_data.data_out = floatBufferOut_.data();
-    src_data.input_frames = nbFrames;
-    src_data.output_frames = nbFrames * sampleFactor;
-    src_data.src_ratio = sampleFactor;
-    src_data.end_of_input = 0; // More data will come
-
-    dataIn.interleaveFloat(floatBufferIn_.data());
-
-    src_state_->process(&src_data);
-    /*
-    TODO: one-shot deinterleave and float-to-short conversion
-    */
-    src_float_to_short_array(floatBufferOut_.data(), scratchBuffer_.data(), outSamples);
-    dataOut.deinterleave(scratchBuffer_.data(), src_data.output_frames, nbChans);
+    dataOut.setFormat(format_);
+    dataOut.resize(frame->nb_samples);
+    if (static_cast<AVSampleFormat>(frame->format) == AV_SAMPLE_FMT_FLTP)
+        dataOut.convertFloatPlanarToSigned16(frame->extended_data,
+            frame->nb_samples, frame->channels);
+    else if (static_cast<AVSampleFormat>(frame->format) == AV_SAMPLE_FMT_S16)
+        dataOut.deinterleave(reinterpret_cast<const AudioSample*>(frame->extended_data[0]),
+            frame->nb_samples, frame->channels);
+    av_frame_free(&frame);
 }
 
 } // namespace ring
diff --git a/src/media/audio/resampler.h b/src/media/audio/resampler.h
index 00d50e965f663e38fc1ece3efe0e1430d4d4fed9..57e9d01ac9c24622d938bcecf3135bb7e7d9ba06 100644
--- a/src/media/audio/resampler.h
+++ b/src/media/audio/resampler.h
@@ -19,20 +19,18 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
  */
 
-#ifndef _SAMPLE_RATE_H
-#define _SAMPLE_RATE_H
+#pragma once
 
-#include <cmath>
-#include <cstring>
 #include <memory>
 
 #include "audiobuffer.h"
-#include "ring_types.h"
 #include "noncopyable.h"
+#include "ring_types.h"
 
 namespace ring {
 
-class SrcState;
+class MediaFilter;
+struct MediaStream;
 
 class Resampler {
     public:
@@ -43,8 +41,8 @@ class Resampler {
         * internal buffer size. Resampler must be reinitialized
         * every time these parameters change
         */
-        Resampler(AudioFormat outFormat, bool quality = false);
-        Resampler(unsigned sample_rate, unsigned channels=1, bool quality = false);
+        Resampler(AudioFormat outFormat);
+        Resampler(unsigned sample_rate, unsigned channels=1);
         // empty dtor, needed for unique_ptr
         ~Resampler();
 
@@ -52,31 +50,22 @@ class Resampler {
          * Change the converter sample rate and channel number.
          * Internal state is lost.
          */
-        void setFormat(AudioFormat format, bool quality = false);
+        void setFormat(AudioFormat format);
 
         /**
          * resample from the samplerate1 to the samplerate2
-         * @param dataIn  Input buffer
+         * @param dataIn Input buffer
          * @param dataOut Output buffer
-         * @param nbSamples	  The number of samples to process
          */
         void resample(const AudioBuffer& dataIn, AudioBuffer& dataOut);
 
     private:
         NON_COPYABLE(Resampler);
 
-        /* temporary buffers */
-        std::vector<float> floatBufferIn_;
-        std::vector<float> floatBufferOut_;
-        std::vector<AudioSample> scratchBuffer_;
+        void reinitFilter(const MediaStream& inputParams);
 
-        size_t samples_; // size in samples of temporary buffers
         AudioFormat format_; // number of channels and max output frequency
-        bool high_quality_;
-
-        std::unique_ptr<SrcState> src_state_;
+        std::unique_ptr<MediaFilter> filter_;
 };
 
 } // namespace ring
-
-#endif //_SAMPLE_RATE_H
diff --git a/src/media/audio/sound/audiofile.cpp b/src/media/audio/sound/audiofile.cpp
index 34297863701a622390c89f161616534a88181983..ae172cf341996cc96f3397edaea5f9d966783fe3 100644
--- a/src/media/audio/sound/audiofile.cpp
+++ b/src/media/audio/sound/audiofile.cpp
@@ -22,7 +22,6 @@
  */
 #include <fstream>
 #include <cmath>
-#include <samplerate.h>
 #include <cstring>
 #include <vector>
 #include <climits>
diff --git a/test/unitTest/Makefile.am b/test/unitTest/Makefile.am
index d4d63298ee1f36d8c25a5083577806bdc9f55f99..d3b7e39cac62d02a56b80dc25c53f4498e28d712 100644
--- a/test/unitTest/Makefile.am
+++ b/test/unitTest/Makefile.am
@@ -70,7 +70,7 @@ ut_media_encoder_SOURCES = media/test_media_encoder.cpp
 #
 # media_decoder
 #
-check_PROGRAMS += ut_media_decoder # no reliable way to get a file
+check_PROGRAMS += ut_media_decoder
 ut_media_decoder_SOURCES = media/test_media_decoder.cpp
 
 #
@@ -79,4 +79,10 @@ ut_media_decoder_SOURCES = media/test_media_decoder.cpp
 check_PROGRAMS += ut_media_filter
 ut_media_filter_SOURCES = media/test_media_filter.cpp
 
+#
+# resampler
+#
+check_PROGRAMS += ut_resampler
+ut_resampler_SOURCES = media/audio/test_resampler.cpp
+
 TESTS = $(check_PROGRAMS)
diff --git a/test/unitTest/media/audio/test_resampler.cpp b/test/unitTest/media/audio/test_resampler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..503f43312ff67a5af0098c1f4a0529d540b58a2e
--- /dev/null
+++ b/test/unitTest/media/audio/test_resampler.cpp
@@ -0,0 +1,88 @@
+/*
+ *  Copyright (C) 2018 Savoir-faire Linux Inc.
+ *
+ *  Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "dring.h"
+#include "libav_deps.h"
+#include "audio/resampler.h"
+
+#include "../test_runner.h"
+
+namespace ring { namespace test {
+
+class ResamplerTest : public CppUnit::TestFixture {
+public:
+    static std::string name() { return "resampler"; }
+
+    void setUp();
+    void tearDown();
+
+private:
+    void testResample();
+
+    CPPUNIT_TEST_SUITE(ResamplerTest);
+    CPPUNIT_TEST(testResample);
+    CPPUNIT_TEST_SUITE_END();
+
+    void writeWav(); // writes a minimal wav file to test decoding
+
+    std::unique_ptr<Resampler> resampler_;
+};
+
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ResamplerTest, ResamplerTest::name());
+
+void
+ResamplerTest::setUp()
+{
+    DRing::init(DRing::InitFlag(DRing::DRING_FLAG_DEBUG | DRing::DRING_FLAG_CONSOLE_LOG));
+    libav_utils::ring_avcodec_init();
+}
+
+void
+ResamplerTest::tearDown()
+{
+    DRing::fini();
+}
+
+void
+ResamplerTest::testResample()
+{
+    const constexpr AudioFormat none(0, 0);
+    const constexpr AudioFormat infmt(44100, 1);
+    const constexpr AudioFormat outfmt(48000, 2);
+
+    resampler_.reset(new Resampler(none));
+
+    resampler_->setFormat(outfmt);
+
+    AudioBuffer inbuf(1024, infmt);
+    AudioBuffer outbuf;
+
+    resampler_->resample(inbuf, outbuf);
+    CPPUNIT_ASSERT(outbuf.getFormat().sample_rate == 48000);
+    CPPUNIT_ASSERT(outbuf.getFormat().nb_channels == 2);
+}
+
+}} // namespace ring::test
+
+RING_TEST_RUNNER(ring::test::ResamplerTest::name());