diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2020-06-18 00:23:43 +0530 |
---|---|---|
committer | GStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org> | 2020-07-22 12:03:20 +0000 |
commit | 2be560f12dac3fc671687adbc79099c99415f605 (patch) | |
tree | bea4f2f2043319d39983233cfe869b51c5d95a09 | |
parent | ddfdb501cde1a6b78d12e4c3d6602d91116c49b6 (diff) |
opus.recipe: Port to Meson, enable on UWP
Tested and compared with autotools build on:
Windows (UWP, MSVC, MinGW) x (x86, x86_64, ARM64)
Android Universal (ARM64, x86, x86_64, ARMv7)
iOS Universal (ARM64, X86_64)
macOS (x86_64)
Linux (x86_64, ARMv7)
Comparison was done by ensuring that the same options were enabled,
and that the static library had the same objects inside it when built
with Autotools and Meson.
Part-of: <https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/560>
-rw-r--r-- | packages/gstreamer-1.0-codecs.package | 2 | ||||
-rw-r--r-- | recipes/gst-plugins-bad-1.0.recipe | 1 | ||||
-rw-r--r-- | recipes/gst-plugins-base-1.0.recipe | 1 | ||||
-rw-r--r-- | recipes/opus.recipe | 25 | ||||
-rw-r--r-- | recipes/opus/0001-celt-Force-stack-alignment-for-functions-using-__m12.patch | 5 | ||||
-rw-r--r-- | recipes/opus/opus-meson-port.patch | 2589 |
6 files changed, 2612 insertions, 11 deletions
diff --git a/packages/gstreamer-1.0-codecs.package b/packages/gstreamer-1.0-codecs.package index b6065f67..0781454f 100644 --- a/packages/gstreamer-1.0-codecs.package +++ b/packages/gstreamer-1.0-codecs.package @@ -47,7 +47,7 @@ class Package(custom.GStreamer, package.Package): if self.config.variants.uwp: self.files = [ - 'libvpx:libs', 'openh264:libs', + 'libvpx:libs', 'openh264:libs', 'opus:libs', 'gst-plugins-base-1.0:plugins_codecs', 'gst-plugins-good-1.0:plugins_codecs', 'gst-plugins-bad-1.0:plugins_codecs', 'gst-plugins-ugly-1.0:plugins_codecs', ] diff --git a/recipes/gst-plugins-bad-1.0.recipe b/recipes/gst-plugins-bad-1.0.recipe index d1c08cd7..817a90ce 100644 --- a/recipes/gst-plugins-bad-1.0.recipe +++ b/recipes/gst-plugins-bad-1.0.recipe @@ -519,7 +519,6 @@ class Recipe(custom.GStreamer): self.disable_plugin('ladspa', 'effects', dep='ladspa') self.disable_plugin('mms', 'net_restricted', option='libmms', dep='libmms') self.disable_plugin('openjpeg', 'codecs', dep='openjpeg') - self.disable_plugin('opusparse', 'codecs', option='opus', dep='opus') self.disable_plugin('rtmp', 'net_restricted', option='rtmp', dep='librtmp') self.disable_plugin('sbc', 'codecs', dep='sbc') self.disable_plugin('spandsp', 'codecs', dep='spandsp') diff --git a/recipes/gst-plugins-base-1.0.recipe b/recipes/gst-plugins-base-1.0.recipe index 24fb600d..861739cc 100644 --- a/recipes/gst-plugins-base-1.0.recipe +++ b/recipes/gst-plugins-base-1.0.recipe @@ -213,7 +213,6 @@ class Recipe(custom.GStreamer): # All these except libvisual can be ported to Meson/UWP self.disable_plugin('libvisual', 'vis', dep='libvisual') self.disable_plugin('ogg', 'codecs', dep='libogg') - self.disable_plugin('opus', 'codecs', dep='opus') self.disable_plugin('pango', 'core', dep='pango') self.disable_plugin('theora', 'codecs', dep='libtheora') self.disable_plugin('vorbis', 'codecs', dep='libvorbis') diff --git a/recipes/opus.recipe b/recipes/opus.recipe index aa0721de..a8cc7a9a 100644 --- a/recipes/opus.recipe +++ b/recipes/opus.recipe @@ -6,16 +6,27 @@ class Recipe(recipe.Recipe): version = '1.3.1' licenses = [{License.BSD_like: ['COPYING']}] stype = SourceType.TARBALL + btype = BuildType.MESON url = 'xiph://.tar.gz' tarball_checksum = '65b58e1e25b2a114157014736a3d9dfeaad8d41be1c8179866f144a2fb44ff9d' + meson_options = { + 'rtcd': 'enabled', + 'intrinsics': 'enabled', + 'extra-programs': 'disabled', + 'tests': 'disabled', + 'docs': 'disabled', + } - patches = ['opus/0001-celt-Force-stack-alignment-for-functions-using-__m12.patch'] + patches = [ + 'opus/0001-celt-Force-stack-alignment-for-functions-using-__m12.patch', + # https://gitlab.xiph.org/xiph/opus/-/merge_requests/13 + 'opus/opus-meson-port.patch', + ] files_libs = ['libopus'] files_devel = ['include/opus', 'lib/pkgconfig/opus.pc'] - # Starting with v1.1, Opus has special ARM assembly optimizations when - # built without floating point support. Since all our builds assume floating - # point is available (NEON or VFP), we're not enabling that. However, the - # option is there. Note that there is separate NEON/intrinsics support for - # ARM and x86. - # configure_options = '--disable-fixed-point --enable-asm' + + def prepare(self): + # Always have NEON on ARM64, don't need to detect the CPU at runtime. + if self.config.target_arch == Architecture.ARM64: + self.meson_options['rtcd'] = 'disabled' diff --git a/recipes/opus/0001-celt-Force-stack-alignment-for-functions-using-__m12.patch b/recipes/opus/0001-celt-Force-stack-alignment-for-functions-using-__m12.patch index dd3eed1b..3c4a4c05 100644 --- a/recipes/opus/0001-celt-Force-stack-alignment-for-functions-using-__m12.patch +++ b/recipes/opus/0001-celt-Force-stack-alignment-for-functions-using-__m12.patch @@ -15,11 +15,14 @@ diff --git a/celt/x86/pitch_sse.c b/celt/x86/pitch_sse.c index 20e7312..3eee8da 100644 --- a/celt/x86/pitch_sse.c +++ b/celt/x86/pitch_sse.c -@@ -40,6 +40,16 @@ +@@ -40,6 +40,19 @@ #include <xmmintrin.h> #include "arch.h" +#ifdef _WIN32 ++#ifdef _MSC_VER ++#define __attribute__(x) ++#endif +void xcorr_kernel_sse(const opus_val16 *x, const opus_val16 *y, opus_val32 sum[4], int len) __attribute__((force_align_arg_pointer)); +void dual_inner_prod_sse(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, + int N, opus_val32 *xy1, opus_val32 *xy2) __attribute__((force_align_arg_pointer)); diff --git a/recipes/opus/opus-meson-port.patch b/recipes/opus/opus-meson-port.patch new file mode 100644 index 00000000..e75f0e81 --- /dev/null +++ b/recipes/opus/opus-meson-port.patch @@ -0,0 +1,2589 @@ +From 61297be2b6f86bcea2cae37998b785060ebf761b Mon Sep 17 00:00:00 2001 +From: Nirbheek Chauhan <nirbheek@centricular.com> +Date: Sat, 18 Jul 2020 11:19:55 +0530 +Subject: [PATCH 1/6] silk: Fix incorrect ifdef in debug.c + +--- + silk/debug.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/silk/debug.c b/silk/debug.c +index 71e69cc6..4f02912b 100644 +--- a/silk/debug.c ++++ b/silk/debug.c +@@ -37,14 +37,13 @@ POSSIBILITY OF SUCH DAMAGE. + + #if SILK_TIC_TOC + +-#ifdef _WIN32 +- + #if (defined(_WIN32) || defined(_WINCE)) + #include <windows.h> /* timer */ + #else /* Linux or Mac*/ + #include <sys/time.h> + #endif + ++#ifdef _WIN32 + unsigned long silk_GetHighResolutionTime(void) /* O time in usec*/ + { + /* Returns a time counter in microsec */ +-- +2.27.0.windows.1 + + +From 70ca3953074121f2334180d3613524a7da2a0ae9 Mon Sep 17 00:00:00 2001 +From: Nirbheek Chauhan <nirbheek@centricular.com> +Date: Sat, 18 Jul 2020 19:16:52 +0530 +Subject: [PATCH 2/6] celt: Fix broken SSE pre-processor check due to typo + +This broke 5 years ago in 43120f00758219a784f952754f33b9788a8d731b +--- + celt/x86/pitch_sse.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/celt/x86/pitch_sse.h b/celt/x86/pitch_sse.h +index e5f87ab5..f7a014b6 100644 +--- a/celt/x86/pitch_sse.h ++++ b/celt/x86/pitch_sse.h +@@ -91,7 +91,7 @@ opus_val32 celt_inner_prod_sse2( + int N); + #endif + +-#if defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(FIXED_POINT) ++#if defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT) + opus_val32 celt_inner_prod_sse( + const opus_val16 *x, + const opus_val16 *y, +-- +2.27.0.windows.1 + + +From c057d93b1a0fe2ab0e6cb40ae2b91e83ef380451 Mon Sep 17 00:00:00 2001 +From: Nirbheek Chauhan <nirbheek@centricular.com> +Date: Mon, 20 Jul 2020 16:19:07 +0530 +Subject: [PATCH 3/6] Fix size_t -> int conversion warning with MSVC build + +../src/repacketizer_demo.c(122): warning C4267: '=': conversion from 'size_t' to 'int', possible loss of data +../src/repacketizer_demo.c(138): warning C4267: '=': conversion from 'size_t' to 'int', possible loss of data +../src/repacketizer_demo.c(140): warning C4267: '=': conversion from 'size_t' to 'int', possible loss of data +--- + src/repacketizer_demo.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/repacketizer_demo.c b/src/repacketizer_demo.c +index dc05c1b3..66ae3bb4 100644 +--- a/src/repacketizer_demo.c ++++ b/src/repacketizer_demo.c +@@ -119,7 +119,7 @@ int main(int argc, char *argv[]) + for (i=0;i<nb_packets;i++) + { + unsigned char ch[4]; +- err = fread(ch, 1, 4, fin); ++ err = (int) fread(ch, 1, 4, fin); + len[i] = char_to_int(ch); + /*fprintf(stderr, "in len = %d\n", len[i]);*/ + if (len[i]>1500 || len[i]<0) +@@ -135,9 +135,9 @@ int main(int argc, char *argv[]) + } + break; + } +- err = fread(ch, 1, 4, fin); ++ err = (int) fread(ch, 1, 4, fin); + rng[i] = char_to_int(ch); +- err = fread(packets[i], 1, len[i], fin); ++ err = (int) fread(packets[i], 1, len[i], fin); + if (feof(fin)) + { + eof = 1; +-- +2.27.0.windows.1 + + +From 0807f33050c0cf1c0ceace7ae1b3ec4a2629e2a3 Mon Sep 17 00:00:00 2001 +From: Nirbheek Chauhan <nirbheek@centricular.com> +Date: Sat, 18 Jul 2020 11:18:23 +0530 +Subject: [PATCH 4/6] Replace WIN32 with _WIN32 everywhere + +_WIN32 is defined on all Windows platforms by every compiler that +targets Windows. We do not need WIN32 at all. +--- + celt/stack_alloc.h | 4 ++-- + include/opus_defines.h | 2 +- + silk/debug.c | 4 ++-- + win32/VS2015/common.props | 2 +- + 4 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/celt/stack_alloc.h b/celt/stack_alloc.h +index 2b51c8d8..ae40e2a1 100644 +--- a/celt/stack_alloc.h ++++ b/celt/stack_alloc.h +@@ -40,7 +40,7 @@ + #endif + + #ifdef USE_ALLOCA +-# ifdef WIN32 ++# ifdef _WIN32 + # include <malloc.h> + # else + # ifdef HAVE_ALLOCA_H +@@ -102,7 +102,7 @@ + + #define VARDECL(type, var) type *var + +-# ifdef WIN32 ++# ifdef _WIN32 + # define ALLOC(var, size, type) var = ((type*)_alloca(sizeof(type)*(size))) + # else + # define ALLOC(var, size, type) var = ((type*)alloca(sizeof(type)*(size))) +diff --git a/include/opus_defines.h b/include/opus_defines.h +index d141418b..ceee5b84 100644 +--- a/include/opus_defines.h ++++ b/include/opus_defines.h +@@ -64,7 +64,7 @@ extern "C" { + /**Export control for opus functions */ + + #ifndef OPUS_EXPORT +-# if defined(WIN32) ++# if defined(_WIN32) + # if defined(OPUS_BUILD) && defined(DLL_EXPORT) + # define OPUS_EXPORT __declspec(dllexport) + # else +diff --git a/silk/debug.c b/silk/debug.c +index 4f02912b..eb0c36ef 100644 +--- a/silk/debug.c ++++ b/silk/debug.c +@@ -67,7 +67,7 @@ unsigned long GetHighResolutionTime(void) /* O time in usec*/ + int silk_Timer_nTimers = 0; + int silk_Timer_depth_ctr = 0; + char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; +-#ifdef WIN32 ++#ifdef _WIN32 + LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; + #else + unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; +@@ -78,7 +78,7 @@ opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; + opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; + opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; + +-#ifdef WIN32 ++#ifdef _WIN32 + void silk_TimerSave(char *file_name) + { + if( silk_Timer_nTimers > 0 ) +diff --git a/win32/VS2015/common.props b/win32/VS2015/common.props +index 6c757d8b..f6e920b6 100644 +--- a/win32/VS2015/common.props ++++ b/win32/VS2015/common.props +@@ -23,7 +23,7 @@ + <CompileAsManaged>false</CompileAsManaged> + <CompileAsWinRT>false</CompileAsWinRT> + <AdditionalIncludeDirectories>..\..;..\..\include;..\..\silk;..\..\celt;..\..\win32;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> +- <PreprocessorDefinitions>HAVE_CONFIG_H;WIN32;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> ++ <PreprocessorDefinitions>HAVE_CONFIG_H;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeTypeInfo>false</RuntimeTypeInfo> + <OpenMPSupport>false</OpenMPSupport> + </ClCompile> +-- +2.27.0.windows.1 + + +From b60d190675850c9259f68109dc3f4ff5e9d3f46b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= <tim@centricular.com> +Date: Sat, 19 Mar 2016 15:40:22 +0000 +Subject: [PATCH 5/6] meson: add meson build + +Tested on Linux with gcc on Debian sid and on Windows +with Visual Studio 2017. + +ARM assembly code paths pretty much untested so far. +Same for OS/X build and Windows/MSVC build. +--- + celt/meson.build | 87 ++++++ + celt/tests/meson.build | 25 ++ + doc/Doxyfile.in | 3 + + doc/meson.build | 36 +++ + include/meson.build | 13 + + meson.build | 608 +++++++++++++++++++++++++++++++++++++++++ + meson_options.txt | 18 ++ + silk/meson.build | 179 ++++++++++++ + silk/tests/meson.build | 10 + + src/meson.build | 61 +++++ + tests/meson.build | 21 ++ + 11 files changed, 1061 insertions(+) + create mode 100644 celt/meson.build + create mode 100644 celt/tests/meson.build + create mode 100644 doc/meson.build + create mode 100644 include/meson.build + create mode 100644 meson.build + create mode 100644 meson_options.txt + create mode 100644 silk/meson.build + create mode 100644 silk/tests/meson.build + create mode 100644 src/meson.build + create mode 100644 tests/meson.build + +diff --git a/celt/meson.build b/celt/meson.build +new file mode 100644 +index 00000000..498fcde3 +--- /dev/null ++++ b/celt/meson.build +@@ -0,0 +1,87 @@ ++celt_sources = [ ++ 'bands.c', ++ 'celt.c', ++ 'celt_encoder.c', ++ 'celt_decoder.c', ++ 'cwrs.c', ++ 'entcode.c', ++ 'entdec.c', ++ 'entenc.c', ++ 'kiss_fft.c', ++ 'laplace.c', ++ 'mathops.c', ++ 'mdct.c', ++ 'modes.c', ++ 'pitch.c', ++ 'celt_lpc.c', ++ 'quant_bands.c', ++ 'rate.c', ++ 'vq.c', ++] ++ ++if may_have_sse ++ celt_sources += [ ++ 'x86/x86cpu.c', ++ 'x86/x86_celt_map.c', ++ 'x86/pitch_sse.c', ++ ] ++endif ++ ++if may_have_sse2 ++ celt_sources += [ ++ 'x86/pitch_sse2.c', ++ 'x86/vq_sse2.c', ++ ] ++endif ++ ++if may_have_sse4_1 ++ celt_sources += [ ++ 'x86/celt_lpc_sse4_1.c', ++ 'x86/pitch_sse4_1.c', ++ ] ++endif ++ ++opus_armasm_lib = [] ++ ++if host_machine.cpu_family() == 'arm' # was: cpu_arm # FIXME: should only be used if intrinsics or asm is enabled ++ celt_sources += [ ++ 'arm/armcpu.c', ++ 'arm/arm_celt_map.c', ++ ] ++ if may_have_neon ++ celt_sources += [ ++ 'arm/celt_neon_intr.c', ++ ] ++ endif ++ if have_arm_ne10 ++ celt_sources += [ ++ 'arm/celt_ne10_fft.c', ++ 'arm/celt_ne10_mdct.c', ++ ] ++ endif ++ if opus_arm_external_asm ++ # FIXME: arm2gnu.pl stuff? ++ celt_sources_arm_asm = [ ++ 'arm/celt_pitch_xcorr_arm.s', ++ ] ++ celt_arm_armopts_s = configure_file(input: 'arm/armopts.s.in', ++ output: 'arm/armopts.s', ++ configuration: opus_conf) ++ opus_armasm_lib = static_library('opus-armasm', ++ celt_arm_armopts_s, celt_sources_arm_asm, ++ install: false) ++ endif ++endif ++ ++celt_c_args = [] ++if host_machine.system() == 'windows' ++ celt_c_args += ['-DDLL_EXPORT'] ++endif ++ ++celt_lib = static_library('opus-celt', ++ celt_sources, ++ c_args: opus_c_args + celt_c_args, ++ include_directories: opus_includes, ++ link_with: opus_armasm_lib, ++ dependencies: libm, ++ install: false) +diff --git a/celt/tests/meson.build b/celt/tests/meson.build +new file mode 100644 +index 00000000..f6d08d62 +--- /dev/null ++++ b/celt/tests/meson.build +@@ -0,0 +1,25 @@ ++tests = [ ++ 'test_unit_types', ++ 'test_unit_mathops', ++ 'test_unit_entropy', ++ 'test_unit_laplace', ++ 'test_unit_dft', ++ 'test_unit_mdct', ++ 'test_unit_rotation', ++ 'test_unit_cwrs32', ++] ++ ++test_args = [] ++if cc.get_id() == 'msvc' ++ test_args += ['/wd4305'] # trunction from double to float in mathops ++endif ++ ++foreach test_name : tests ++ exe = executable(test_name, '@0@.c'.format(test_name), ++ include_directories : opus_includes, ++ c_args : opus_c_args + test_args, ++ link_with : [opus_armasm_lib, celt_lib], ++ dependencies : libm, ++ install : false) ++ test(test_name, exe) ++endforeach +diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in +index 6d25f1fb..6eef650b 100644 +--- a/doc/Doxyfile.in ++++ b/doc/Doxyfile.in +@@ -335,3 +335,6 @@ PREDEFINED = OPUS_EXPORT= \ + # configure time. + # + HAVE_DOT = @HAVE_DOT@ ++ ++# move docs to the correct place ++OUTPUT_DIRECTORY = @top_builddir@/doc +diff --git a/doc/meson.build b/doc/meson.build +new file mode 100644 +index 00000000..8f967a51 +--- /dev/null ++++ b/doc/meson.build +@@ -0,0 +1,36 @@ ++top_srcdir = meson.source_root() ++top_builddir = meson.build_root() ++ ++have_dot = find_program('dot', required: false).found() ++ ++doxyfile_conf = configuration_data() ++doxyfile_conf.set('VERSION', opus_version) ++doxyfile_conf.set('HAVE_DOT', have_dot) ++doxyfile_conf.set('top_srcdir', top_srcdir) ++doxyfile_conf.set('top_builddir', top_builddir) ++ ++doxyfile = configure_file(input: 'Doxyfile.in', ++ output: 'Doxyfile', ++ configuration: doxyfile_conf, ++ install: false) ++ ++docdir = join_paths(get_option('datadir'), get_option('docdir')) ++ ++doc_inputs = [ ++ 'customdoxygen.css', ++ 'footer.html', ++ 'header.html', ++ 'opus_logo.svg', ++ top_srcdir + '/include/opus.h', ++ top_srcdir + '/include/opus_multistream.h', ++ top_srcdir + '/include/opus_defines.h', ++ top_srcdir + '/include/opus_types.h', ++ top_srcdir + '/include/opus_custom.h', ++] ++ ++custom_target('doc', ++ input: [ doxyfile ] + doc_inputs, ++ output: [ 'html' ], ++ command: [ doxygen, doxyfile ], ++ install_dir: docdir, ++ install: true) +diff --git a/include/meson.build b/include/meson.build +new file mode 100644 +index 00000000..9f41b03a +--- /dev/null ++++ b/include/meson.build +@@ -0,0 +1,13 @@ ++opus_headers = [ ++ 'opus.h', ++ 'opus_multistream.h', ++ 'opus_types.h', ++ 'opus_defines.h', ++] ++ ++if opt_custom_modes ++ opus_headers += ['opus_custom.h'] ++endif ++ ++install_headers(opus_headers, subdir: 'opus') ++ +diff --git a/meson.build b/meson.build +new file mode 100644 +index 00000000..c18e9a50 +--- /dev/null ++++ b/meson.build +@@ -0,0 +1,608 @@ ++# Based on git v1.2.1-35-geee68982 ++project('opus', 'c', ++ version: '1.2.1', ++ meson_version: '>= 0.47.0', ++ default_options: ['warning_level=1', ++ 'c_std=gnu99', ++ 'buildtype=debugoptimized']) ++ ++cc = meson.get_compiler('c') ++ ++opus_includes = include_directories('.', 'include', 'celt', 'silk') ++opus_public_includes = include_directories('include') ++ ++add_project_arguments('-DOPUS_BUILD', language: 'c') ++add_project_arguments('-DHAVE_CONFIG_H', language: 'c') ++ ++if host_machine.system() == 'windows' ++ add_project_arguments('-DWIN32', language: 'c') ++ if cc.get_id() == 'msvc' ++ add_project_arguments('-D_CRT_SECURE_NO_WARNINGS', language: 'c') ++ endif ++endif ++ ++# Check for extra compiler args ++additional_c_args = [] ++if cc.get_id() != 'msvc' ++ additional_c_args += [ ++ '-fvisibility=hidden', ++ '-Wall', ++ '-Wextra', ++ '-Wcast-align', ++ '-Wnested-externs', ++ '-Wshadow', ++ '-Wstrict-prototypes', ++ ] ++endif ++ ++foreach arg : additional_c_args ++ if cc.has_argument(arg) ++ add_project_arguments(arg, language: 'c') ++ endif ++endforeach ++ ++# Windows MSVC warnings ++if cc.get_id() == 'msvc' ++ # Ignore several spurious warnings. ++ # If a warning is completely useless and spammy, use '/wdXXXX' to suppress it ++ # If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once ++ # NOTE: Only add warnings here if you are sure they're spurious ++ add_project_arguments('/wd4035', '/wd4715', '/wd4116', '/wd4046', '/wd4068', ++ '/wd4820', '/wd4244', '/wd4255', '/wd4668', ++ #'/FImsvc_recommended_pragmas.h', ++ language : 'c') ++endif ++ ++opus_c_args = [] ++ ++# FIXME: CURRENT_VERSION from git script, so e.g. 1.1.1-rc-71-gc43b1bc ++opus_version = meson.project_version() ++ ++opus_conf = configuration_data() ++opus_conf.set('PACKAGE_BUGREPORT', '"opus@xiph.org"') ++opus_conf.set('PACKAGE_NAME', '"opus"') ++opus_conf.set('PACKAGE_STRING', '"opus @0@"'.format(opus_version)) ++opus_conf.set('PACKAGE_TARNAME', '"opus"') ++opus_conf.set('PACKAGE_URL', '""') ++opus_conf.set('PACKAGE_VERSION', '"@0@"'.format(opus_version)) ++ ++# FIXME: optional Ne10 dependency ++have_arm_ne10 = false ++ ++libm = cc.find_library('m', required : false) ++ ++opus_conf.set('HAVE_LRINTF', cc.has_function('lrintf', prefix: '#include <math.h>', dependencies: libm)) ++opus_conf.set('HAVE_LRINT', cc.has_function('lrint', prefix: '#include <math.h>', dependencies: libm)) ++opus_conf.set('HAVE___MALLOC_HOOK', cc.has_function('__malloc_hook', prefix: '#include <malloc.h>')) ++ ++# Check for restrict keyword ++restrict_tmpl = ''' ++typedef int * int_ptr; ++int foo (int_ptr @0@ ip, int * @0@ baz[]) { ++ return ip[0]; ++} ++int main (int argc, char ** argv) { ++ int s[1]; ++ int * @0@ t = s; ++ t[0] = 0; ++ return foo(t, (void *)0); ++}''' ++# Define restrict to the equivalent of the C99 restrict keyword, or to ++# nothing if this is not supported. Do not define if restrict is ++# supported directly. ++if not cc.compiles(restrict_tmpl.format('restrict'), name : 'restrict keyword') ++ if cc.compiles(restrict_tmpl.format('__restrict'), name : '__restrict') ++ opus_conf.set('restrict', '__restrict') ++ elif cc.compiles(restrict_tmpl.format('__restrict__'), name : '__restrict__') ++ opus_conf.set('restrict', '__restrict') ++ elif cc.compiles(restrict_tmpl.format('_Restrict'), name : '_Restrict') ++ opus_conf.set('restrict', '_Restrict') ++ else ++ opus_conf.set('restrict', '/**/') ++ endif ++endif ++ ++# Check for C99 variable-size arrays, or alloca() as fallback ++msg_c99_var_arrays = 'no' ++msg_use_alloca = 'no' ++if false and cc.compiles('''static int x; ++ char some_func (void) { ++ char a[++x]; ++ a[sizeof a - 1] = 0; ++ int N; ++ return a[0]; ++ }''', name : 'C99 variable-size arrays') ++ opus_conf.set('VAR_ARRAYS', 1) ++ msg_c99_var_arrays = 'yes' ++ msg_use_alloca = 'no (using C99 variable-size arrays instead)' ++elif cc.compiles('''#include <alloca.h> ++ void some_func (void) { ++ int foo=10; ++ int * array = alloca(foo); ++ }''', name : 'alloca (alloca.h)') ++ opus_conf.set('USE_ALLOCA', true) ++ opus_conf.set('HAVE_ALLOCA_H', true) ++ msg_use_alloca = 'yes' ++elif cc.compiles('''#include <malloc.h> ++ #include <stdlib.h> ++ void some_func (void) { ++ int foo=10; ++ int * array = alloca(foo); ++ }''', name : 'alloca (std)') ++ opus_conf.set('USE_ALLOCA', true) ++ msg_use_alloca = 'yes' ++endif ++ ++opts = [ ++ [ 'fixed-point', 'FIXED_POINT' ], ++ [ 'fixed-point-debug', 'FIXED_DEBUG' ], ++ [ 'custom-modes', 'CUSTOM_MODES' ], ++ [ 'float-approx', 'FLOAT_APPROX' ], ++ [ 'assertions', 'ENABLE_ASSERTIONS' ], ++ [ 'fuzzing', 'FUZZING' ], ++] ++ ++foreach opt : opts ++ # we assume these are all boolean options ++ opt_foo = get_option(opt[0]) ++ if opt_foo ++ opus_conf.set(opt[1], 1) ++ endif ++ set_variable('opt_' + opt[0].underscorify(), opt_foo) ++endforeach ++ ++enable_asm = not get_option('disable-asm') ++enable_rtcd = not get_option('disable-rtcd') ++enable_intrinsics = get_option('enable-intrinsics') ++disable_extra_programs = get_option('disable-extra-programs') ++disable_tests = get_option('disable-tests') ++ ++disable_float_api = not get_option('float-api') ++if disable_float_api ++ opus_conf.set('DISABLE_FLOAT_API', 1) ++endif ++ ++# This is for the description in the pkg-config .pc file ++if opt_fixed_point ++ pc_build = 'fixed-point' ++else ++ pc_build = 'floating-point' ++endif ++if opt_custom_modes ++ pc_build = pc_build + ', custom modes' ++endif ++ ++rtcd_support = 'no' ++cpu_arm = false # FIXME: check, unused ++opus_arm_external_asm = false ++ ++asm_tmpl = ''' ++int main (int argc, char ** argv) { ++ __asm__("@0@"); ++ return 0; ++}''' ++ ++asm_optimization='none' ++if enable_asm ++ inline_optimization='No inline ASM for your platform, please send patches' ++ # Currently we only have asm for fixed-point ++ if host_machine.cpu_family() == 'arm' and opt_fixed_point ++ cpu_arm = true ++ opus_conf.set('OPUS_ARM_ASM', true) ++ ++ # Check if compiler supports gcc-style inline assembly ++ if cc.compiles('''#ifdef __GNUC_MINOR__ ++ #if (__GNUC__ * 1000 + __GNUC_MINOR__) < 3004 ++ #error GCC before 3.4 has critical bugs compiling inline assembly ++ #endif ++ #endif ++ __asm__ (""::)''', ++ name : 'Compiler supports gcc-style inline assembly') ++ inline_optimization = 'ARM' ++ ++ opus_conf.set('OPUS_ARM_INLINE_ASM', 1) ++ ++ # AS_ASM_ARM_EDSP ++ if cc.compiles(asm_tmpl.format('qadd r3,r3,r3'), ++ name : 'Assembler supports EDSP instructions on ARM') ++ opus_conf.set('OPUS_ARM_INLINE_EDSP', 1) ++ inline_optimization = inline_optimization + ' (ESDP)' ++ endif ++ ++ # AS_ASM_ARM_MEDIA ++ if cc.compiles(asm_tmpl.format('shadd8 r3,r3,r3'), ++ name : 'Assembler supports ARMv6 media instructions on ARM') ++ opus_conf.set('OPUS_ARM_INLINE_MEDIA', 1) ++ inline_optimization = inline_optimization + ' (Media)' ++ endif ++ ++ # AS_ASM_ARM_NEON ++ if cc.compiles(asm_tmpl.format('vorr d0,d0,d0'), ++ name : 'Assembler supports NEON instructions on ARM') ++ opus_conf.set('OPUS_ARM_INLINE_NEON', 1) ++ inline_optimization = inline_optimization + ' (NEON)' ++ endif ++ else ++ inline_optimization = 'disabled' ++ endif ++ ++ # We need Perl to translate RVCT-syntax asm to gas syntax ++ # FIXME: for now we just error out if no perl is found ++ perl = find_program('perl', required : true) ++ if perl.found() ++ opus_arm_external_asm = true ++ asm_optimization = 'ARM' ++ ++ opus_arm_presume_edsp = opus_conf.has('OPUS_ARM_INLINE_EDSP') ++ opus_arm_may_have_edsp = opus_arm_presume_edsp ++ ++ opus_arm_presume_media = opus_conf.has('OPUS_ARM_INLINE_MEDIA') ++ opus_arm_may_have_media = opus_arm_presume_media ++ ++ opus_arm_presume_neon = opus_conf.has('OPUS_ARM_INLINE_NEON') ++ opus_arm_may_have_neon = opus_arm_presume_neon ++ ++ if enable_rtcd ++ if not opus_arm_may_have_edsp ++ message('Trying to force-enable armv5e EDSP instructions...') ++ # AS_ASM_ARM_EDSP_FORCE ++ opus_arm_may_have_edsp = cc.compiles(asm_tmpl.format('.arch armv5te\n.object_arch armv4t\nqadd r3,r3,r3'), ++ name : 'Assembler supports EDSP instructions on ARM (forced)') ++ endif ++ if not opus_arm_may_have_media ++ message('Trying to force-enable ARMv6 media instructions...') ++ opus_arm_may_have_media = cc.compiles(asm_tmpl.format('.arch armv6\n.object_arch armv4t\nshadd8 r3,r3,r3'), ++ name : 'Assembler supports ARMv6 media instructions on ARM (forced)') ++ endif ++ if not opus_arm_may_have_neon ++ message('Trying to force-enable NEON instructions...') ++ opus_arm_may_have_neon = cc.compiles(asm_tmpl.format('.arch armv7-a\n.fpu neon\n.object_arch armv4t\nvorr d0,d0,d0'), ++ name : 'Assembler supports NEON instructions on ARM (forced)') ++ endif ++ endif ++ ++ rtcd_support = '' ++ if opus_arm_may_have_edsp ++ opus_conf.set('OPUS_ARM_MAY_HAVE_EDSP', 1) ++ if opus_arm_presume_edsp ++ opus_conf.set('OPUS_ARM_PRESUME_EDSP', 1) ++ asm_optimization = asm_optimization + ' (EDSP)' ++ else ++ rtcd_support = rtcd_support + ' (EDSP)' ++ endif ++ endif ++ if opus_arm_may_have_media ++ opus_conf.set('OPUS_ARM_MAY_HAVE_MEDIA', 1) ++ if opus_arm_presume_media ++ opus_conf.set('OPUS_ARM_PRESUME_MEDIA', 1) ++ asm_optimization = asm_optimization + ' (Media)' ++ else ++ rtcd_support = rtcd_support + ' (Media)' ++ endif ++ endif ++ if opus_arm_may_have_neon ++ opus_conf.set('OPUS_ARM_MAY_HAVE_NEON', 1) ++ if opus_arm_presume_neon ++ opus_conf.set('OPUS_ARM_PRESUME_NEON', 1) ++ asm_optimization = asm_optimization + ' (NEON)' ++ else ++ rtcd_support = rtcd_support + ' (NEON)' ++ endif ++ endif ++ ++ # Make sure turning on RTCD gets us at least one instruction set ++ if rtcd_support != '' ++ rtcd_support = 'ARM ' + rtcd_support ++ else ++ rtcd_support = 'no' ++ endif ++ ++ # Check for apple-style tools ++ if cc.compiles('''#ifndef __APPLE__ ++ #error not apple ++ #endif''', name : 'Apple-style tools') ++ arm2gnu_params = '--apple' # FIXME: use somewhere ++ else ++ arm2gnu_params = '' ++ endif ++ endif # found perl ++ endif # arm + enable fixed point ++else # enable asm ++ inline_optimization='disabled' ++ asm_optimization='disabled' ++endif ++ ++intrinsics_foo=''' ++m4_define([DEFAULT_ARM_NEON_INTR_CFLAGS], [-mfpu=neon]) ++# With GCC on ARM32 softfp architectures (e.g. Android, or older Ubuntu) you need to specify ++# -mfloat-abi=softfp for -mfpu=neon to work. However, on ARM32 hardfp architectures (e.g. newer Ubuntu), ++# this option will break things. ++ ++# As a heuristic, if host matches arm*eabi* but not arm*hf*, it's probably soft-float. ++m4_define([DEFAULT_ARM_NEON_SOFTFP_INTR_CFLAGS], [-mfpu=neon -mfloat-abi=softfp]) ++ ++AS_CASE([$host], ++ [arm*hf*], [AS_VAR_SET([RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS], "DEFAULT_ARM_NEON_INTR_CFLAGS")], ++ [arm*eabi*], [AS_VAR_SET([RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS], "DEFAULT_ARM_NEON_SOFTFP_INTR_CFLAGS")], ++ [AS_VAR_SET([RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS], "DEFAULT_ARM_NEON_INTR_CFLAGS")]) ++ ++AC_ARG_VAR([ARM_NEON_INTR_CFLAGS], [C compiler flags to compile ARM NEON intrinsics @<:@default=]DEFAULT_ARM_NEON_INTR_CFLAGS / DEFAULT_ARM_NEON_SOFTFP_INTR_CFLAGS[@:>@]) ++ ++AS_VAR_SET_IF([ARM_NEON_INTR_CFLAGS], [], [AS_VAR_SET([ARM_NEON_INTR_CFLAGS], ["$RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS"])]) ++''' ++ ++may_have_sse = false ++may_have_sse2 = false ++may_have_sse4_1 = false ++may_have_avx = false ++ ++may_have_neon = false # FIXME: merge with / fixup opus_arm_may_have_neon ++ ++if enable_intrinsics ++ intrinsics_support = '' ++ rtcd_support = '' ++ if host_machine.cpu_family().startswith('arm') ++foo1_arm=''' ++ AS_CASE([$host_cpu], ++ [arm*], ++ [ ++ cpu_arm=yes ++ OPUS_CHECK_INTRINSICS( ++ [ARM Neon], ++ [$ARM_NEON_INTR_CFLAGS], ++ [OPUS_ARM_MAY_HAVE_NEON_INTR], ++ [OPUS_ARM_PRESUME_NEON_INTR], ++ [[#include <arm_neon.h> ++ ]], ++ [[ ++ static float32x4_t A0, A1, SUMM; ++ SUMM = vmlaq_f32(SUMM, A0, A1); ++ ]] ++ ) ++ AS_IF([test x"$OPUS_ARM_MAY_HAVE_NEON_INTR" = x"1" && test x"$OPUS_ARM_PRESUME_NEON_INTR" != x"1"], ++ [ ++ OPUS_ARM_NEON_INTR_CFLAGS="$ARM_NEON_INTR_CFLAGS" ++ AC_SUBST([OPUS_ARM_NEON_INTR_CFLAGS]) ++ ] ++ ) ++ ++ AS_IF([test x"$OPUS_ARM_MAY_HAVE_NEON_INTR" = x"1"], ++ [ ++ AC_DEFINE([OPUS_ARM_MAY_HAVE_NEON_INTR], 1, [Compiler supports ARMv7 Neon Intrinsics]) ++ intrinsics_support="$intrinsics_support (Neon_Intrinsics)" ++ ++ AS_IF([test x"enable_rtcd" != x"" && test x"$OPUS_ARM_PRESUME_NEON_INTR" != x"1"], ++ [rtcd_support="$rtcd_support (ARMv7_Neon_Intrinsics)"]) ++ ++ AS_IF([test x"$OPUS_ARM_PRESUME_NEON_INTR" = x"1"], ++ [AC_DEFINE([OPUS_ARM_PRESUME_NEON_INTR], 1, [Define if binary requires NEON intrinsics support])]) ++ ++ OPUS_PATH_NE10() ++ AS_IF([test x"$NE10_LIBS" != x""], ++ [ ++ intrinsics_support="$intrinsics_support (NE10)" ++ AS_IF([test x"enable_rtcd" != x"" \ ++ && test x"$OPUS_ARM_PRESUME_NEON_INTR" != x"1"], ++ [rtcd_support="$rtcd_support (NE10)"]) ++ ]) ++ ++ AS_IF([test x"$rtcd_support" = x""], ++ [rtcd_support=no]) ++ ++ AS_IF([test x"$intrinsics_support" = x""], ++ [intrinsics_support=no], ++ [intrinsics_support="arm$intrinsics_support"]) ++ ], ++ [ ++ AC_MSG_WARN([Compiler does not support ARM intrinsics]) ++ intrinsics_support=no ++ ]) ++ ], ++''' ++ elif host_machine.cpu_family().startswith('x86') ++ # FIXME: allow external override/specification of the flags ++ x86_intrinsics = [ ++ [ 'SSE', 'xmmintrin.h', '__m128', '_mm_setzero_ps()', '-msse' ], ++ [ 'SSE2', 'emmintrin.h', '__m128i', '_mm_setzero_si128()', '-msse2' ], ++ [ 'SSE4.1', 'smmintrin.h', '__m128i', '_mm_setzero_si128(); mtest = _mm_cmpeq_epi64(mtest, mtest)', '-msse4.1' ], ++ [ 'AVX', 'immintrin.h', '__m256', '_mm256_setzero_ps()', '-mavx' ], ++ ] ++ ++ foreach intrin : x86_intrinsics ++ intrin_check = '''#include <@0@> ++ int main (int argc, char ** argv) { ++ static @1@ mtest; ++ mtest = @2@; ++ return *((unsigned char *) &mtest) != 0; ++ }'''.format(intrin.get(1),intrin.get(2),intrin.get(3)) ++ intrin_name = intrin.get(0) ++ intrin_link_args = intrin.get(4) ++ if cc.links(intrin_check, name : 'if compiler supports @0@ intrinsics'.format(intrin_name)) ++ may_have_intrin = true ++ presume_intrin = true ++ else ++ presume_intrin = false ++ if cc.links(intrin_check, ++ args : intrin_link_args, ++ name : 'if compiler supports @0@ intrinsics with @1@'.format(intrin_name,intrin_link_args)) ++ may_have_intrin = true ++ # FIXME: add args to some var and use it later ++ else ++ may_have_intrin = false ++ endif ++ endif ++ set_variable('may_have_' + intrin_name.to_lower().underscorify(), may_have_intrin) ++ # FIXME: unused: set_variable('presume_' + intrin_name.to_lower().underscorify(), presume_intrin) ++ if may_have_intrin ++ intrinsics_support = intrinsics_support + ' ' + intrin_name ++ opus_conf.set('OPUS_X86_MAY_HAVE_' + intrin_name.underscorify(), 1) ++ if presume_intrin ++ opus_conf.set('OPUS_X86_PRESUME_' + intrin_name.underscorify(), 1) ++ else ++ rtcd_support = rtcd_support + ' ' + intrin_name ++ opus_c_args += [ intrin_link_args ] ++ endif ++ else ++ message('Warning: Compiler does not support @0@ intrinsics'.format(intrin_name)) ++ endif ++ endforeach ++ ++ if intrinsics_support == '' ++ intrinsics_support = 'no' ++ else ++ intrinsics_support = 'x86' + intrinsics_support ++ endif ++ ++ if rtcd_support == '' ++ rtcd_support = 'no' ++ else ++ rtcd_support = 'x86' + rtcd_support ++ endif ++ ++ if enable_rtcd and rtcd_support != 'no' ++ get_cpuid_by_asm = false ++ cpuid_asm_code = ''' ++ #include <stdio.h> ++ int main (int argc, char ** argv) { ++ unsigned int CPUInfo0; ++ unsigned int CPUInfo1; ++ unsigned int CPUInfo2; ++ unsigned int CPUInfo3; ++ unsigned int InfoType; ++ __asm__ __volatile__ ( ++ "cpuid": ++ "=a" (CPUInfo0), ++ "=b" (CPUInfo1), ++ "=c" (CPUInfo2), ++ "=d" (CPUInfo3) : ++ "a" (InfoType), "c" (0) ++ ); ++ return 0; ++ }''' ++ cpuid_c_code = ''' ++ #include <cpuid.h> ++ int main (int argc, char ** argv) { ++ unsigned int CPUInfo0; ++ unsigned int CPUInfo1; ++ unsigned int CPUInfo2; ++ unsigned int CPUInfo3; ++ unsigned int InfoType; ++ __get_cpuid(InfoType, &CPUInfo0, &CPUInfo1, &CPUInfo2, &CPUInfo3); ++ return 0; ++ }''' ++ if cc.links(cpuid_asm_code, name : 'Get X86 CPU info via inline assembly') ++ opus_conf.set('CPU_INFO_BY_ASM', 1) ++ elif cc.links(cpuid_c_code, name : 'Get X86 CPU info via C method') ++ opus_conf.set('CPU_INFO_BY_C', 1) ++ else ++ error('No supported Get CPU Info method, please disable intrinsics') ++ endif ++ endif ++ else ++ message('Warning: No intrinsics support for your architecture (@0@)'.format(host_machine.get_cpu())) ++ intrinsics_support = 'no' ++ endif ++else ++ intrinsics_support = 'no' ++endif ++ ++if enable_rtcd ++ if rtcd_support != 'no' ++ opus_conf.set('OPUS_HAVE_RTCD', 1) ++ endif ++else ++ rtcd_support = 'disabled' ++endif ++ ++subdir('include') ++subdir('silk') ++subdir('celt') ++subdir('src') ++ ++configure_file(output: 'config.h', configuration: opus_conf) ++ ++if not disable_tests ++ subdir('celt/tests') ++ subdir('silk/tests') ++ subdir('tests') ++endif ++ ++# pkg-config files ++# FIXME: use pkg-config import module instead? ++pkgconf = configuration_data() ++ ++pkgconf.set('prefix', join_paths(get_option('prefix'))) ++pkgconf.set('exec_prefix', '${prefix}') ++pkgconf.set('libdir', '${prefix}/@0@'.format(get_option('libdir'))) ++pkgconf.set('includedir', '${prefix}/@0@'.format(get_option('includedir'))) ++pkgconf.set('VERSION', opus_version) ++pkgconf.set('PC_BUILD', pc_build) ++if libm.found() ++ pkgconf.set('LIBM', '-lm') ++endif ++ ++pkg_install_dir = '@0@/pkgconfig'.format(get_option('libdir')) ++ ++configure_file(input : 'opus.pc.in', ++ output : 'opus.pc', ++ configuration : pkgconf, ++ install_dir : pkg_install_dir) ++ ++# The uninstalled one has hardcoded libtool + static lib stuff, skip it for now ++#configure_file(input : 'opus-uninstalled.pc.in', ++# output : 'opus-uninstalled.pc', ++# configuration : pkgconf, ++# install : false) ++ ++doxygen = find_program('doxygen', required: get_option('docs')) ++have_doxygen = doxygen.found() ++if have_doxygen ++ msg_doc = 'yes' ++ subdir('doc') ++else ++ if get_option('docs').disabled() ++ msg_doc = 'disabled' ++ else ++ msg_doc = 'not found' ++ endif ++endif ++ ++# FIXME: use bool.to_string('yes', 'no') here once meson 0.31 is out ++# FIXME: only print the ninja help if ninja is used as backend ++msg_c99_lrintf = opus_conf.has('HAVE_LRINTF').to_string() ++message(''' ++------------------------------------------------------------------------ ++ opus @0@: Automatic configuration OK. ++ ++ Compiler support: ++ ++ C99 var arrays: ................ @1@ ++ C99 lrintf: .................... @2@ ++ Use alloca: .................... @3@ ++ ++ General configuration: ++ ++ Floating point support: ........ @4@ ++ Fast float approximations: ..... @5@ ++ Fixed point debugging: ......... @6@ ++ Inline Assembly Optimizations: . @7@ ++ External Assembly Optimizations: @8@ ++ Intrinsics Optimizations.......: @9@ ++ Run-time CPU detection: ........ @10@ ++ Custom modes: .................. @11@ ++ Assertion checking: ............ @12@ ++ Fuzzing: ....................... @13@ ++ ++ API documentation: ............. @14@ ++ Extra programs: ................ @15@ ++ Tests: ......................... @16@ ++------------------------------------------------------------------------ ++ ++ Type "ninja; ninja install" to compile and install ++ Type "ninja test" to run the test suite ++'''.format(meson.project_version(), msg_c99_var_arrays, msg_c99_lrintf, ++ msg_use_alloca, not opt_fixed_point, opt_float_approx, ++ opt_fixed_point_debug, inline_optimization, asm_optimization, ++ intrinsics_support, rtcd_support, opt_custom_modes, ++ opt_assertions, opt_fuzzing, msg_doc, ++ not disable_extra_programs, not disable_tests)) +diff --git a/meson_options.txt b/meson_options.txt +new file mode 100644 +index 00000000..21322ac5 +--- /dev/null ++++ b/meson_options.txt +@@ -0,0 +1,18 @@ ++option('fixed-point', type : 'boolean', value : false, description : 'Compile without floating point (for machines without a fast enough FPU') ++option('fixed-point-debug', type : 'boolean', value : false, description : 'Debug fixed-point implementation') ++option('float-api', type : 'boolean', value : true, description : 'Compile with or without the floating point API (for machines with no float library') ++option('custom-modes', type : 'boolean', value : false, description : 'Enable non-Opus modes, e.g. 44.1 kHz & 2^n frames') ++option('float-approx', type : 'boolean', value : false, description : 'Enable fast approximations for floating point (not supported on all platforms)') ++option('disable-asm', type : 'boolean', value : false, description : 'Disable assembly optimizations') ++option('disable-rtcd', type : 'boolean', value : false, description : 'Disable run-time CPU capabilities detection') ++option('enable-intrinsics', type : 'boolean', value : false, description : 'Enable intrinsics optimizations for ARM(float) X86(fixed)') ++option('disable-extra-programs', type : 'boolean', value : false, description : 'Do not build extra programs (demo and tests)') ++option('assertions', type : 'boolean', value : false, description : 'Enable additional software error checking') ++option('fuzzing', type : 'boolean', value : false, description : 'Causes the encoder to make random decisions') ++option('disable-tests', type : 'boolean', value : false, description : 'Do not build tests') ++ ++# feature options ++option('docs', type: 'feature', value: 'auto', description: 'Build API documentation') ++ ++# other options ++option('docdir', type: 'string', value: 'doc/opus', description: 'Directory to install documentation into (default: DATADIR/doc/opus') +diff --git a/silk/meson.build b/silk/meson.build +new file mode 100644 +index 00000000..1a1a0954 +--- /dev/null ++++ b/silk/meson.build +@@ -0,0 +1,179 @@ ++silk_sources = [ ++ 'CNG.c', ++ 'code_signs.c', ++ 'init_decoder.c', ++ 'decode_core.c', ++ 'decode_frame.c', ++ 'decode_parameters.c', ++ 'decode_indices.c', ++ 'decode_pulses.c', ++ 'decoder_set_fs.c', ++ 'dec_API.c', ++ 'enc_API.c', ++ 'encode_indices.c', ++ 'encode_pulses.c', ++ 'gain_quant.c', ++ 'interpolate.c', ++ 'LP_variable_cutoff.c', ++ 'NLSF_decode.c', ++ 'NSQ.c', ++ 'NSQ_del_dec.c', ++ 'PLC.c', ++ 'shell_coder.c', ++ 'tables_gain.c', ++ 'tables_LTP.c', ++ 'tables_NLSF_CB_NB_MB.c', ++ 'tables_NLSF_CB_WB.c', ++ 'tables_other.c', ++ 'tables_pitch_lag.c', ++ 'tables_pulses_per_block.c', ++ 'VAD.c', ++ 'control_audio_bandwidth.c', ++ 'quant_LTP_gains.c', ++ 'VQ_WMat_EC.c', ++ 'HP_variable_cutoff.c', ++ 'NLSF_encode.c', ++ 'NLSF_VQ.c', ++ 'NLSF_unpack.c', ++ 'NLSF_del_dec_quant.c', ++ 'process_NLSFs.c', ++ 'stereo_LR_to_MS.c', ++ 'stereo_MS_to_LR.c', ++ 'check_control_input.c', ++ 'control_SNR.c', ++ 'init_encoder.c', ++ 'control_codec.c', ++ 'A2NLSF.c', ++ 'ana_filt_bank_1.c', ++ 'biquad_alt.c', ++ 'bwexpander_32.c', ++ 'bwexpander.c', ++ 'debug.c', ++ 'decode_pitch.c', ++ 'inner_prod_aligned.c', ++ 'lin2log.c', ++ 'log2lin.c', ++ 'LPC_analysis_filter.c', ++ 'LPC_inv_pred_gain.c', ++ 'table_LSF_cos.c', ++ 'NLSF2A.c', ++ 'NLSF_stabilize.c', ++ 'NLSF_VQ_weights_laroia.c', ++ 'pitch_est_tables.c', ++ 'resampler.c', ++ 'resampler_down2_3.c', ++ 'resampler_down2.c', ++ 'resampler_private_AR2.c', ++ 'resampler_private_down_FIR.c', ++ 'resampler_private_IIR_FIR.c', ++ 'resampler_private_up2_HQ.c', ++ 'resampler_rom.c', ++ 'sigm_Q15.c', ++ 'sort.c', ++ 'sum_sqr_shift.c', ++ 'stereo_decode_pred.c', ++ 'stereo_encode_pred.c', ++ 'stereo_find_predictor.c', ++ 'stereo_quant_pred.c', ++ 'LPC_fit.c', ++] ++ ++silk_sources_sse4_1 = [ ++ 'x86/NSQ_sse4_1.c', ++ 'x86/NSQ_del_dec_sse4_1.c', ++ 'x86/x86_silk_map.c', ++ 'x86/VAD_sse4_1.c', ++ 'x86/VQ_WMat_EC_sse4_1.c', ++] ++ ++silk_sources_fixed = [ ++ 'fixed/LTP_analysis_filter_FIX.c', ++ 'fixed/LTP_scale_ctrl_FIX.c', ++ 'fixed/corrMatrix_FIX.c', ++ 'fixed/encode_frame_FIX.c', ++ 'fixed/find_LPC_FIX.c', ++ 'fixed/find_LTP_FIX.c', ++ 'fixed/find_pitch_lags_FIX.c', ++ 'fixed/find_pred_coefs_FIX.c', ++ 'fixed/noise_shape_analysis_FIX.c', ++ 'fixed/process_gains_FIX.c', ++ 'fixed/regularize_correlations_FIX.c', ++ 'fixed/residual_energy16_FIX.c', ++ 'fixed/residual_energy_FIX.c', ++ 'fixed/warped_autocorrelation_FIX.c', ++ 'fixed/apply_sine_window_FIX.c', ++ 'fixed/autocorr_FIX.c', ++ 'fixed/burg_modified_FIX.c', ++ 'fixed/k2a_FIX.c', ++ 'fixed/k2a_Q16_FIX.c', ++ 'fixed/pitch_analysis_core_FIX.c', ++ 'fixed/vector_ops_FIX.c', ++ 'fixed/schur64_FIX.c', ++ 'fixed/schur_FIX.c', ++] ++ ++silk_sources_fixed_sse4_1 = [ ++ 'fixed/x86/vector_ops_FIX_sse4_1.c', ++ 'fixed/x86/burg_modified_FIX_sse4_1.c', ++] ++ ++silk_sources_float = [ ++ 'float/apply_sine_window_FLP.c', ++ 'float/corrMatrix_FLP.c', ++ 'float/encode_frame_FLP.c', ++ 'float/find_LPC_FLP.c', ++ 'float/find_LTP_FLP.c', ++ 'float/find_pitch_lags_FLP.c', ++ 'float/find_pred_coefs_FLP.c', ++ 'float/LPC_analysis_filter_FLP.c', ++ 'float/LTP_analysis_filter_FLP.c', ++ 'float/LTP_scale_ctrl_FLP.c', ++ 'float/noise_shape_analysis_FLP.c', ++ 'float/process_gains_FLP.c', ++ 'float/regularize_correlations_FLP.c', ++ 'float/residual_energy_FLP.c', ++ 'float/warped_autocorrelation_FLP.c', ++ 'float/wrappers_FLP.c', ++ 'float/autocorrelation_FLP.c', ++ 'float/burg_modified_FLP.c', ++ 'float/bwexpander_FLP.c', ++ 'float/energy_FLP.c', ++ 'float/inner_product_FLP.c', ++ 'float/k2a_FLP.c', ++ 'float/LPC_inv_pred_gain_FLP.c', ++ 'float/pitch_analysis_core_FLP.c', ++ 'float/scale_copy_vector_FLP.c', ++ 'float/scale_vector_FLP.c', ++ 'float/schur_FLP.c', ++ 'float/sort_FLP.c', ++] ++ ++if opt_fixed_point ++ silk_sources += silk_sources_fixed ++ if may_have_sse4_1 ++ silk_sources += silk_sources_sse4_1 ++ silk_sources += silk_sources_fixed_sse4_1 ++ endif ++else ++ silk_sources += silk_sources_float ++ if may_have_sse4_1 ++ silk_sources += silk_sources_sse4_1 ++ endif ++endif ++ ++if host_machine.cpu_family() == 'arm' # was: cpu_arm # FIXME: should only be used if intrinsics or asm is enabled ++ silk_sources += silk_sources_arm ++endif ++ ++silk_c_args = [] ++if host_machine.system() == 'windows' ++ silk_c_args += ['-DDLL_EXPORT'] ++endif ++ ++silk_lib = static_library('opus-silk', ++ silk_sources, ++ c_args: opus_c_args + silk_c_args, ++ include_directories: [opus_includes, include_directories('float', 'fixed')], ++ #link_with: opus_armasm_lib, ++ dependencies: libm, ++ install: false) +diff --git a/silk/tests/meson.build b/silk/tests/meson.build +new file mode 100644 +index 00000000..06cefe40 +--- /dev/null ++++ b/silk/tests/meson.build +@@ -0,0 +1,10 @@ ++exe = executable('test_unit_LPC_inv_pred_gain', ++ 'test_unit_LPC_inv_pred_gain.c', '../LPC_inv_pred_gain.c', ++ include_directories: opus_includes, ++ c_args: opus_c_args, ++ link_with: [opus_armasm_lib, celt_lib, silk_lib], ++ dependencies: libm, ++ install: false) ++ ++test(test_name, exe) ++ +diff --git a/src/meson.build b/src/meson.build +new file mode 100644 +index 00000000..8fc463e1 +--- /dev/null ++++ b/src/meson.build +@@ -0,0 +1,61 @@ ++opus_sources = [ ++ 'opus.c', ++ 'opus_decoder.c', ++ 'opus_encoder.c', ++ 'opus_multistream.c', ++ 'opus_multistream_encoder.c', ++ 'opus_multistream_decoder.c', ++ 'repacketizer.c', ++] ++ ++opus_sources_float = [ ++ 'analysis.c', ++ 'mlp.c', ++ 'mlp_data.c', ++] ++ ++if not disable_float_api ++ opus_sources += opus_sources_float ++endif ++ ++opus_lib_c_args = [] ++if host_machine.system() == 'windows' ++ opus_lib_c_args += ['-DDLL_EXPORT'] ++endif ++ ++opus_lib = library('opus', ++ opus_sources, ++# FIXME version : libversion, ++# FIXME soversion : soversion, ++ c_args: opus_c_args + opus_lib_c_args, ++ include_directories: opus_includes, ++ link_with: [celt_lib, silk_lib], ++ dependencies: libm, ++ install: true) ++ ++opus_dep = declare_dependency(link_with: opus_lib, ++ include_directories: opus_public_includes) ++ ++# Extra uninstalled Opus programs ++if not disable_extra_programs ++ extra_programs = ['opus_compare', 'opus_demo', 'repacketizer_demo'] ++ ++ foreach prog : extra_programs ++ executable(prog, '@0@.c'.format(prog), ++ include_directories: opus_includes, ++ c_args: opus_c_args, ++ link_with: opus_lib, ++ dependencies: libm, ++ install: false) ++ endforeach ++ ++ if opt_custom_modes ++ executable('opus_custom_demo', '../celt/opus_custom_demo.c', ++ include_directories: opus_includes, ++ c_args: opus_c_args, ++ link_with: opus_lib, ++ dependencies: libm, ++ install: false) ++ endif ++ ++endif # not disable_extra_programs +diff --git a/tests/meson.build b/tests/meson.build +new file mode 100644 +index 00000000..9026ac30 +--- /dev/null ++++ b/tests/meson.build +@@ -0,0 +1,21 @@ ++# Tests that link to libopus ++opus_tests = [ ++ ['test_opus_api'], ++ ['test_opus_decode'], ++ ['test_opus_encode', 'opus_encode_regressions.c', 120], ++ ['test_opus_padding'], ++ ['test_opus_projection'], ++] ++ ++foreach t : opus_tests ++ test_name = t.get(0) ++ extra_srcs = t.get(1, []) ++ timeout = t.get(2, 30) ++ exe = executable(test_name, '@0@.c'.format(test_name), extra_srcs, ++ include_directories: opus_includes, ++ c_args: opus_c_args, ++ link_with: opus_lib, ++ dependencies: libm, ++ install: false) ++ test(test_name, exe, timeout: timeout) ++endforeach +-- +2.27.0.windows.1 + + +From d1f655dbb9c4dad61f3fdd173adb3de97459e016 Mon Sep 17 00:00:00 2001 +From: Nirbheek Chauhan <nirbheek@centricular.com> +Date: Thu, 18 Jun 2020 00:16:17 +0530 +Subject: [PATCH 6/6] meson: Update to latest git, finish support for ARM, + general cleanups + +* Fix build of opus_projection test + +Needs the projection API to actually be built, and it needs to link +directly to the objects. This is also what the Makefile does. + +At the same time, use kwargs: to set the test timeout so we don't need +to hard-code the default value. + +Both these require a meson version bump. + +* Set the libversion and darwin_versions to match the LT_VERSION + +Now our binaries have the same ABI / soversion as the Autotools build. + +* Reorganize intrinsics and rtcd support + +* Add summary() support + +* Increase warning_level instead of passing -Wextra + +* Add missing stdint.h check +--- + celt/meson.build | 86 ++++--- + celt/tests/meson.build | 4 +- + include/meson.build | 1 + + meson.build | 561 ++++++++++++++++++++++------------------- + meson_options.txt | 20 +- + silk/meson.build | 48 +++- + silk/tests/meson.build | 4 +- + src/meson.build | 19 +- + tests/meson.build | 27 +- + 9 files changed, 431 insertions(+), 339 deletions(-) + +diff --git a/celt/meson.build b/celt/meson.build +index 498fcde3..8afc2ab8 100644 +--- a/celt/meson.build ++++ b/celt/meson.build +@@ -19,69 +19,83 @@ celt_sources = [ + 'vq.c', + ] + +-if may_have_sse +- celt_sources += [ +- 'x86/x86cpu.c', +- 'x86/x86_celt_map.c', +- 'x86/pitch_sse.c', +- ] +-endif ++celt_sse_sources = [ ++ 'x86/x86cpu.c', ++ 'x86/x86_celt_map.c', ++ 'x86/pitch_sse.c', ++] + +-if may_have_sse2 +- celt_sources += [ +- 'x86/pitch_sse2.c', +- 'x86/vq_sse2.c', +- ] +-endif ++celt_sse2_sources = [ ++ 'x86/pitch_sse2.c', ++ 'x86/vq_sse2.c', ++] + +-if may_have_sse4_1 +- celt_sources += [ +- 'x86/celt_lpc_sse4_1.c', +- 'x86/pitch_sse4_1.c', +- ] +-endif ++celt_sse4_1_sources = [ ++ 'x86/celt_lpc_sse4_1.c', ++ 'x86/pitch_sse4_1.c', ++] + +-opus_armasm_lib = [] ++celt_neon_intr_sources = [ ++ 'arm/celt_neon_intr.c', ++ 'arm/pitch_neon_intr.c', ++] + +-if host_machine.cpu_family() == 'arm' # was: cpu_arm # FIXME: should only be used if intrinsics or asm is enabled ++celt_static_libs = [] ++ ++foreach intr_name : ['sse', 'sse2', 'sse4_1', 'neon_intr'] ++ have_intr = get_variable('have_' + intr_name) ++ if not have_intr ++ continue ++ endif ++ ++ intr_sources = get_variable('celt_@0@_sources'.format(intr_name)) ++ intr_args = get_variable('opus_@0@_args'.format(intr_name), []) ++ celt_static_libs += static_library('celt_' + intr_name, intr_sources, ++ c_args: intr_args, ++ include_directories: opus_includes, ++ install: false) ++endforeach ++ ++have_arm_intrinsics_or_asm = have_arm_ne10 ++if (intrinsics_support.length() + asm_optimization.length() + inline_optimization.length()) > 0 ++ have_arm_intrinsics_or_asm = true ++endif ++ ++if host_cpu_family in ['arm', 'aarch64'] and have_arm_intrinsics_or_asm + celt_sources += [ + 'arm/armcpu.c', + 'arm/arm_celt_map.c', + ] +- if may_have_neon +- celt_sources += [ +- 'arm/celt_neon_intr.c', +- ] +- endif + if have_arm_ne10 + celt_sources += [ +- 'arm/celt_ne10_fft.c', +- 'arm/celt_ne10_mdct.c', ++ 'arm/celt_fft_ne10.c', ++ 'arm/celt_mdct_ne10.c', + ] + endif + if opus_arm_external_asm +- # FIXME: arm2gnu.pl stuff? +- celt_sources_arm_asm = [ +- 'arm/celt_pitch_xcorr_arm.s', +- ] ++ arm2gnu = [find_program('arm/arm2gnu.pl')] + arm2gnu_args ++ celt_sources_arm_asm = configure_file(input: 'arm/celt_pitch_xcorr_arm.s', ++ output: '@BASENAME@-gnu.S', ++ command: arm2gnu + ['@INPUT@'], ++ capture: true) + celt_arm_armopts_s = configure_file(input: 'arm/armopts.s.in', + output: 'arm/armopts.s', + configuration: opus_conf) +- opus_armasm_lib = static_library('opus-armasm', ++ celt_static_libs += static_library('celt-armasm', + celt_arm_armopts_s, celt_sources_arm_asm, + install: false) + endif + endif + + celt_c_args = [] +-if host_machine.system() == 'windows' ++if host_system == 'windows' + celt_c_args += ['-DDLL_EXPORT'] + endif + + celt_lib = static_library('opus-celt', + celt_sources, +- c_args: opus_c_args + celt_c_args, ++ c_args: celt_c_args, + include_directories: opus_includes, +- link_with: opus_armasm_lib, ++ link_whole: celt_static_libs, + dependencies: libm, + install: false) +diff --git a/celt/tests/meson.build b/celt/tests/meson.build +index f6d08d62..3088d195 100644 +--- a/celt/tests/meson.build ++++ b/celt/tests/meson.build +@@ -17,8 +17,8 @@ endif + foreach test_name : tests + exe = executable(test_name, '@0@.c'.format(test_name), + include_directories : opus_includes, +- c_args : opus_c_args + test_args, +- link_with : [opus_armasm_lib, celt_lib], ++ c_args : test_args, ++ link_with : [celt_lib, celt_static_libs], + dependencies : libm, + install : false) + test(test_name, exe) +diff --git a/include/meson.build b/include/meson.build +index 9f41b03a..78c5c76d 100644 +--- a/include/meson.build ++++ b/include/meson.build +@@ -1,6 +1,7 @@ + opus_headers = [ + 'opus.h', + 'opus_multistream.h', ++ 'opus_projection.h', + 'opus_types.h', + 'opus_defines.h', + ] +diff --git a/meson.build b/meson.build +index c18e9a50..c7d8ad11 100644 +--- a/meson.build ++++ b/meson.build +@@ -1,12 +1,18 @@ +-# Based on git v1.2.1-35-geee68982 ++# Based on git v1.3.1-64-g484af258 ++# FIXME: use update_version to set version: + project('opus', 'c', +- version: '1.2.1', +- meson_version: '>= 0.47.0', +- default_options: ['warning_level=1', ++ version: '1.3.1', ++ meson_version: '>=0.54.0', ++ default_options: ['warning_level=2', + 'c_std=gnu99', + 'buildtype=debugoptimized']) + ++libversion = '0.8.0' ++macosversion = '9.0.0' ++ + cc = meson.get_compiler('c') ++host_system = host_machine.system() ++host_cpu_family = host_machine.cpu_family() + + opus_includes = include_directories('.', 'include', 'celt', 'silk') + opus_public_includes = include_directories('include') +@@ -14,25 +20,32 @@ opus_public_includes = include_directories('include') + add_project_arguments('-DOPUS_BUILD', language: 'c') + add_project_arguments('-DHAVE_CONFIG_H', language: 'c') + +-if host_machine.system() == 'windows' +- add_project_arguments('-DWIN32', language: 'c') +- if cc.get_id() == 'msvc' ++if host_system == 'windows' ++ if cc.get_argument_syntax() == 'msvc' + add_project_arguments('-D_CRT_SECURE_NO_WARNINGS', language: 'c') + endif + endif + ++if cc.get_argument_syntax() == 'gnu' ++ add_project_arguments('-D_FORTIFY_SOURCE=2', language: 'c') ++endif ++ + # Check for extra compiler args + additional_c_args = [] +-if cc.get_id() != 'msvc' ++if cc.get_argument_syntax() != 'msvc' + additional_c_args += [ + '-fvisibility=hidden', +- '-Wall', +- '-Wextra', + '-Wcast-align', + '-Wnested-externs', + '-Wshadow', + '-Wstrict-prototypes', + ] ++ ++ # On Windows, -fstack-protector-strong adds a libssp-0.dll dependency and ++ # prevents static linking ++ if host_system != 'windows' ++ additional_c_args += ['-fstack-protector-strong'] ++ endif + endif + + foreach arg : additional_c_args +@@ -49,12 +62,9 @@ if cc.get_id() == 'msvc' + # NOTE: Only add warnings here if you are sure they're spurious + add_project_arguments('/wd4035', '/wd4715', '/wd4116', '/wd4046', '/wd4068', + '/wd4820', '/wd4244', '/wd4255', '/wd4668', +- #'/FImsvc_recommended_pragmas.h', + language : 'c') + endif + +-opus_c_args = [] +- + # FIXME: CURRENT_VERSION from git script, so e.g. 1.1.1-rc-71-gc43b1bc + opus_version = meson.project_version() + +@@ -74,6 +84,7 @@ libm = cc.find_library('m', required : false) + opus_conf.set('HAVE_LRINTF', cc.has_function('lrintf', prefix: '#include <math.h>', dependencies: libm)) + opus_conf.set('HAVE_LRINT', cc.has_function('lrint', prefix: '#include <math.h>', dependencies: libm)) + opus_conf.set('HAVE___MALLOC_HOOK', cc.has_function('__malloc_hook', prefix: '#include <malloc.h>')) ++opus_conf.set('HAVE_STDINT_H', cc.check_header('stdint.h')) + + # Check for restrict keyword + restrict_tmpl = ''' +@@ -103,9 +114,8 @@ if not cc.compiles(restrict_tmpl.format('restrict'), name : 'restrict keyword') + endif + + # Check for C99 variable-size arrays, or alloca() as fallback +-msg_c99_var_arrays = 'no' +-msg_use_alloca = 'no' +-if false and cc.compiles('''static int x; ++msg_use_alloca = false ++if cc.compiles('''static int x; + char some_func (void) { + char a[++x]; + a[sizeof a - 1] = 0; +@@ -113,8 +123,7 @@ if false and cc.compiles('''static int x; + return a[0]; + }''', name : 'C99 variable-size arrays') + opus_conf.set('VAR_ARRAYS', 1) +- msg_c99_var_arrays = 'yes' +- msg_use_alloca = 'no (using C99 variable-size arrays instead)' ++ msg_use_alloca = 'NO (using C99 variable-size arrays instead)' + elif cc.compiles('''#include <alloca.h> + void some_func (void) { + int foo=10; +@@ -122,7 +131,7 @@ elif cc.compiles('''#include <alloca.h> + }''', name : 'alloca (alloca.h)') + opus_conf.set('USE_ALLOCA', true) + opus_conf.set('HAVE_ALLOCA_H', true) +- msg_use_alloca = 'yes' ++ msg_use_alloca = true + elif cc.compiles('''#include <malloc.h> + #include <stdlib.h> + void some_func (void) { +@@ -130,7 +139,7 @@ elif cc.compiles('''#include <malloc.h> + int * array = alloca(foo); + }''', name : 'alloca (std)') + opus_conf.set('USE_ALLOCA', true) +- msg_use_alloca = 'yes' ++ msg_use_alloca = true + endif + + opts = [ +@@ -139,7 +148,9 @@ opts = [ + [ 'custom-modes', 'CUSTOM_MODES' ], + [ 'float-approx', 'FLOAT_APPROX' ], + [ 'assertions', 'ENABLE_ASSERTIONS' ], ++ [ 'hardening', 'ENABLE_HARDENING' ], + [ 'fuzzing', 'FUZZING' ], ++ [ 'check-asm', 'OPUS_CHECK_ASM' ], + ] + + foreach opt : opts +@@ -151,11 +162,11 @@ foreach opt : opts + set_variable('opt_' + opt[0].underscorify(), opt_foo) + endforeach + +-enable_asm = not get_option('disable-asm') +-enable_rtcd = not get_option('disable-rtcd') +-enable_intrinsics = get_option('enable-intrinsics') +-disable_extra_programs = get_option('disable-extra-programs') +-disable_tests = get_option('disable-tests') ++opt_asm = get_option('asm') ++opt_rtcd = get_option('rtcd') ++opt_intrinsics = get_option('intrinsics') ++extra_programs = get_option('extra-programs') ++opt_tests = get_option('tests') + + disable_float_api = not get_option('float-api') + if disable_float_api +@@ -172,8 +183,7 @@ if opt_custom_modes + pc_build = pc_build + ', custom modes' + endif + +-rtcd_support = 'no' +-cpu_arm = false # FIXME: check, unused ++rtcd_support = [] + opus_arm_external_asm = false + + asm_tmpl = ''' +@@ -182,12 +192,11 @@ int main (int argc, char ** argv) { + return 0; + }''' + +-asm_optimization='none' +-if enable_asm +- inline_optimization='No inline ASM for your platform, please send patches' +- # Currently we only have asm for fixed-point +- if host_machine.cpu_family() == 'arm' and opt_fixed_point +- cpu_arm = true ++asm_optimization = [] ++inline_optimization = [] ++if not opt_asm.disabled() ++ # Currently we only have inline asm for fixed-point ++ if host_cpu_family == 'arm' and opt_fixed_point + opus_conf.set('OPUS_ARM_ASM', true) + + # Check if compiler supports gcc-style inline assembly +@@ -197,41 +206,41 @@ if enable_asm + #endif + #endif + __asm__ (""::)''', +- name : 'Compiler supports gcc-style inline assembly') +- inline_optimization = 'ARM' ++ name : 'compiler supports gcc-style inline assembly') + + opus_conf.set('OPUS_ARM_INLINE_ASM', 1) + + # AS_ASM_ARM_EDSP + if cc.compiles(asm_tmpl.format('qadd r3,r3,r3'), +- name : 'Assembler supports EDSP instructions on ARM') ++ name : 'assembler supports EDSP instructions on ARM') + opus_conf.set('OPUS_ARM_INLINE_EDSP', 1) +- inline_optimization = inline_optimization + ' (ESDP)' ++ inline_optimization += ['ESDP'] + endif + + # AS_ASM_ARM_MEDIA + if cc.compiles(asm_tmpl.format('shadd8 r3,r3,r3'), +- name : 'Assembler supports ARMv6 media instructions on ARM') ++ name : 'assembler supports ARMv6 media instructions on ARM') + opus_conf.set('OPUS_ARM_INLINE_MEDIA', 1) +- inline_optimization = inline_optimization + ' (Media)' ++ inline_optimization += ['Media'] + endif + + # AS_ASM_ARM_NEON + if cc.compiles(asm_tmpl.format('vorr d0,d0,d0'), +- name : 'Assembler supports NEON instructions on ARM') ++ name : 'assembler supports NEON instructions on ARM') + opus_conf.set('OPUS_ARM_INLINE_NEON', 1) +- inline_optimization = inline_optimization + ' (NEON)' ++ inline_optimization += ['NEON'] + endif +- else +- inline_optimization = 'disabled' + endif + + # We need Perl to translate RVCT-syntax asm to gas syntax +- # FIXME: for now we just error out if no perl is found +- perl = find_program('perl', required : true) ++ perl = find_program('perl', required: get_option('asm')) + if perl.found() + opus_arm_external_asm = true +- asm_optimization = 'ARM' ++ # opus_arm_presume_* mean we can and will use those instructions ++ # directly without doing runtime CPU detection. ++ # opus_arm_may_have_* mean we can emit those instructions, but we can ++ # only use them after runtime detection. ++ # The same rules apply for x86 assembly and intrinsics. + + opus_arm_presume_edsp = opus_conf.has('OPUS_ARM_INLINE_EDSP') + opus_arm_may_have_edsp = opus_arm_presume_edsp +@@ -242,7 +251,7 @@ if enable_asm + opus_arm_presume_neon = opus_conf.has('OPUS_ARM_INLINE_NEON') + opus_arm_may_have_neon = opus_arm_presume_neon + +- if enable_rtcd ++ if not opt_rtcd.disabled() + if not opus_arm_may_have_edsp + message('Trying to force-enable armv5e EDSP instructions...') + # AS_ASM_ARM_EDSP_FORCE +@@ -261,146 +270,142 @@ if enable_asm + endif + endif + +- rtcd_support = '' + if opus_arm_may_have_edsp + opus_conf.set('OPUS_ARM_MAY_HAVE_EDSP', 1) + if opus_arm_presume_edsp + opus_conf.set('OPUS_ARM_PRESUME_EDSP', 1) +- asm_optimization = asm_optimization + ' (EDSP)' ++ asm_optimization += ['EDSP'] + else +- rtcd_support = rtcd_support + ' (EDSP)' ++ rtcd_support += ['EDSP'] + endif + endif + if opus_arm_may_have_media + opus_conf.set('OPUS_ARM_MAY_HAVE_MEDIA', 1) + if opus_arm_presume_media + opus_conf.set('OPUS_ARM_PRESUME_MEDIA', 1) +- asm_optimization = asm_optimization + ' (Media)' ++ asm_optimization += ['Media'] + else +- rtcd_support = rtcd_support + ' (Media)' ++ rtcd_support += ['Media'] + endif + endif + if opus_arm_may_have_neon + opus_conf.set('OPUS_ARM_MAY_HAVE_NEON', 1) + if opus_arm_presume_neon + opus_conf.set('OPUS_ARM_PRESUME_NEON', 1) +- asm_optimization = asm_optimization + ' (NEON)' ++ asm_optimization += ['NEON'] + else +- rtcd_support = rtcd_support + ' (NEON)' ++ rtcd_support += ['NEON'] + endif + endif + +- # Make sure turning on RTCD gets us at least one instruction set +- if rtcd_support != '' +- rtcd_support = 'ARM ' + rtcd_support ++ if cc.get_define('__APPLE__') ++ arm2gnu_args = ['--apple'] + else +- rtcd_support = 'no' ++ arm2gnu_args = [] + endif ++ endif # found perl ++ else # arm + enable fixed point ++ if opt_asm.enabled() ++ error('asm option is enabled, but no assembly support for ' + host_cpu_family) ++ endif ++ endif ++endif # enable asm ++ ++# Check whether we require assembly and we support assembly on this arch, ++# but none were detected. Can happen because of incorrect compiler flags, such ++# as missing -mfloat-abi=softfp on ARM32 softfp architectures. ++if opt_asm.enabled() and (asm_optimization.length() + inline_optimization.length()) == 0 ++ error('asm option was enabled, but no assembly support was detected') ++endif + +- # Check for apple-style tools +- if cc.compiles('''#ifndef __APPLE__ +- #error not apple +- #endif''', name : 'Apple-style tools') +- arm2gnu_params = '--apple' # FIXME: use somewhere ++# XXX: NEON has hardfp vs softfp compiler configuration issues ++# When targeting ARM32 softfp, we sometimes need to explicitly pass ++# -mfloat-abi=softfp to enable NEON. F.ex., on Android. It should ++# be set in the cross file. ++arm_neon_intr_link_args = ['-mfpu=neon'] ++ ++have_sse = false ++have_sse2 = false ++have_sse4_1 = false ++have_avx = false # no avx opus code yet ++have_neon_intr = false ++ ++intrinsics_support = [] ++if not opt_intrinsics.disabled() ++ if host_cpu_family in ['arm', 'aarch64'] ++ # Check for ARMv7/AArch64 neon intrinsics ++ intrin_check = ''' ++ #include <arm_neon.h> ++ int main (void) { ++ static float32x4_t A0, A1, SUMM; ++ SUMM = vmlaq_f32(SUMM, A0, A1); ++ return (int)vgetq_lane_f32(SUMM, 0); ++ }''' ++ intrin_name = 'ARMv7/AArch64 NEON' ++ if cc.links(intrin_check, ++ name: 'compiler supports @0@ intrinsics'.format(intrin_name)) ++ opus_arm_presume_neon_intr = true ++ opus_arm_may_have_neon_intr = true ++ else ++ opus_arm_presume_neon_intr = false ++ if cc.links(intrin_check, ++ args: arm_neon_intr_link_args, ++ name: 'compiler supports @0@ intrinsics with @1@'.format(intrin_name, ' '.join(arm_neon_intr_link_args))) ++ opus_arm_may_have_neon_intr = true + else +- arm2gnu_params = '' ++ opus_arm_may_have_neon_intr = false + endif +- endif # found perl +- endif # arm + enable fixed point +-else # enable asm +- inline_optimization='disabled' +- asm_optimization='disabled' +-endif ++ endif + +-intrinsics_foo=''' +-m4_define([DEFAULT_ARM_NEON_INTR_CFLAGS], [-mfpu=neon]) +-# With GCC on ARM32 softfp architectures (e.g. Android, or older Ubuntu) you need to specify +-# -mfloat-abi=softfp for -mfpu=neon to work. However, on ARM32 hardfp architectures (e.g. newer Ubuntu), +-# this option will break things. +- +-# As a heuristic, if host matches arm*eabi* but not arm*hf*, it's probably soft-float. +-m4_define([DEFAULT_ARM_NEON_SOFTFP_INTR_CFLAGS], [-mfpu=neon -mfloat-abi=softfp]) +- +-AS_CASE([$host], +- [arm*hf*], [AS_VAR_SET([RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS], "DEFAULT_ARM_NEON_INTR_CFLAGS")], +- [arm*eabi*], [AS_VAR_SET([RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS], "DEFAULT_ARM_NEON_SOFTFP_INTR_CFLAGS")], +- [AS_VAR_SET([RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS], "DEFAULT_ARM_NEON_INTR_CFLAGS")]) +- +-AC_ARG_VAR([ARM_NEON_INTR_CFLAGS], [C compiler flags to compile ARM NEON intrinsics @<:@default=]DEFAULT_ARM_NEON_INTR_CFLAGS / DEFAULT_ARM_NEON_SOFTFP_INTR_CFLAGS[@:>@]) +- +-AS_VAR_SET_IF([ARM_NEON_INTR_CFLAGS], [], [AS_VAR_SET([ARM_NEON_INTR_CFLAGS], ["$RESOLVED_DEFAULT_ARM_NEON_INTR_CFLAGS"])]) +-''' +- +-may_have_sse = false +-may_have_sse2 = false +-may_have_sse4_1 = false +-may_have_avx = false +- +-may_have_neon = false # FIXME: merge with / fixup opus_arm_may_have_neon +- +-if enable_intrinsics +- intrinsics_support = '' +- rtcd_support = '' +- if host_machine.cpu_family().startswith('arm') +-foo1_arm=''' +- AS_CASE([$host_cpu], +- [arm*], +- [ +- cpu_arm=yes +- OPUS_CHECK_INTRINSICS( +- [ARM Neon], +- [$ARM_NEON_INTR_CFLAGS], +- [OPUS_ARM_MAY_HAVE_NEON_INTR], +- [OPUS_ARM_PRESUME_NEON_INTR], +- [[#include <arm_neon.h> +- ]], +- [[ +- static float32x4_t A0, A1, SUMM; +- SUMM = vmlaq_f32(SUMM, A0, A1); +- ]] +- ) +- AS_IF([test x"$OPUS_ARM_MAY_HAVE_NEON_INTR" = x"1" && test x"$OPUS_ARM_PRESUME_NEON_INTR" != x"1"], +- [ +- OPUS_ARM_NEON_INTR_CFLAGS="$ARM_NEON_INTR_CFLAGS" +- AC_SUBST([OPUS_ARM_NEON_INTR_CFLAGS]) +- ] +- ) +- +- AS_IF([test x"$OPUS_ARM_MAY_HAVE_NEON_INTR" = x"1"], +- [ +- AC_DEFINE([OPUS_ARM_MAY_HAVE_NEON_INTR], 1, [Compiler supports ARMv7 Neon Intrinsics]) +- intrinsics_support="$intrinsics_support (Neon_Intrinsics)" +- +- AS_IF([test x"enable_rtcd" != x"" && test x"$OPUS_ARM_PRESUME_NEON_INTR" != x"1"], +- [rtcd_support="$rtcd_support (ARMv7_Neon_Intrinsics)"]) +- +- AS_IF([test x"$OPUS_ARM_PRESUME_NEON_INTR" = x"1"], +- [AC_DEFINE([OPUS_ARM_PRESUME_NEON_INTR], 1, [Define if binary requires NEON intrinsics support])]) +- +- OPUS_PATH_NE10() +- AS_IF([test x"$NE10_LIBS" != x""], +- [ +- intrinsics_support="$intrinsics_support (NE10)" +- AS_IF([test x"enable_rtcd" != x"" \ +- && test x"$OPUS_ARM_PRESUME_NEON_INTR" != x"1"], +- [rtcd_support="$rtcd_support (NE10)"]) +- ]) +- +- AS_IF([test x"$rtcd_support" = x""], +- [rtcd_support=no]) +- +- AS_IF([test x"$intrinsics_support" = x""], +- [intrinsics_support=no], +- [intrinsics_support="arm$intrinsics_support"]) +- ], +- [ +- AC_MSG_WARN([Compiler does not support ARM intrinsics]) +- intrinsics_support=no +- ]) +- ], +-''' +- elif host_machine.cpu_family().startswith('x86') +- # FIXME: allow external override/specification of the flags ++ if opus_arm_may_have_neon_intr ++ have_neon_intr = true ++ intrinsics_support += [intrin_name] ++ opus_conf.set('OPUS_ARM_MAY_HAVE_NEON_INTR', 1) ++ if opus_arm_presume_neon_intr ++ opus_conf.set('OPUS_ARM_PRESUME_NEON_INTR', 1) ++ else ++ rtcd_support += [intrin_name] ++ opus_neon_intr_args = arm_neon_intr_link_args ++ endif ++ else ++ message('Compiler does not support @0@ intrinsics'.format(intrin_name)) ++ endif ++ ++ # Check for aarch64 neon intrinsics ++ intrin_check = ''' ++ #include <arm_neon.h> ++ int main (void) { ++ static int32_t IN; ++ static int16_t OUT; ++ OUT = vqmovns_s32(IN); ++ }''' ++ intrin_name = 'AArch64 NEON' ++ if cc.links(intrin_check, ++ name: 'compiler supports @0@ intrinsics'.format(intrin_name)) ++ opus_arm_presume_aarch64_neon_intr = true ++ opus_arm_may_have_aarch64_neon_intr = true ++ else ++ opus_arm_presume_aarch64_neon_intr = false ++ if cc.links(intrin_check, ++ args: arm_neon_intr_link_args, ++ name: 'compiler supports @0@ intrinsics with @1@'.format(intrin_name, ' '.join(arm_neon_intr_link_args))) ++ opus_arm_may_have_aarch64_neon_intr = true ++ else ++ opus_arm_may_have_aarch64_neon_intr = false ++ endif ++ endif ++ ++ if opus_arm_may_have_aarch64_neon_intr ++ intrinsics_support += [intrin_name] ++ opus_conf.set('OPUS_X86_MAY_HAVE_AARCH64_NEON_INTR', 1) ++ if opus_arm_presume_aarch64_neon_intr ++ opus_conf.set('OPUS_X86_PRESUME_AARCH64_NEON_INTR', 1) ++ endif ++ else ++ message('Compiler does not support @0@ intrinsics'.format(intrin_name)) ++ endif ++ elif host_cpu_family in ['x86', 'x86_64'] ++ # XXX: allow external override/specification of the flags + x86_intrinsics = [ + [ 'SSE', 'xmmintrin.h', '__m128', '_mm_setzero_ps()', '-msse' ], + [ 'SSE2', 'emmintrin.h', '__m128i', '_mm_setzero_si128()', '-msse2' ], +@@ -414,69 +419,69 @@ foo1_arm=''' + static @1@ mtest; + mtest = @2@; + return *((unsigned char *) &mtest) != 0; +- }'''.format(intrin.get(1),intrin.get(2),intrin.get(3)) +- intrin_name = intrin.get(0) +- intrin_link_args = intrin.get(4) +- if cc.links(intrin_check, name : 'if compiler supports @0@ intrinsics'.format(intrin_name)) ++ }'''.format(intrin[1],intrin[2],intrin[3]) ++ intrin_name = intrin[0] ++ intrin_args = intrin[4] ++ if cc.links(intrin_check, name : 'compiler supports @0@ intrinsics'.format(intrin_name)) + may_have_intrin = true + presume_intrin = true + else + presume_intrin = false + if cc.links(intrin_check, +- args : intrin_link_args, +- name : 'if compiler supports @0@ intrinsics with @1@'.format(intrin_name,intrin_link_args)) ++ args : intrin_args, ++ name : 'compiler supports @0@ intrinsics with @1@'.format(intrin_name, intrin_args)) + may_have_intrin = true +- # FIXME: add args to some var and use it later + else + may_have_intrin = false + endif + endif +- set_variable('may_have_' + intrin_name.to_lower().underscorify(), may_have_intrin) +- # FIXME: unused: set_variable('presume_' + intrin_name.to_lower().underscorify(), presume_intrin) + if may_have_intrin +- intrinsics_support = intrinsics_support + ' ' + intrin_name ++ intrinsics_support += [intrin_name] ++ intrin_lower_name = intrin_name.to_lower().underscorify() ++ set_variable('have_' + intrin_lower_name, true) + opus_conf.set('OPUS_X86_MAY_HAVE_' + intrin_name.underscorify(), 1) + if presume_intrin + opus_conf.set('OPUS_X86_PRESUME_' + intrin_name.underscorify(), 1) + else +- rtcd_support = rtcd_support + ' ' + intrin_name +- opus_c_args += [ intrin_link_args ] ++ rtcd_support += [intrin_name] ++ set_variable('opus_@0@_args'.format(intrin_lower_name), intrin_args) + endif + else +- message('Warning: Compiler does not support @0@ intrinsics'.format(intrin_name)) ++ message('Compiler does not support @0@ intrinsics'.format(intrin_name)) + endif + endforeach + +- if intrinsics_support == '' +- intrinsics_support = 'no' +- else +- intrinsics_support = 'x86' + intrinsics_support +- endif +- +- if rtcd_support == '' +- rtcd_support = 'no' +- else +- rtcd_support = 'x86' + rtcd_support +- endif +- +- if enable_rtcd and rtcd_support != 'no' ++ if not opt_rtcd.disabled() + get_cpuid_by_asm = false + cpuid_asm_code = ''' + #include <stdio.h> + int main (int argc, char ** argv) { +- unsigned int CPUInfo0; +- unsigned int CPUInfo1; +- unsigned int CPUInfo2; +- unsigned int CPUInfo3; +- unsigned int InfoType; +- __asm__ __volatile__ ( +- "cpuid": +- "=a" (CPUInfo0), +- "=b" (CPUInfo1), +- "=c" (CPUInfo2), +- "=d" (CPUInfo3) : +- "a" (InfoType), "c" (0) +- ); ++ unsigned int CPUInfo0; ++ unsigned int CPUInfo1; ++ unsigned int CPUInfo2; ++ unsigned int CPUInfo3; ++ unsigned int InfoType; ++ #if defined(__i386__) && defined(__PIC__) ++ __asm__ __volatile__ ( ++ "xchg %%ebx, %1\n" ++ "cpuid\n" ++ "xchg %%ebx, %1\n": ++ "=a" (CPUInfo0), ++ "=r" (CPUInfo1), ++ "=c" (CPUInfo2), ++ "=d" (CPUInfo3) : ++ "a" (InfoType), "c" (0) ++ ); ++ #else ++ __asm__ __volatile__ ( ++ "cpuid": ++ "=a" (CPUInfo0), ++ "=b" (CPUInfo1), ++ "=c" (CPUInfo2), ++ "=d" (CPUInfo3) : ++ "a" (InfoType), "c" (0) ++ ); ++ #endif + return 0; + }''' + cpuid_c_code = ''' +@@ -490,28 +495,55 @@ foo1_arm=''' + __get_cpuid(InfoType, &CPUInfo0, &CPUInfo1, &CPUInfo2, &CPUInfo3); + return 0; + }''' ++ cpuid_msvc_code = ''' ++ #include <intrin.h> ++ int main (void) { ++ int CPUInfo, InfoType; ++ __cpuid(&CPUInfo, InfoType); ++ }''' + if cc.links(cpuid_asm_code, name : 'Get X86 CPU info via inline assembly') + opus_conf.set('CPU_INFO_BY_ASM', 1) + elif cc.links(cpuid_c_code, name : 'Get X86 CPU info via C method') + opus_conf.set('CPU_INFO_BY_C', 1) ++ elif cc.get_define('_MSC_VER') != '' and cc.links(cpuid_msvc_code) ++ message('Getting X86 CPU info via __cpuid') + else +- error('No supported Get CPU Info method, please disable intrinsics') ++ if opt_intrinsics.enabled() and opt_rtcd.enabled() ++ error('intrinsics and rtcd options are enabled, but no Get CPU Info method detected') ++ endif ++ warning('Get CPU Info method not detected, no rtcd for intrinsics') + endif +- endif ++ endif # opt_rtcd + else +- message('Warning: No intrinsics support for your architecture (@0@)'.format(host_machine.get_cpu())) +- intrinsics_support = 'no' ++ if opt_intrinsics.enabled() ++ error('intrinsics option enabled, but no intrinsics support for ' + host_machine.get_cpu()) ++ endif ++ warning('No intrinsics support for ' + host_machine.get_cpu()) + endif +-else +- intrinsics_support = 'no' + endif + +-if enable_rtcd +- if rtcd_support != 'no' ++# Check whether we require intrinsics and we support intrinsics on this arch, ++# but none were detected. Can happen because of incorrect compiler flags, such ++# as missing -mfloat-abi=softfp on ARM32 softfp architectures. ++if opt_intrinsics.enabled() and intrinsics_support.length() == 0 ++ error('intrinsics option was enabled, but none were detected') ++endif ++ ++if opt_rtcd.disabled() ++ rtcd_support = 'disabled' ++else ++ if rtcd_support.length() > 0 + opus_conf.set('OPUS_HAVE_RTCD', 1) ++ else ++ if intrinsics_support.length() == 0 ++ rtcd_support = 'none' ++ if opt_rtcd.enabled() ++ error('rtcd option is enabled, but no support for intrinsics or assembly is available') ++ endif ++ else ++ rtcd_support = 'not needed' ++ endif + endif +-else +- rtcd_support = 'disabled' + endif + + subdir('include') +@@ -521,7 +553,7 @@ subdir('src') + + configure_file(output: 'config.h', configuration: opus_conf) + +-if not disable_tests ++if not opt_tests.disabled() + subdir('celt/tests') + subdir('silk/tests') + subdir('tests') +@@ -537,9 +569,7 @@ pkgconf.set('libdir', '${prefix}/@0@'.format(get_option('libdir'))) + pkgconf.set('includedir', '${prefix}/@0@'.format(get_option('includedir'))) + pkgconf.set('VERSION', opus_version) + pkgconf.set('PC_BUILD', pc_build) +-if libm.found() +- pkgconf.set('LIBM', '-lm') +-endif ++pkgconf.set('LIBM', libm.found() ? '-lm' : '') + + pkg_install_dir = '@0@/pkgconfig'.format(get_option('libdir')) + +@@ -555,54 +585,65 @@ configure_file(input : 'opus.pc.in', + # install : false) + + doxygen = find_program('doxygen', required: get_option('docs')) +-have_doxygen = doxygen.found() +-if have_doxygen +- msg_doc = 'yes' ++if doxygen.found() + subdir('doc') +-else +- if get_option('docs').disabled() +- msg_doc = 'disabled' +- else +- msg_doc = 'not found' +- endif + endif + +-# FIXME: use bool.to_string('yes', 'no') here once meson 0.31 is out +-# FIXME: only print the ninja help if ninja is used as backend +-msg_c99_lrintf = opus_conf.has('HAVE_LRINTF').to_string() +-message(''' +------------------------------------------------------------------------- +- opus @0@: Automatic configuration OK. +- +- Compiler support: +- +- C99 var arrays: ................ @1@ +- C99 lrintf: .................... @2@ +- Use alloca: .................... @3@ +- +- General configuration: +- +- Floating point support: ........ @4@ +- Fast float approximations: ..... @5@ +- Fixed point debugging: ......... @6@ +- Inline Assembly Optimizations: . @7@ +- External Assembly Optimizations: @8@ +- Intrinsics Optimizations.......: @9@ +- Run-time CPU detection: ........ @10@ +- Custom modes: .................. @11@ +- Assertion checking: ............ @12@ +- Fuzzing: ....................... @13@ +- +- API documentation: ............. @14@ +- Extra programs: ................ @15@ +- Tests: ......................... @16@ +------------------------------------------------------------------------- +- +- Type "ninja; ninja install" to compile and install +- Type "ninja test" to run the test suite +-'''.format(meson.project_version(), msg_c99_var_arrays, msg_c99_lrintf, +- msg_use_alloca, not opt_fixed_point, opt_float_approx, +- opt_fixed_point_debug, inline_optimization, asm_optimization, +- intrinsics_support, rtcd_support, opt_custom_modes, +- opt_assertions, opt_fuzzing, msg_doc, +- not disable_extra_programs, not disable_tests)) ++summary( ++ { ++ 'C99 var arrays': opus_conf.has('VAR_ARRAYS'), ++ 'C99 lrintf': opus_conf.has('HAVE_LRINTF'), ++ 'Use alloca': msg_use_alloca, ++ }, ++ section: 'Compiler support', ++ bool_yn: true, ++ list_sep: ', ', ++) ++ ++# Parse optimization status ++foreach status : [['inline_optimization', opt_asm], ++ ['asm_optimization', opt_asm], ++ ['intrinsics_support', opt_intrinsics]] ++ res = status[0] ++ opt = status[1] ++ resval = get_variable(res) ++ if opt.disabled() ++ set_variable(res, 'disabled') ++ elif resval.length() == 0 ++ if host_cpu_family not in ['arm', 'aarch64', 'x86', 'x86_64'] ++ set_variable(res, 'No optimizations for your platform, please send patches') ++ else ++ set_variable(res, 'none') ++ endif ++ endif ++endforeach ++ ++summary( ++ { ++ 'Floating point support': not opt_fixed_point, ++ 'Fast float approximations': opt_float_approx, ++ 'Fixed point debugging': opt_fixed_point_debug, ++ 'Inline assembly optimizations': inline_optimization, ++ 'External assembly optimizations': asm_optimization, ++ 'Intrinsics optimizations': intrinsics_support, ++ 'Run-time CPU detection': rtcd_support, ++ }, ++ section: 'Optimizations', ++ bool_yn: true, ++ list_sep: ', ', ++) ++summary( ++ { ++ 'Custom modes': opt_custom_modes, ++ 'Assertions': opt_assertions, ++ 'Hardening': opt_hardening, ++ 'Fuzzing': opt_fuzzing, ++ 'Check ASM': opt_check_asm, ++ 'API documentation': doxygen.found(), ++ 'Extra programs': not extra_programs.disabled(), ++ 'Tests': not opt_tests.disabled(), ++ }, ++ section: 'General configuration', ++ bool_yn: true, ++ list_sep: ', ', ++) +diff --git a/meson_options.txt b/meson_options.txt +index 21322ac5..360ff263 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -1,17 +1,21 @@ ++# Optimizations + option('fixed-point', type : 'boolean', value : false, description : 'Compile without floating point (for machines without a fast enough FPU') + option('fixed-point-debug', type : 'boolean', value : false, description : 'Debug fixed-point implementation') + option('float-api', type : 'boolean', value : true, description : 'Compile with or without the floating point API (for machines with no float library') +-option('custom-modes', type : 'boolean', value : false, description : 'Enable non-Opus modes, e.g. 44.1 kHz & 2^n frames') + option('float-approx', type : 'boolean', value : false, description : 'Enable fast approximations for floating point (not supported on all platforms)') +-option('disable-asm', type : 'boolean', value : false, description : 'Disable assembly optimizations') +-option('disable-rtcd', type : 'boolean', value : false, description : 'Disable run-time CPU capabilities detection') +-option('enable-intrinsics', type : 'boolean', value : false, description : 'Enable intrinsics optimizations for ARM(float) X86(fixed)') +-option('disable-extra-programs', type : 'boolean', value : false, description : 'Do not build extra programs (demo and tests)') +-option('assertions', type : 'boolean', value : false, description : 'Enable additional software error checking') ++option('rtcd', type : 'feature', value : 'auto', description : 'Run-time CPU capabilities detection') ++option('asm', type : 'feature', value : 'auto', description : 'Assembly optimizations for ARM (fixed-point)') ++option('intrinsics', type : 'feature', value : 'auto', description : 'Intrinsics optimizations for ARM NEON or x86') ++ ++option('custom-modes', type : 'boolean', value : false, description : 'Enable non-Opus modes, e.g. 44.1 kHz & 2^n frames') ++option('extra-programs', type : 'feature', value : 'auto', description : 'Extra programs (demo and tests)') ++option('assertions', type : 'boolean', value : false, description : 'Additional software error checking') ++option('hardening', type : 'boolean', value : true, description : 'Run-time checks that are cheap and safe for use in production') + option('fuzzing', type : 'boolean', value : false, description : 'Causes the encoder to make random decisions') +-option('disable-tests', type : 'boolean', value : false, description : 'Do not build tests') ++option('check-asm', type : 'boolean', value : false, description : 'Run bit-exactness checks between optimized and c implementations') + +-# feature options ++# common feature options ++option('tests', type : 'feature', value : 'auto', description : 'Build tests') + option('docs', type: 'feature', value: 'auto', description: 'Build API documentation') + + # other options +diff --git a/silk/meson.build b/silk/meson.build +index 1a1a0954..210887ec 100644 +--- a/silk/meson.build ++++ b/silk/meson.build +@@ -86,6 +86,18 @@ silk_sources_sse4_1 = [ + 'x86/VQ_WMat_EC_sse4_1.c', + ] + ++silk_sources_neon_intr = [ ++ 'arm/arm_silk_map.c', ++ 'arm/biquad_alt_neon_intr.c', ++ 'arm/LPC_inv_pred_gain_neon_intr.c', ++ 'arm/NSQ_del_dec_neon_intr.c', ++ 'arm/NSQ_neon.c', ++] ++ ++silk_sources_fixed_neon_intr = [ ++ 'fixed/arm/warped_autocorrelation_FIX_neon_intr.c', ++] ++ + silk_sources_fixed = [ + 'fixed/LTP_analysis_filter_FIX.c', + 'fixed/LTP_scale_ctrl_FIX.c', +@@ -150,20 +162,30 @@ silk_sources_float = [ + + if opt_fixed_point + silk_sources += silk_sources_fixed +- if may_have_sse4_1 +- silk_sources += silk_sources_sse4_1 +- silk_sources += silk_sources_fixed_sse4_1 +- endif + else + silk_sources += silk_sources_float +- if may_have_sse4_1 +- silk_sources += silk_sources_sse4_1 +- endif + endif + +-if host_machine.cpu_family() == 'arm' # was: cpu_arm # FIXME: should only be used if intrinsics or asm is enabled +- silk_sources += silk_sources_arm +-endif ++silk_includes = [opus_includes, include_directories('float', 'fixed')] ++silk_static_libs = [] ++ ++foreach intr_name : ['sse4_1', 'neon_intr'] ++ have_intr = get_variable('have_' + intr_name) ++ if not have_intr ++ continue ++ endif ++ ++ intr_sources = get_variable('silk_sources_' + intr_name) ++ if opt_fixed_point ++ intr_sources += get_variable('silk_sources_fixed_' + intr_name) ++ endif ++ ++ intr_args = get_variable('opus_@0@_args'.format(intr_name), []) ++ silk_static_libs += static_library('silk_' + intr_name, intr_sources, ++ c_args: intr_args, ++ include_directories: silk_includes, ++ install: false) ++endforeach + + silk_c_args = [] + if host_machine.system() == 'windows' +@@ -172,8 +194,8 @@ endif + + silk_lib = static_library('opus-silk', + silk_sources, +- c_args: opus_c_args + silk_c_args, +- include_directories: [opus_includes, include_directories('float', 'fixed')], +- #link_with: opus_armasm_lib, ++ c_args: silk_c_args, ++ include_directories: silk_includes, ++ link_whole: silk_static_libs, + dependencies: libm, + install: false) +diff --git a/silk/tests/meson.build b/silk/tests/meson.build +index 06cefe40..b7c70f75 100644 +--- a/silk/tests/meson.build ++++ b/silk/tests/meson.build +@@ -1,10 +1,8 @@ + exe = executable('test_unit_LPC_inv_pred_gain', + 'test_unit_LPC_inv_pred_gain.c', '../LPC_inv_pred_gain.c', + include_directories: opus_includes, +- c_args: opus_c_args, +- link_with: [opus_armasm_lib, celt_lib, silk_lib], ++ link_with: [celt_lib, celt_static_libs, silk_lib, silk_static_libs], + dependencies: libm, + install: false) + + test(test_name, exe) +- +diff --git a/src/meson.build b/src/meson.build +index 8fc463e1..f21e4277 100644 +--- a/src/meson.build ++++ b/src/meson.build +@@ -1,10 +1,13 @@ + opus_sources = [ ++ 'mapping_matrix.c', + 'opus.c', + 'opus_decoder.c', + 'opus_encoder.c', + 'opus_multistream.c', + 'opus_multistream_encoder.c', + 'opus_multistream_decoder.c', ++ 'opus_projection_encoder.c', ++ 'opus_projection_decoder.c', + 'repacketizer.c', + ] + +@@ -25,9 +28,9 @@ endif + + opus_lib = library('opus', + opus_sources, +-# FIXME version : libversion, +-# FIXME soversion : soversion, +- c_args: opus_c_args + opus_lib_c_args, ++ version: libversion, ++ darwin_versions: macosversion, ++ c_args: opus_lib_c_args, + include_directories: opus_includes, + link_with: [celt_lib, silk_lib], + dependencies: libm, +@@ -37,13 +40,10 @@ opus_dep = declare_dependency(link_with: opus_lib, + include_directories: opus_public_includes) + + # Extra uninstalled Opus programs +-if not disable_extra_programs +- extra_programs = ['opus_compare', 'opus_demo', 'repacketizer_demo'] +- +- foreach prog : extra_programs ++if not extra_programs.disabled() ++ foreach prog : ['opus_compare', 'opus_demo', 'repacketizer_demo'] + executable(prog, '@0@.c'.format(prog), + include_directories: opus_includes, +- c_args: opus_c_args, + link_with: opus_lib, + dependencies: libm, + install: false) +@@ -52,10 +52,9 @@ if not disable_extra_programs + if opt_custom_modes + executable('opus_custom_demo', '../celt/opus_custom_demo.c', + include_directories: opus_includes, +- c_args: opus_c_args, + link_with: opus_lib, + dependencies: libm, + install: false) + endif + +-endif # not disable_extra_programs ++endif +diff --git a/tests/meson.build b/tests/meson.build +index 9026ac30..5f3ac9df 100644 +--- a/tests/meson.build ++++ b/tests/meson.build +@@ -1,7 +1,7 @@ + # Tests that link to libopus + opus_tests = [ + ['test_opus_api'], +- ['test_opus_decode'], ++ ['test_opus_decode', [], 60], + ['test_opus_encode', 'opus_encode_regressions.c', 120], + ['test_opus_padding'], + ['test_opus_projection'], +@@ -10,12 +10,25 @@ opus_tests = [ + foreach t : opus_tests + test_name = t.get(0) + extra_srcs = t.get(1, []) +- timeout = t.get(2, 30) ++ ++ test_kwargs = {} ++ if t.length() > 2 ++ test_kwargs += {'timeout': t[2]} ++ endif ++ ++ exe_kwargs = {} ++ # This test uses private symbols ++ if test_name == 'test_opus_projection' ++ exe_kwargs = { ++ 'link_with': [celt_lib, silk_lib], ++ 'objects': opus_lib.extract_all_objects(), ++ } ++ endif ++ + exe = executable(test_name, '@0@.c'.format(test_name), extra_srcs, + include_directories: opus_includes, +- c_args: opus_c_args, +- link_with: opus_lib, +- dependencies: libm, +- install: false) +- test(test_name, exe, timeout: timeout) ++ dependencies: [libm, opus_dep], ++ install: false, ++ kwargs: exe_kwargs) ++ test(test_name, exe, kwargs: test_kwargs) + endforeach +-- +2.27.0.windows.1 + |