mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-07 22:02:12 +08:00
audio: remove libsamplerate dependency
Rewrites the Resampler class to use MediaFilter. Adds a unit test for the new Resampler. Change-Id: I8ed78d2e1d82df81bbaf46a9719c682c825ee245
This commit is contained in:

committed by
Adrien Béraud

parent
834e835dee
commit
e3022741bd
@ -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]))
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
85d93df24d9d62e7803a5d0ac5d268b2085214adcb160e32fac316b12ee8a0ce36ccfb433a3c0a08f6e3ec418a5962bdb84f8a11262286a9b347436983029a7d libsamplerate-0.1.8.tar.gz
|
@ -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')
|
@ -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 */
|
||||
-
|
@ -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
|
||||
|
@ -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%
|
@ -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 $@
|
@ -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
|
||||
|
@ -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')
|
||||
|
@ -26,7 +26,6 @@ RUN apt-get update && \
|
||||
autotools-dev \
|
||||
gettext \
|
||||
libpulse-dev \
|
||||
libsamplerate0-dev \
|
||||
libasound2-dev \
|
||||
libexpat1-dev \
|
||||
libpcre3-dev \
|
||||
|
@ -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@ \
|
||||
|
@ -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_);
|
||||
|
||||
src_state_.reset(new SrcState(format.nb_channels, quality));
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
void Resampler::resample(const AudioBuffer &dataIn, AudioBuffer &dataOut)
|
||||
void
|
||||
Resampler::setFormat(AudioFormat format)
|
||||
{
|
||||
const double inputFreq = dataIn.getSampleRate();
|
||||
const double outputFreq = dataOut.getSampleRate();
|
||||
const double sampleFactor = outputFreq / inputFreq;
|
||||
format_ = format;
|
||||
if (filter_)
|
||||
reinitFilter(filter_->getInputParams());
|
||||
}
|
||||
|
||||
if (sampleFactor == 1.0)
|
||||
void
|
||||
Resampler::resample(const AudioBuffer& dataIn, AudioBuffer& dataOut)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -22,7 +22,6 @@
|
||||
*/
|
||||
#include <fstream>
|
||||
#include <cmath>
|
||||
#include <samplerate.h>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include <climits>
|
||||
|
@ -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)
|
||||
|
88
test/unitTest/media/audio/test_resampler.cpp
Normal file
88
test/unitTest/media/audio/test_resampler.cpp
Normal file
@ -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());
|
Reference in New Issue
Block a user