audiolayer: use Speex AEC

Change-Id: Ieb36dc5b97e8a451160b59079353c82f07d049be
This commit is contained in:
Adrien Béraud
2020-02-26 11:02:46 -05:00
parent 1a78baf930
commit 3b1f043633
30 changed files with 859 additions and 237 deletions

View File

@ -135,12 +135,12 @@ if(MSVC)
"${CMAKE_CURRENT_SOURCE_DIR}/src/jamidht;"
"${CMAKE_CURRENT_SOURCE_DIR}/src/security;"
"${CMAKE_CURRENT_SOURCE_DIR}/src/sip;"
"${CMAKE_CURRENT_SOURCE_DIR}/compat/msvc;"
"${CMAKE_CURRENT_SOURCE_DIR}/src/upnp;"
"${CMAKE_CURRENT_SOURCE_DIR}/src/upnp/igd;"
"${CMAKE_CURRENT_SOURCE_DIR}/src/upnp/protocol;"
"${CMAKE_CURRENT_SOURCE_DIR}/src/upnp/mapping;"
"${CMAKE_CURRENT_SOURCE_DIR}/src/jamidht/eth;"
"${CMAKE_CURRENT_SOURCE_DIR}/compat/msvc;"
"${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc;"
"${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/include;"
"${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/msgpack-c/include;"
@ -152,6 +152,7 @@ if(MSVC)
"${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/include;"
"${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/third_party;"
"${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjmedia/include"
"${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/speexdsp/include;"
)
endif()
@ -224,39 +225,40 @@ if(MSVC)
# Dependencies
################################################################################
set(libAdditionalDependencies "${CMAKE_STATIC_LINKER_FLAGS} /LTCG ws2_32.lib
advapi32.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avcodec.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avdevice.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avfilter.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avformat.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avutil.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/swresample.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/swscale.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/libgnutls.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/lib_json.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/libopendht.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/argon2/vs2015/Argon2Ref/vs2015/build/Argon2Ref.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/secp256k1.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/yaml-cpp/msvc/Release/libyaml-cppmd.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/portaudio.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/libupnp.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/natpmp/msvc/Release/natpmp.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsip-core-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsip-simple-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsua2-lib-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsua-lib-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsip-ua-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjmedia/lib/pjmedia-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjlib-util/lib/pjlib-util-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjlib/lib/pjlib-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjnath/lib/pjnath-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/fmt/msvc/Release/fmt.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/http_parser/x64/Release/http-parser.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/asio/asio/msvc/x64/Release/asio.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/openssl/out32dll/libeay32.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/openssl/out32dll/ssleay32.lib
/ignore:4006
set(libAdditionalDependencies "${CMAKE_STATIC_LINKER_FLAGS} /LTCG ws2_32.lib
advapi32.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avcodec.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avdevice.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avfilter.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avformat.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/avutil.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/swresample.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/ffmpeg/Build/win32/x64/bin/swscale.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/libgnutls.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/lib_json.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/libopendht.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/argon2/vs2015/Argon2Ref/vs2015/build/Argon2Ref.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/secp256k1.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/yaml-cpp/msvc/Release/libyaml-cppmd.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/portaudio.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/msvc/lib/x64/libupnp.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/natpmp/msvc/Release/natpmp.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsip-core-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsip-simple-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsua2-lib-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsua-lib-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjsip/lib/pjsip-ua-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjmedia/lib/pjmedia-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjlib-util/lib/pjlib-util-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjlib/lib/pjlib-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/pjproject/pjnath/lib/pjnath-x86_64-x64-vc15-Release.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/fmt/msvc/Release/fmt.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/http_parser/x64/Release/http-parser.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/asio/asio/msvc/x64/Release/asio.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/openssl/out32dll/libeay32.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/openssl/out32dll/ssleay32.lib
${CMAKE_CURRENT_SOURCE_DIR}/contrib/build/speexdsp/lib/libspeexdsp.lib
/ignore:4006
"
)

View File

@ -8,9 +8,10 @@
"pjproject",
"portaudio",
"secp256k1",
"speexdsp",
"upnp",
"yaml-cpp"
],
"configuration": "ReleaseLib_win32",
"project_paths": ["ring-daemon.vcxproj"]
}
}

View File

@ -0,0 +1,15 @@
{
"name": "speexdsp",
"version": "SpeexDSP-1.2.0",
"url": "https://github.com/xiph/speexdsp/archive/__VERSION__.tar.gz",
"deps": [],
"patches": ["speexdsp_vs_proj.patch"],
"win_patches": [],
"project_paths": ["win32/msvc/libspeexdsp/libspeexdsp.vcxproj"],
"with_env" : "",
"custom_scripts": {
"pre_build": [],
"build": [],
"post_build": []
}
}

View File

@ -0,0 +1,398 @@
From ba88ffed7a018d37661c9574f98f4246cdf6031c Mon Sep 17 00:00:00 2001
From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
Date: Wed, 19 Feb 2020 16:14:02 -0500
Subject: [PATCH] b
---
win32/msvc/libspeexdsp/libspeexdsp.vcxproj | 378 +++++++++++++++++++++++++++++
1 file changed, 378 insertions(+)
create mode 100644 win32/msvc/libspeexdsp/libspeexdsp.vcxproj
diff --git a/win32/msvc/libspeexdsp/libspeexdsp.vcxproj b/win32/msvc/libspeexdsp/libspeexdsp.vcxproj
new file mode 100644
index 0000000..071c9b3
--- /dev/null
+++ b/win32/msvc/libspeexdsp/libspeexdsp.vcxproj
@@ -0,0 +1,378 @@
+<?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="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_Dynamic_SSE|Win32">
+ <Configuration>Release_Dynamic_SSE</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_Dynamic_SSE|x64">
+ <Configuration>Release_Dynamic_SSE</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_Static_SSE|Win32">
+ <Configuration>Release_Static_SSE</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release_Static_SSE|x64">
+ <Configuration>Release_Static_SSE</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{03207781-0D1C-4DB3-A71D-45C608F28DBD}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>15.0.28127.55</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>Debug\</OutDir>
+ <IntDir>Debug\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(Configuration)\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|Win32'">
+ <OutDir>$(Configuration)\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|Win32'">
+ <OutDir>$(Configuration)\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <CompileAs>CompileAsC</CompileAs>
+ </ClCompile>
+ <Lib>
+ <OutputFile>../../../lib/libspeexdsp.lib</OutputFile>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>CompileAsC</CompileAs>
+ </ClCompile>
+ <Lib>
+ <OutputFile>../../../lib/libspeexdsp.lib</OutputFile>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling />
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>CompileAsC</CompileAs>
+ <DisableSpecificWarnings>4244;4305;4311;4100;4127;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Lib>
+ <OutputFile>../../../lib/libspeexdsp.lib</OutputFile>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>CompileAsC</CompileAs>
+ <DisableSpecificWarnings>4244;4305;4311;4100;4127;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Lib>
+ <OutputFile>../../../lib/libspeexdsp.lib</OutputFile>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling />
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>CompileAsC</CompileAs>
+ <DisableSpecificWarnings>4244;4305;4311;4100;4127;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <OutputFile>../../../bin/libspeexdsp.dll</OutputFile>
+ <ModuleDefinitionFile>..\..\libspeexdsp.def</ModuleDefinitionFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention />
+ <ImportLibrary>../../../lib/libspeexdsp.lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Dynamic_SSE|x64'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>CompileAsC</CompileAs>
+ <DisableSpecificWarnings>4244;4305;4311;4100;4127;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <OutputFile>../../../bin/libspeexdsp.dll</OutputFile>
+ <ModuleDefinitionFile>..\..\libspeexdsp.def</ModuleDefinitionFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <DataExecutionPrevention>
+ </DataExecutionPrevention>
+ <ImportLibrary>../../../lib/libspeexdsp.lib</ImportLibrary>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|Win32'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling />
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>CompileAsC</CompileAs>
+ <DisableSpecificWarnings>4244;4305;4311;4100;4127;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Lib>
+ <OutputFile>../../../lib/libspeexdsp.lib</OutputFile>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_Static_SSE|x64'">
+ <ClCompile>
+ <Optimization>Full</Optimization>
+ <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>..\..\..\include;..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>USE_SSE;WIN32;NDEBUG;_WINDOWS;_USRDLL;HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>false</BufferSecurityCheck>
+ <EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <CompileAs>CompileAsC</CompileAs>
+ <DisableSpecificWarnings>4244;4305;4311;4100;4127;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Lib>
+ <OutputFile>../../../lib/libspeexdsp.lib</OutputFile>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\libspeexdsp\buffer.c" />
+ <ClCompile Include="..\..\..\libspeexdsp\fftwrap.c" />
+ <ClCompile Include="..\..\..\libspeexdsp\filterbank.c" />
+ <ClCompile Include="..\..\..\libspeexdsp\jitter.c" />
+ <ClCompile Include="..\..\..\libspeexdsp\kiss_fft.c" />
+ <ClCompile Include="..\..\..\libspeexdsp\kiss_fftr.c" />
+ <ClCompile Include="..\..\..\libspeexdsp\mdf.c" />
+ <ClCompile Include="..\..\..\libspeexdsp\preprocess.c" />
+ <ClCompile Include="..\..\..\libspeexdsp\resample.c" />
+ <ClCompile Include="..\..\..\libspeexdsp\scal.c" />
+ <ClCompile Include="..\..\..\libspeexdsp\smallft.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\include\speex\speex.h" />
+ <ClInclude Include="..\..\..\include\speex\speex_bits.h" />
+ <ClInclude Include="..\..\..\include\speex\speex_buffer.h" />
+ <ClInclude Include="..\..\..\include\speex\speex_echo.h" />
+ <ClInclude Include="..\..\..\include\speex\speex_jitter.h" />
+ <ClInclude Include="..\..\..\include\speex\speex_preprocess.h" />
+ <ClInclude Include="..\..\..\include\speex\speex_resampler.h" />
+ <ClInclude Include="..\..\..\include\speex\speex_types.h" />
+ <ClInclude Include="..\..\..\libspeexdsp\arch.h" />
+ <ClInclude Include="..\..\..\libspeexdsp\fftwrap.h" />
+ <ClInclude Include="..\..\..\libspeexdsp\filterbank.h" />
+ <ClInclude Include="..\..\..\libspeexdsp\fixed_debug.h" />
+ <ClInclude Include="..\..\..\libspeexdsp\fixed_generic.h" />
+ <ClInclude Include="..\..\..\libspeexdsp\kiss_fft.h" />
+ <ClInclude Include="..\..\..\libspeexdsp\kiss_fftr.h" />
+ <ClInclude Include="..\..\..\libspeexdsp\math_approx.h" />
+ <ClInclude Include="..\..\..\libspeexdsp\os_support.h" />
+ <ClInclude Include="..\..\..\libspeexdsp\pseudofloat.h" />
+ <ClInclude Include="..\..\..\libspeexdsp\smallft.h" />
+ <ClInclude Include="..\..\..\libspeexdsp\_kiss_fft_guts.h" />
+ <ClInclude Include="..\..\config.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\libspeexdsp.def" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
--
2.7.4

View File

@ -107,6 +107,22 @@ AudioFrame::setFormat(const jami::AudioFormat& format)
d->format = format.sampleFormat;
}
jami::AudioFormat
AudioFrame::getFormat() const
{
return {
(unsigned)frame_->sample_rate,
(unsigned)frame_->channels,
(AVSampleFormat)frame_->format
};
}
size_t
AudioFrame::getFrameSize() const
{
return frame_->nb_samples;
}
void
AudioFrame::reserve(size_t nb_samples)
{

View File

@ -107,6 +107,8 @@ public:
~AudioFrame() {};
void mix(const AudioFrame& o);
float calcRMS() const;
jami::AudioFormat getFormat() const;
size_t getFrameSize() const;
private:
void setFormat(const jami::AudioFormat& format);

View File

@ -99,7 +99,6 @@ AlsaLayer::AlsaLayer(const AudioPreference &pref)
, is_playback_open_(false)
, is_capture_open_(false)
, audioThread_(nullptr)
, mainRingBuffer_(Manager::instance().getRingBufferPool().getRingBuffer(RingBufferPool::DEFAULT_ID))
{}
AlsaLayer::~AlsaLayer()
@ -702,10 +701,7 @@ void AlsaLayer::capture()
const int framesPerBufferAlsa = 2048;
toGetFrames = std::min(framesPerBufferAlsa, toGetFrames);
if (auto r = read(toGetFrames)) {
if (isCaptureMuted_)
libav_utils::fillWithSilence(r->pointer());
//dcblocker_.process(captureBuff_);
mainRingBuffer_->put(std::move(r));
putRecorded(std::move(r));
} else
JAMI_ERR("ALSA MIC : Couldn't read!");
}

View File

@ -250,7 +250,6 @@ class AlsaLayer : public AudioLayer {
bool is_capture_open_;
std::unique_ptr<AlsaThread> audioThread_;
std::shared_ptr<RingBuffer> mainRingBuffer_;
};
} // namespace jami

View File

@ -123,7 +123,7 @@ AudioFrameResizer::dequeue()
if (samples() < frameSize_)
return {};
auto frame = std::make_unique<AudioFrame>(format_, frameSize_);
auto frame = std::make_shared<AudioFrame>(format_, frameSize_);
int ret;
if ((ret = av_audio_fifo_read(queue_, reinterpret_cast<void**>(frame->pointer()->data), frameSize_)) < 0) {
JAMI_ERR() << "Could not read samples from queue: " << libav_utils::getError(ret);

View File

@ -323,7 +323,7 @@ AudioInput::createDecoder()
}
auto decoder = std::make_unique<MediaDecoder>([this](std::shared_ptr<MediaFrame>&& frame) {
fileBuf_->put(std::move(std::static_pointer_cast<AudioFrame>(frame)));
fileBuf_->put(std::static_pointer_cast<AudioFrame>(frame));
});
// NOTE don't emulate rate, file is read as frames are needed

View File

@ -59,7 +59,7 @@ AudioReceiveThread::setup()
{
audioDecoder_.reset(new MediaDecoder([this](std::shared_ptr<MediaFrame>&& frame) mutable {
notify(frame);
ringbuffer_->put(std::move(std::static_pointer_cast<AudioFrame>(frame)));
ringbuffer_->put(std::static_pointer_cast<AudioFrame>(frame));
}));
audioDecoder_->setInterruptCallback(interruptCb, this);

View File

@ -28,21 +28,88 @@
#include "tonecontrol.h"
#include "client/ring_signal.h"
extern "C" {
#include <speex/speex_echo.h>
}
#include <ctime>
#include <algorithm>
namespace jami {
struct AudioLayer::EchoState
{
EchoState(AudioFormat format, unsigned frameSize, unsigned tailLength)
: state(speex_echo_state_init_mc(
frameSize, frameSize * 16,
format.nb_channels, format.nb_channels), &speex_echo_state_destroy)
, playbackQueue(format, frameSize)
, recordQueue(format, frameSize) {
int sr = format.sample_rate;
speex_echo_ctl(state.get(), SPEEX_ECHO_SET_SAMPLING_RATE, &sr);
}
void putRecorded(std::shared_ptr<AudioFrame>&& in) {
// JAMI_DBG("putRecorded %s %d", in->getFormat().toString().c_str(), in->getFrameSize());
recordQueue.enqueue(std::move(in));
}
void putPlayback(const std::shared_ptr<AudioFrame>& in) {
// JAMI_DBG("putPlayback %s %d", in->getFormat().toString().c_str(), in->getFrameSize());
auto c = in;
playbackQueue.enqueue(std::move(c));
}
std::shared_ptr<AudioFrame> getRecorded() {
if (playbackQueue.samples() < playbackQueue.frameSize()
or recordQueue.samples() < recordQueue.frameSize()) {
/* JAMI_DBG("getRecorded underflow %d / %d, %d / %d",
playbackQueue.samples(), playbackQueue.frameSize(),
recordQueue.samples(), recordQueue.frameSize()); */
return {};
}
if (recordQueue.samples() > 2 * recordQueue.frameSize() && playbackQueue.samples() == 0) {
JAMI_DBG("getRecorded PLAYBACK underflow");
return recordQueue.dequeue();
}
while (playbackQueue.samples() > 10 * playbackQueue.frameSize()) {
JAMI_DBG("getRecorded playback underflow");
playbackQueue.dequeue();
}
while (recordQueue.samples() > 4 * recordQueue.frameSize()) {
JAMI_DBG("getRecorded record underflow");
recordQueue.dequeue();
}
auto playback = playbackQueue.dequeue();
auto record = recordQueue.dequeue();
if (playback and record) {
auto ret = std::make_shared<AudioFrame>(record->getFormat(), record->getFrameSize());
speex_echo_cancellation(state.get(),
(const int16_t*)record->pointer()->data[0],
(const int16_t*)playback->pointer()->data[0],
(int16_t*)ret->pointer()->data[0]);
return ret;
}
return {};
}
private:
using SpeexEchoStatePtr = std::unique_ptr<SpeexEchoState, void(*)(SpeexEchoState*)>;
SpeexEchoStatePtr state;
AudioFrameResizer playbackQueue;
AudioFrameResizer recordQueue;
};
AudioLayer::AudioLayer(const AudioPreference &pref)
: isCaptureMuted_(pref.getCaptureMuted())
, isPlaybackMuted_(pref.getPlaybackMuted())
, captureGain_(pref.getVolumemic())
, playbackGain_(pref.getVolumespkr())
, mainRingBuffer_(Manager::instance().getRingBufferPool().getRingBuffer(RingBufferPool::DEFAULT_ID))
, audioFormat_(Manager::instance().getRingBufferPool().getInternalAudioFormat())
, audioInputFormat_(Manager::instance().getRingBufferPool().getInternalAudioFormat())
, urgentRingBuffer_("urgentRingBuffer_id", SIZEBUF, audioFormat_)
, resampler_(new Resampler)
, inputResampler_(new Resampler)
, lastNotificationTime_()
{
urgentRingBuffer_.createReadOffset(RingBufferPool::DEFAULT_ID);
@ -51,11 +118,12 @@ AudioLayer::AudioLayer(const AudioPreference &pref)
AudioLayer::~AudioLayer()
{}
void AudioLayer::hardwareFormatAvailable(AudioFormat playback)
void AudioLayer::hardwareFormatAvailable(AudioFormat playback, size_t bufSize)
{
JAMI_DBG("Hardware audio format available : %s", playback.toString().c_str());
JAMI_DBG("Hardware audio format available : %s %zu", playback.toString().c_str(), bufSize);
audioFormat_ = Manager::instance().hardwareAudioFormatChanged(playback);
urgentRingBuffer_.setFormat(audioFormat_);
nativeFrameSize_ = bufSize;
}
void AudioLayer::hardwareInputFormatAvailable(AudioFormat capture)
@ -86,6 +154,37 @@ void AudioLayer::flush()
urgentRingBuffer_.flushAll();
}
void AudioLayer::playbackChanged(bool started)
{
playbackStarted_ = started;
checkAEC();
}
void AudioLayer::recordChanged(bool started)
{
recordStarted_ = started;
checkAEC();
}
void AudioLayer::setHasNativeAEC(bool hasEAC)
{
hasNativeAEC_ = hasEAC;
checkAEC();
}
void AudioLayer::checkAEC()
{
bool shouldSoftAEC = not hasNativeAEC_ and playbackStarted_ and recordStarted_;
if (not echoState_ and shouldSoftAEC) {
JAMI_WARN("Starting AEC");
echoState_.reset(new EchoState(audioFormat_, nativeFrameSize_, audioFormat_.sample_rate / 4));
} else if (echoState_ and not shouldSoftAEC) {
JAMI_WARN("Stopping AEC");
echoState_.reset();
}
}
void AudioLayer::putUrgent(AudioBuffer& buffer)
{
std::lock_guard<std::mutex> lock(mutex_);
@ -153,19 +252,44 @@ AudioLayer::getToPlay(AudioFormat format, size_t writableSamples)
std::shared_ptr<AudioFrame> playbackBuf {};
while (!(playbackBuf = playbackQueue_->dequeue())) {
std::shared_ptr<AudioFrame> resampled;
if (auto urgentSamples = urgentRingBuffer_.get(RingBufferPool::DEFAULT_ID)) {
bufferPool.discard(1, RingBufferPool::DEFAULT_ID);
playbackQueue_->enqueue(resampler_->resample(std::move(urgentSamples),format));
resampled = resampler_->resample(std::move(urgentSamples),format);
} else if (auto toneToPlay = Manager::instance().getTelephoneTone()) {
playbackQueue_->enqueue(resampler_->resample(toneToPlay->getNext(), format));
resampled = resampler_->resample(toneToPlay->getNext(), format);
} else if (auto buf = bufferPool.getData(RingBufferPool::DEFAULT_ID)) {
playbackQueue_->enqueue(resampler_->resample(std::move(buf), format));
resampled = resampler_->resample(std::move(buf), format);
} else {
break;
}
if (resampled) {
if (echoState_) {
echoState_->putPlayback(resampled);
}
playbackQueue_->enqueue(std::move(resampled));
} else
break;
}
return playbackBuf;
}
void
AudioLayer::putRecorded(std::shared_ptr<AudioFrame>&& frame)
{
//if (isCaptureMuted_)
// libav_utils::fillWithSilence(frame->pointer());
if (echoState_) {
echoState_->putRecorded(std::move(frame));
while (auto rec = echoState_->getRecorded())
mainRingBuffer_->put(std::move(rec));
} else {
mainRingBuffer_->put(std::move(frame));
}
}
} // namespace jami

View File

@ -33,6 +33,11 @@
#include <atomic>
#include <condition_variable>
extern "C" {
struct SpeexEchoState_;
typedef struct SpeexEchoState_ SpeexEchoState;
}
/**
* @file audiolayer.h
* @brief Main sound class. Manages the data transfers between the application and the hardware.
@ -223,7 +228,7 @@ protected:
/**
* Callback to be called by derived classes when the audio output is opened.
*/
void hardwareFormatAvailable(AudioFormat playback);
void hardwareFormatAvailable(AudioFormat playback, size_t bufSize = 0);
/**
* Set the input format on necessary objects.
@ -232,6 +237,10 @@ protected:
void devicesChanged();
void playbackChanged(bool started);
void recordChanged(bool started);
void setHasNativeAEC(bool hasEAC);
std::shared_ptr<AudioFrame> getToPlay(AudioFormat format, size_t writableSamples);
std::shared_ptr<AudioFrame> getToRing(AudioFormat format, size_t writableSamples);
@ -242,6 +251,8 @@ protected:
return ringBuff ? ringBuff : playBuff;
}
void putRecorded(std::shared_ptr<AudioFrame>&& frame);
void flush();
/**
@ -259,6 +270,10 @@ protected:
*/
bool isRingtoneMuted_ {false};
bool playbackStarted_ {false};
bool recordStarted_ {false};
bool hasNativeAEC_ {true};
/**
* Gain applied to mic signal
*/
@ -272,10 +287,8 @@ protected:
/**
* Buffers for audio processing
*/
AudioBuffer playbackBuffer_;
AudioBuffer playbackResampleBuffer_;
std::shared_ptr<RingBuffer> mainRingBuffer_;
AudioBuffer ringtoneBuffer_;
AudioBuffer ringtoneResampleBuffer_;
std::unique_ptr<AudioFrameResizer> playbackQueue_;
/**
@ -294,6 +307,8 @@ protected:
*/
AudioFormat audioInputFormat_;
size_t nativeFrameSize_ {0};
/**
* Urgent ring buffer used for ringtones
*/
@ -314,12 +329,11 @@ protected:
*/
std::unique_ptr<Resampler> resampler_;
/**
* Manage input sampling rate conversions
*/
std::unique_ptr<Resampler> inputResampler_;
struct EchoState;
std::unique_ptr<EchoState> echoState_;
private:
void checkAEC();
/**
* Time of the last incoming call notification

View File

@ -165,8 +165,6 @@ class CoreLayer : public AudioLayer {
UInt32 inChannelsPerFrame_;
Float64 outSampleRate_;
UInt32 outChannelsPerFrame_;
std::shared_ptr<RingBuffer> mainRingBuffer_;
};
} // namespace jami

View File

@ -43,7 +43,6 @@ CoreLayer::CoreLayer(const AudioPreference &pref)
, indexOut_(pref.getAlsaCardout())
, indexRing_(pref.getAlsaCardring())
, playbackBuff_(0, audioFormat_)
, mainRingBuffer_(Manager::instance().getRingBufferPool().getRingBuffer(RingBufferPool::DEFAULT_ID))
{}
CoreLayer::~CoreLayer()
@ -440,7 +439,7 @@ CoreLayer::read(AudioUnitRenderActionFlags* ioActionFlags,
auto format = audioInputFormat_;
format.sampleFormat = AV_SAMPLE_FMT_FLTP;
auto inBuff = std::make_unique<AudioFrame>(format, inNumberFrames);
auto inBuff = std::make_shared<AudioFrame>(format, inNumberFrames);
if (isCaptureMuted_) {
libav_utils::fillWithSilence(inBuff->pointer());
} else {
@ -448,7 +447,7 @@ CoreLayer::read(AudioUnitRenderActionFlags* ioActionFlags,
for (unsigned i = 0; i < inChannelsPerFrame_; ++i)
std::copy_n((Float32*)captureBuff_->mBuffers[i].mData, inNumberFrames, (Float32*)in.extended_data[i]);
}
mainRingBuffer_->put(std::move(inBuff));
putRecorded(std::move(inBuff));
}
void CoreLayer::updatePreference(AudioPreference &preference, int index, DeviceType type)

View File

@ -38,7 +38,6 @@ CoreLayer::CoreLayer(const AudioPreference &pref)
, indexOut_(pref.getAlsaCardout())
, indexRing_(pref.getAlsaCardring())
, playbackBuff_(0, audioFormat_)
, mainRingBuffer_(Manager::instance().getRingBufferPool().getRingBuffer(RingBufferPool::DEFAULT_ID))
{}
CoreLayer::~CoreLayer()
@ -345,7 +344,7 @@ CoreLayer::read(AudioUnitRenderActionFlags* ioActionFlags,
auto format = audioInputFormat_;
format.sampleFormat = AV_SAMPLE_FMT_FLTP;
auto inBuff = std::make_unique<AudioFrame>(format, inNumberFrames);
auto inBuff = std::make_shared<AudioFrame>(format, inNumberFrames);
if (isCaptureMuted_) {
libav_utils::fillWithSilence(inBuff->pointer());
} else {
@ -353,7 +352,7 @@ CoreLayer::read(AudioUnitRenderActionFlags* ioActionFlags,
for (unsigned i = 0; i < inChannelsPerFrame_; ++i)
std::copy_n((Float32*)captureBuff_->mBuffers[i].mData, inNumberFrames, (Float32*)in.extended_data[i]);
}
mainRingBuffer_->put(std::move(inBuff));
putRecorded(std::move(inBuff));
}
void CoreLayer::updatePreference(AudioPreference &preference, int index, DeviceType type)

View File

@ -172,8 +172,6 @@ class CoreLayer : public AudioLayer {
Float64 inSampleRate_;
UInt32 inChannelsPerFrame_;
std::shared_ptr<RingBuffer> mainRingBuffer_;
std::vector<AudioDevice> getDeviceList(bool getCapture) const;
};

View File

@ -209,8 +209,7 @@ createPorts(jack_client_t *client, std::vector<jack_port_t *> &ports,
JackLayer::JackLayer(const AudioPreference &p) :
AudioLayer(p),
captureClient_(nullptr),
playbackClient_(nullptr),
mainRingBuffer_(Manager::instance().getRingBufferPool().getRingBuffer(RingBufferPool::DEFAULT_ID))
playbackClient_(nullptr)
{
playbackClient_ = jack_client_open(PACKAGE_NAME,
(jack_options_t) (JackNullOption | JackNoStartServer), NULL);

View File

@ -49,7 +49,6 @@ private:
std::thread ringbuffer_thread_;
std::mutex ringbuffer_thread_mutex_;
std::condition_variable data_ready_;
std::shared_ptr<RingBuffer> mainRingBuffer_;
static int process_capture(jack_nframes_t frames, void *arg);
static int process_playback(jack_nframes_t frames, void *arg);

View File

@ -40,8 +40,6 @@ void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *ctx) {
(static_cast<AudioPlayer *>(ctx))->processSLCallback(bq);
}
void AudioPlayer::processSLCallback(SLAndroidSimpleBufferQueueItf bq) {
std::lock_guard<std::mutex> lk(m_);
// retrieve the finished device buf and put onto the free queue
// so recorder could re-use it
sample_buf *buf;

View File

@ -58,7 +58,6 @@ public:
void registerCallback(EngineCallback cb) {callback_ = cb;}
size_t dbgGetDevBufCount();
std::mutex m_;
std::atomic_bool waiting_ {false};
};

View File

@ -59,7 +59,7 @@ void AudioRecorder::processSLCallback(SLAndroidSimpleBufferQueueItf bq) {
AudioRecorder::AudioRecorder(jami::AudioFormat sampleFormat, SLEngineItf slEngine) :
sampleInfo_(sampleFormat)
{
// configure audio source
// configure audio source/
SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE,
SL_IODEVICE_AUDIOINPUT,
SL_DEFAULTDEVICEID_AUDIOINPUT,
@ -76,7 +76,13 @@ AudioRecorder::AudioRecorder(jami::AudioFormat sampleFormat, SLEngineItf slEngin
// create audio recorder
// (requires the RECORD_AUDIO permission)
const SLInterfaceID ids[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE, SL_IID_ANDROIDCONFIGURATION};
const SLInterfaceID ids[] = {
SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
SL_IID_ANDROIDCONFIGURATION,
SL_IID_ANDROIDACOUSTICECHOCANCELLATION,
SL_IID_ANDROIDAUTOMATICGAINCONTROL,
SL_IID_ANDROIDNOISESUPPRESSION
};
const SLboolean req[1] = {SL_BOOLEAN_TRUE};
SLresult result;
result = (*slEngine)->CreateAudioRecorder(slEngine,
@ -91,11 +97,85 @@ AudioRecorder::AudioRecorder(jami::AudioFormat sampleFormat, SLEngineItf slEngin
result = (*recObjectItf_)->GetInterface(recObjectItf_, SL_IID_ANDROIDCONFIGURATION, &recordConfig);
result = (*recordConfig)->SetConfiguration(recordConfig, SL_ANDROID_KEY_RECORDING_PRESET, &streamType, sizeof(SLint32));
bool aec{true}, agc(true), ns(true);
result = (*recObjectItf_)->Realize(recObjectItf_, SL_BOOLEAN_FALSE);
SLASSERT(result);
result = (*recObjectItf_)->GetInterface(recObjectItf_, SL_IID_RECORD, &recItf_);
SLASSERT(result);
/* Check actual performance mode granted*/
SLuint32 modeRetrieved = SL_ANDROID_PERFORMANCE_NONE;
SLuint32 modeSize = sizeof(SLuint32);
result = (*recordConfig)->GetConfiguration(recordConfig, SL_ANDROID_KEY_PERFORMANCE_MODE,
&modeSize, (void*)&modeRetrieved);
SLASSERT(result);
JAMI_WARN("Actual performance mode is %u\n", modeRetrieved);
/* Enable AEC if requested */
if (aec) {
SLAndroidAcousticEchoCancellationItf aecItf;
result = (*recObjectItf_)->GetInterface(recObjectItf_, SL_IID_ANDROIDACOUSTICECHOCANCELLATION, (void*)&aecItf);
JAMI_WARN("AEC is %savailable\n", SL_RESULT_SUCCESS == result ? "" : "not ");
if (SL_RESULT_SUCCESS == result) {
SLboolean enabled;
result = (*aecItf)->IsEnabled(aecItf, &enabled);
SLASSERT(result);
JAMI_WARN("AEC was %s\n", enabled ? "enabled" : "not enabled");
result = (*aecItf)->SetEnabled(aecItf, true);
SLASSERT(result);
result = (*aecItf)->IsEnabled(aecItf, &enabled);
SLASSERT(result);
JAMI_WARN("AEC is now %s\n", enabled ? "enabled" : "not enabled");
hasNativeAEC_ = enabled;
}
}
/* Enable AGC if requested */
if (agc) {
SLAndroidAutomaticGainControlItf agcItf;
result = (*recObjectItf_)->GetInterface(
recObjectItf_, SL_IID_ANDROIDAUTOMATICGAINCONTROL, (void*)&agcItf);
JAMI_WARN("AGC is %savailable\n", SL_RESULT_SUCCESS == result ? "" : "not ");
if (SL_RESULT_SUCCESS == result) {
SLboolean enabled;
result = (*agcItf)->IsEnabled(agcItf, &enabled);
SLASSERT(result);
JAMI_WARN("AGC was %s\n", enabled ? "enabled" : "not enabled");
result = (*agcItf)->SetEnabled(agcItf, true);
SLASSERT(result);
result = (*agcItf)->IsEnabled(agcItf, &enabled);
SLASSERT(result);
JAMI_WARN("AGC is now %s\n", enabled ? "enabled" : "not enabled");
}
}
/* Enable NS if requested */
if (ns) {
SLAndroidNoiseSuppressionItf nsItf;
result = (*recObjectItf_)->GetInterface(
recObjectItf_, SL_IID_ANDROIDNOISESUPPRESSION, (void*)&nsItf);
JAMI_WARN("NS is %savailable\n", SL_RESULT_SUCCESS == result ? "" : "not ");
if (SL_RESULT_SUCCESS == result) {
SLboolean enabled;
result = (*nsItf)->IsEnabled(nsItf, &enabled);
SLASSERT(result);
JAMI_WARN("NS was %s\n", enabled ? "enabled" : "not enabled");
result = (*nsItf)->SetEnabled(nsItf, true);
SLASSERT(result);
result = (*nsItf)->IsEnabled(nsItf, &enabled);
SLASSERT(result);
JAMI_WARN("NS is now %s\n", enabled ? "enabled" : "not enabled");
}
}
result = (*recObjectItf_)->GetInterface(recObjectItf_, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recBufQueueItf_);
SLASSERT(result);

View File

@ -40,6 +40,7 @@ class AudioRecorder {
uint32_t audioBufCount;
EngineCallback callback_ {};
bool hasNativeAEC_ {false};
public:
explicit AudioRecorder(jami::AudioFormat, SLEngineItf engineEngine);
@ -52,6 +53,8 @@ public:
void processSLCallback(SLAndroidSimpleBufferQueueItf bq);
void registerCallback(EngineCallback cb) {callback_ = cb;}
size_t dbgGetDevBufCount();
bool hasNativeAEC() const { return hasNativeAEC_; }
};
}

View File

@ -30,25 +30,19 @@
#include "logger.h"
#include "array_size.h"
#include <SLES/OpenSLES_AndroidConfiguration.h>
#include <thread>
#include <chrono>
#include <cstdio>
#include <cassert>
#include <unistd.h>
#include "SLES/OpenSLES_AndroidConfiguration.h"
/* available only from api 14 */
#ifndef SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION
#define SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION ((SLuint32) 0x00000004)
#endif
namespace jami {
// Constructor
OpenSLLayer::OpenSLLayer(const AudioPreference &pref)
: AudioLayer(pref),
mainRingBuffer_(Manager::instance().getRingBufferPool().getRingBuffer(RingBufferPool::DEFAULT_ID))
: AudioLayer(pref)
{}
// Destructor
@ -81,7 +75,7 @@ OpenSLLayer::startStream(AudioStreamType stream)
emitSignal<DRing::ConfigurationSignal::GetHardwareAudioFormat>(&hw_infos);
hardwareFormat_ = AudioFormat(hw_infos[0], 1); // Mono on Android
hardwareBuffSize_ = hw_infos[1];
hardwareFormatAvailable(hardwareFormat_);
hardwareFormatAvailable(hardwareFormat_, hardwareBuffSize_);
startThread_ = std::thread([this](){
init();
@ -216,8 +210,9 @@ OpenSLLayer::engineServicePlay(bool waiting) {
break;
} else
freePlayBufQueue_.pop();
} else
} else {
break;
}
}
}
@ -284,6 +279,7 @@ OpenSLLayer::initAudioCapture()
recorder_.reset(new opensl::AudioRecorder(hardwareFormat_, engineInterface_));
recorder_->setBufQueues(&freeRecBufQueue_, &recBufQueue_);
recorder_->registerCallback(std::bind(&OpenSLLayer::engineServiceRec, this, _1));
setHasNativeAEC(recorder_->hasNativeAEC());
} catch (const std::exception& e) {
JAMI_ERR("Error initializing audio capture: %s", e.what());
}
@ -301,24 +297,26 @@ OpenSLLayer::startAudioPlayback()
if (ringtone_)
ringtone_->start();
playThread = std::thread([&]() {
playbackChanged(true);
std::unique_lock<std::mutex> lck(playMtx);
while (player_ || ringtone_) {
playCv.wait_for(lck, std::chrono::seconds(1));
if (player_ && player_->waiting_) {
std::lock_guard<std::mutex> lk(player_->m_);
//std::lock_guard<std::mutex> lk(player_->m_);
engineServicePlay(false);
auto n = playBufQueue_.size();
if (n >= PLAY_KICKSTART_BUFFER_COUNT)
player_->playAudioBuffers(n);
}
if (ringtone_ && ringtone_->waiting_) {
std::lock_guard<std::mutex> lk(ringtone_->m_);
//std::lock_guard<std::mutex> lk(ringtone_->m_);
engineServiceRing(false);
auto n = ringBufQueue_.size();
if (n >= PLAY_KICKSTART_BUFFER_COUNT)
ringtone_->playAudioBuffers(n);
}
}
playbackChanged(false);
});
JAMI_WARN("Audio playback started");
}
@ -332,6 +330,7 @@ OpenSLLayer::startAudioCapture()
recorder_->start();
recThread = std::thread([&]() {
recordChanged(true);
std::unique_lock<std::mutex> lck(recMtx);
while (recorder_) {
recCv.wait_for(lck, std::chrono::seconds(1));
@ -342,18 +341,18 @@ OpenSLLayer::startAudioCapture()
recBufQueue_.pop();
if (buf->size_ > 0) {
auto nb_samples = buf->size_ / hardwareFormat_.getBytesPerFrame();
auto out = std::make_unique<AudioFrame>(hardwareFormat_, nb_samples);
auto out = std::make_shared<AudioFrame>(hardwareFormat_, nb_samples);
if (isCaptureMuted_)
libav_utils::fillWithSilence(out->pointer());
else
std::copy_n((const AudioSample*)buf->buf_, nb_samples, (AudioSample*)out->pointer()->data[0]);
// dcblocker_.process(buffer);
mainRingBuffer_->put(std::move(out));
putRecorded(std::move(out));
}
buf->size_ = 0;
freeRecBufQueue_.push(buf);
}
}
recordChanged(false);
});
JAMI_DBG("Audio capture started");

View File

@ -18,8 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _OPENSL_LAYER_H
#define _OPENSL_LAYER_H
#pragma once
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>
@ -52,147 +51,144 @@ class RingBuffer;
*/
class OpenSLLayer : public AudioLayer {
public:
/**
* Constructor
*/
OpenSLLayer(const AudioPreference &pref);
public:
/**
* Constructor
*/
OpenSLLayer(const AudioPreference &pref);
/**
* Destructor
*/
~OpenSLLayer();
/**
* Destructor
*/
~OpenSLLayer();
/**
* Start the capture stream and prepare the playback stream.
* The playback starts accordingly to its threshold
*/
virtual void startStream(AudioStreamType stream = AudioStreamType::DEFAULT);
/**
* Start the capture stream and prepare the playback stream.
* The playback starts accordingly to its threshold
*/
virtual void startStream(AudioStreamType stream = AudioStreamType::DEFAULT);
/**
* Stop the playback and capture streams.
* Drops the pending frames and put the capture and playback handles to PREPARED state
*/
virtual void stopStream();
/**
* Stop the playback and capture streams.
* Drops the pending frames and put the capture and playback handles to PREPARED state
*/
virtual void stopStream();
/**
* Scan the sound card available for capture on the system
* @return std::vector<std::string> The vector containing the string description of the card
*/
virtual std::vector<std::string> getCaptureDeviceList() const;
/**
* Scan the sound card available for capture on the system
* @return std::vector<std::string> The vector containing the string description of the card
*/
virtual std::vector<std::string> getCaptureDeviceList() const;
/**
* Scan the sound card available for capture on the system
* @return std::vector<std::string> The vector containing the string description of the card
*/
virtual std::vector<std::string> getPlaybackDeviceList() const;
/**
* Scan the sound card available for capture on the system
* @return std::vector<std::string> The vector containing the string description of the card
*/
virtual std::vector<std::string> getPlaybackDeviceList() const;
void init();
void init();
void initAudioEngine();
void initAudioEngine();
void shutdownAudioEngine();
void shutdownAudioEngine();
void initAudioPlayback();
void initAudioPlayback();
void initAudioCapture();
void initAudioCapture();
void startAudioPlayback();
void startAudioPlayback();
void startAudioCapture();
void startAudioCapture();
void stopAudioPlayback();
void stopAudioPlayback();
void stopAudioCapture();
void stopAudioCapture();
virtual int getAudioDeviceIndex(const std::string&, DeviceType) const {
return 0;
}
virtual int getAudioDeviceIndex(const std::string&, DeviceType) const {
return 0;
}
virtual std::string getAudioDeviceName(int, DeviceType) const {
return "";
}
virtual std::string getAudioDeviceName(int, DeviceType) const {
return "";
}
void engineServicePlay(bool waiting);
void engineServiceRing(bool waiting);
void engineServiceRec(bool waiting);
void engineServicePlay(bool waiting);
void engineServiceRing(bool waiting);
void engineServiceRec(bool waiting);
private:
/**
* Get the index of the audio card for capture
* @return int The index of the card used for capture
* 0 for the first available card on the system, 1 ...
*/
virtual int getIndexCapture() const {
return 0;
}
private:
/**
* Get the index of the audio card for capture
* @return int The index of the card used for capture
* 0 for the first available card on the system, 1 ...
*/
virtual int getIndexCapture() const {
return 0;
}
/**
* Get the index of the audio card for playback
* @return int The index of the card used for playback
* 0 for the first available card on the system, 1 ...
*/
virtual int getIndexPlayback() const {
return 0;
}
/**
* Get the index of the audio card for playback
* @return int The index of the card used for playback
* 0 for the first available card on the system, 1 ...
*/
virtual int getIndexPlayback() const {
return 0;
}
/**
* Get the index of the audio card for ringtone (could be differnet from playback)
* @return int The index of the card used for ringtone
* 0 for the first available card on the system, 1 ...
*/
virtual int getIndexRingtone() const {
return 0;
}
/**
* Get the index of the audio card for ringtone (could be differnet from playback)
* @return int The index of the card used for ringtone
* 0 for the first available card on the system, 1 ...
*/
virtual int getIndexRingtone() const {
return 0;
}
uint32_t dbgEngineGetBufCount();
uint32_t dbgEngineGetBufCount();
void dumpAvailableEngineInterfaces();
void dumpAvailableEngineInterfaces();
NON_COPYABLE(OpenSLLayer);
NON_COPYABLE(OpenSLLayer);
virtual void updatePreference(AudioPreference &pref, int index, DeviceType type);
virtual void updatePreference(AudioPreference &pref, int index, DeviceType type);
/**
* OpenSL standard object interface
*/
SLObjectItf engineObject_ {nullptr};
/**
* OpenSL standard object interface
*/
SLObjectItf engineObject_ {nullptr};
/**
* OpenSL sound engine interface
*/
SLEngineItf engineInterface_ {nullptr};
/**
* OpenSL sound engine interface
*/
SLEngineItf engineInterface_ {nullptr};
std::unique_ptr<opensl::AudioPlayer> player_ {};
std::unique_ptr<opensl::AudioPlayer> ringtone_ {};
std::unique_ptr<opensl::AudioRecorder> recorder_ {};
std::unique_ptr<opensl::AudioPlayer> player_ {};
std::unique_ptr<opensl::AudioPlayer> ringtone_ {};
std::unique_ptr<opensl::AudioRecorder> recorder_ {};
AudioQueue freePlayBufQueue_ {BUF_COUNT};
AudioQueue playBufQueue_ {BUF_COUNT};
AudioQueue freePlayBufQueue_ {BUF_COUNT};
AudioQueue playBufQueue_ {BUF_COUNT};
AudioQueue freeRingBufQueue_ {BUF_COUNT};
AudioQueue ringBufQueue_ {BUF_COUNT};
AudioQueue freeRingBufQueue_ {BUF_COUNT};
AudioQueue ringBufQueue_ {BUF_COUNT};
std::mutex playMtx {};
std::condition_variable playCv {};
std::thread playThread {};
std::mutex playMtx {};
std::condition_variable playCv {};
std::thread playThread {};
AudioQueue freeRecBufQueue_ {BUF_COUNT}; //Owner of the queue
AudioQueue recBufQueue_ {BUF_COUNT}; //Owner of the queue
AudioQueue freeRecBufQueue_ {BUF_COUNT}; //Owner of the queue
AudioQueue recBufQueue_ {BUF_COUNT}; //Owner of the queue
std::mutex recMtx {};
std::condition_variable recCv {};
std::thread recThread {};
std::mutex recMtx {};
std::condition_variable recCv {};
std::thread recThread {};
std::vector<sample_buf> bufs_ {};
std::vector<sample_buf> bufs_ {};
AudioFormat hardwareFormat_ {AudioFormat::MONO()};
size_t hardwareBuffSize_ {BUFFER_SIZE};
AudioFormat hardwareFormat_ {AudioFormat::MONO()};
size_t hardwareBuffSize_ {BUFFER_SIZE};
std::shared_ptr<RingBuffer> mainRingBuffer_;
std::thread startThread_;
std::thread startThread_;
};
}
#endif // _OPENSL_LAYER_H_

View File

@ -33,6 +33,8 @@
#include <cmath>
namespace jami {
struct AudioLayer::EchoState;
enum Direction { Input = 0, Output = 1, IO = 2, End = 3 };
@ -55,8 +57,6 @@ struct PortAudioLayer::PortAudioLayerImpl
AudioBuffer playbackBuff_;
std::shared_ptr<RingBuffer> mainRingBuffer_;
std::array<PaStream*, static_cast<int>(Direction::End)> streams_;
int paOutputCallback(PortAudioLayer& parent,
@ -226,7 +226,6 @@ PortAudioLayer::PortAudioLayerImpl::PortAudioLayerImpl(PortAudioLayer& parent, c
, indexOut_ {pref.getAlsaCardout()}
, indexRing_ {pref.getAlsaCardring()}
, playbackBuff_ {0, parent.audioFormat_}
, mainRingBuffer_ {Manager::instance().getRingBufferPool().getRingBuffer(RingBufferPool::DEFAULT_ID)}
{
init(parent);
}
@ -562,13 +561,13 @@ PortAudioLayer::PortAudioLayerImpl::paInputCallback(PortAudioLayer& parent,
return paContinue;
}
auto inBuff = std::make_unique<AudioFrame>(parent.audioInputFormat_, framesPerBuffer);
auto inBuff = std::make_shared<AudioFrame>(parent.audioInputFormat_, framesPerBuffer);
auto nFrames = framesPerBuffer * parent.audioInputFormat_.nb_channels;
if (parent.isCaptureMuted_)
libav_utils::fillWithSilence(inBuff->pointer());
else
std::copy_n(inputBuffer, nFrames, (AudioSample*)inBuff->pointer()->extended_data[0]);
mainRingBuffer_->put(std::move(inBuff));
parent.putRecorded(std::move(inBuff));
return paContinue;
}

View File

@ -65,7 +65,6 @@ PulseLayer::PulseLayer(AudioPreference &pref)
, ringtone_()
, mainloop_(pa_threaded_mainloop_new(), pa_threaded_mainloop_free)
, preference_(pref)
, mainRingBuffer_(Manager::instance().getRingBufferPool().getRingBuffer(RingBufferPool::DEFAULT_ID))
{
if (!mainloop_)
throw std::runtime_error("Couldn't create pulseaudio mainloop");
@ -456,7 +455,7 @@ void PulseLayer::readFromMic()
size_t sample_size = record_->frameSize();
const size_t samples = bytes / sample_size;
auto out = std::make_unique<AudioFrame>(record_->format(), samples);
auto out = std::make_shared<AudioFrame>(record_->format(), samples);
if (isCaptureMuted_)
libav_utils::fillWithSilence(out->pointer());
else
@ -465,8 +464,7 @@ void PulseLayer::readFromMic()
if (pa_stream_drop(record_->stream()) < 0)
JAMI_ERR("Capture stream drop failed: %s" , pa_strerror(pa_context_errno(context_)));
//dcblocker_.process(*out);
mainRingBuffer_->put(std::move(out));
putRecorded(std::move(out));
}
void PulseLayer::ringtoneToSpeaker()
@ -710,20 +708,20 @@ void PulseLayer::updatePreference(AudioPreference &preference, int index, Device
const std::string devName(getAudioDeviceName(index, type));
switch (type) {
case DeviceType::PLAYBACK:
JAMI_DBG("setting %s for playback", devName.c_str());
preference.setPulseDevicePlayback(devName);
break;
case DeviceType::PLAYBACK:
JAMI_DBG("setting %s for playback", devName.c_str());
preference.setPulseDevicePlayback(devName);
break;
case DeviceType::CAPTURE:
JAMI_DBG("setting %s for capture", devName.c_str());
preference.setPulseDeviceRecord(devName);
break;
case DeviceType::CAPTURE:
JAMI_DBG("setting %s for capture", devName.c_str());
preference.setPulseDeviceRecord(devName);
break;
case DeviceType::RINGTONE:
JAMI_DBG("setting %s for ringer", devName.c_str());
preference.setPulseDeviceRingtone(devName);
break;
case DeviceType::RINGTONE:
JAMI_DBG("setting %s for ringer", devName.c_str());
preference.setPulseDeviceRingtone(devName);
break;
}
}

View File

@ -206,18 +206,6 @@ class PulseLayer : public AudioLayer {
*/
std::vector<PaDeviceInfos> sourceList_ {};
/*
* Buffers used to avoid doing malloc/free in the audio thread
*/
AudioBuffer micBuffer_;
AudioBuffer micResampleBuffer_;
AudioBuffer playbackBuffer_;
AudioBuffer playbackResampleBuffer_;
AudioBuffer ringtoneBuffer_;
AudioBuffer ringtoneResampleBuffer_;
/** PulseAudio server defaults */
AudioFormat defaultAudioFormat_ {AudioFormat::MONO()};
std::string defaultSink_ {};
@ -235,7 +223,6 @@ class PulseLayer : public AudioLayer {
std::thread streamStarter_ {};
AudioPreference &preference_;
std::shared_ptr<RingBuffer> mainRingBuffer_;
pa_operation* subscribeOp_ {nullptr};
friend class AudioLayerTest;

View File

@ -91,7 +91,7 @@ public:
* @param buffer Data to copied
* @param toCopy Number of bytes to copy
*/
void put(std::shared_ptr<AudioFrame>&& data);
void put(std::shared_ptr<AudioFrame>&& data);
/**
* To get how much samples are available in the buffer to read in
@ -130,6 +130,10 @@ public:
return putLength() == 0;
}
inline void setFrameSize(int nb_samples) {
resizer_.setFrameSize(nb_samples);
}
/**
* Blocks until min_data_length samples of data is available, or until deadline has passed.
*

View File

@ -271,7 +271,7 @@ RingBufferPool::getData(const std::string& call_id)
if (bindings->size() == 1)
return (*bindings->cbegin())->get(call_id);
auto mixBuffer = std::make_unique<AudioFrame>(internalAudioFormat_);
auto mixBuffer = std::make_shared<AudioFrame>(internalAudioFormat_);
for (const auto& rbuf : *bindings) {
if (auto b = rbuf->get(call_id)) {
mixBuffer->mix(*b);
@ -326,7 +326,7 @@ RingBufferPool::getAvailableData(const std::string& call_id)
if (availableFrames == 0)
return {};
auto buf = std::make_unique<AudioFrame>(internalAudioFormat_);
auto buf = std::make_shared<AudioFrame>(internalAudioFormat_);
for (const auto &rbuf : *bindings) {
if (auto b = rbuf->get(call_id))
buf->mix(*b);