Initialize signal processing function pointers statically

The last run-time logic for selecting function pointers was removed in
May 2016, here: https://codereview.webrtc.org/1955413003

It would be even better if we could eliminate the function pointers
entirely and just have different implementations that we select at
compile time; I've left a TODO asking for this.

Bug: webrtc:9553
Change-Id: Ica71d71e19759da00967168f6479b7eb8b46c590
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/144053
Reviewed-by: Alessio Bazzica <alessiob@webrtc.org>
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28414}
diff --git a/audio/audio_level.cc b/audio/audio_level.cc
index 3b8df97..63b80a5 100644
--- a/audio/audio_level.cc
+++ b/audio/audio_level.cc
@@ -18,7 +18,6 @@
 
 AudioLevel::AudioLevel()
     : abs_max_(0), count_(0), current_level_full_range_(0) {
-  WebRtcSpl_Init();
 }
 
 AudioLevel::~AudioLevel() {}
diff --git a/common_audio/signal_processing/include/signal_processing_library.h b/common_audio/signal_processing/include/signal_processing_library.h
index 7b743f0..4e8bf4f 100644
--- a/common_audio/signal_processing/include/signal_processing_library.h
+++ b/common_audio/signal_processing/include/signal_processing_library.h
@@ -99,14 +99,6 @@
 // third party math functions
 #include "common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h"
 
-// Initialize SPL. Currently it contains only function pointer initialization.
-// If the underlying platform is known to be ARM-Neon (WEBRTC_HAS_NEON defined),
-// the pointers will be assigned to code optimized for Neon; otherwise, generic
-// C code will be assigned.
-// Note that this function MUST be called in any application that uses SPL
-// functions.
-void WebRtcSpl_Init(void);
-
 int16_t WebRtcSpl_GetScalingSquare(int16_t* in_vector,
                                    size_t in_vector_length,
                                    size_t times);
@@ -141,7 +133,7 @@
 //
 // Return value  : Maximum absolute value in vector.
 typedef int16_t (*MaxAbsValueW16)(const int16_t* vector, size_t length);
-extern MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16;
+extern const MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16;
 int16_t WebRtcSpl_MaxAbsValueW16C(const int16_t* vector, size_t length);
 #if defined(WEBRTC_HAS_NEON)
 int16_t WebRtcSpl_MaxAbsValueW16Neon(const int16_t* vector, size_t length);
@@ -158,7 +150,7 @@
 //
 // Return value  : Maximum absolute value in vector.
 typedef int32_t (*MaxAbsValueW32)(const int32_t* vector, size_t length);
-extern MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32;
+extern const MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32;
 int32_t WebRtcSpl_MaxAbsValueW32C(const int32_t* vector, size_t length);
 #if defined(WEBRTC_HAS_NEON)
 int32_t WebRtcSpl_MaxAbsValueW32Neon(const int32_t* vector, size_t length);
@@ -175,7 +167,7 @@
 //
 // Return value  : Maximum sample value in |vector|.
 typedef int16_t (*MaxValueW16)(const int16_t* vector, size_t length);
-extern MaxValueW16 WebRtcSpl_MaxValueW16;
+extern const MaxValueW16 WebRtcSpl_MaxValueW16;
 int16_t WebRtcSpl_MaxValueW16C(const int16_t* vector, size_t length);
 #if defined(WEBRTC_HAS_NEON)
 int16_t WebRtcSpl_MaxValueW16Neon(const int16_t* vector, size_t length);
@@ -192,7 +184,7 @@
 //
 // Return value  : Maximum sample value in |vector|.
 typedef int32_t (*MaxValueW32)(const int32_t* vector, size_t length);
-extern MaxValueW32 WebRtcSpl_MaxValueW32;
+extern const MaxValueW32 WebRtcSpl_MaxValueW32;
 int32_t WebRtcSpl_MaxValueW32C(const int32_t* vector, size_t length);
 #if defined(WEBRTC_HAS_NEON)
 int32_t WebRtcSpl_MaxValueW32Neon(const int32_t* vector, size_t length);
@@ -209,7 +201,7 @@
 //
 // Return value  : Minimum sample value in |vector|.
 typedef int16_t (*MinValueW16)(const int16_t* vector, size_t length);
-extern MinValueW16 WebRtcSpl_MinValueW16;
+extern const MinValueW16 WebRtcSpl_MinValueW16;
 int16_t WebRtcSpl_MinValueW16C(const int16_t* vector, size_t length);
 #if defined(WEBRTC_HAS_NEON)
 int16_t WebRtcSpl_MinValueW16Neon(const int16_t* vector, size_t length);
@@ -226,7 +218,7 @@
 //
 // Return value  : Minimum sample value in |vector|.
 typedef int32_t (*MinValueW32)(const int32_t* vector, size_t length);
-extern MinValueW32 WebRtcSpl_MinValueW32;
+extern const MinValueW32 WebRtcSpl_MinValueW32;
 int32_t WebRtcSpl_MinValueW32C(const int32_t* vector, size_t length);
 #if defined(WEBRTC_HAS_NEON)
 int32_t WebRtcSpl_MinValueW32Neon(const int32_t* vector, size_t length);
@@ -347,7 +339,7 @@
                                            int right_shifts,
                                            int16_t* out_vector,
                                            size_t length);
-extern ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound;
+extern const ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound;
 int WebRtcSpl_ScaleAndAddVectorsWithRoundC(const int16_t* in_vector1,
                                            int16_t in_vector1_scale,
                                            const int16_t* in_vector2,
@@ -514,7 +506,7 @@
                                  size_t dim_cross_correlation,
                                  int right_shifts,
                                  int step_seq2);
-extern CrossCorrelation WebRtcSpl_CrossCorrelation;
+extern const CrossCorrelation WebRtcSpl_CrossCorrelation;
 void WebRtcSpl_CrossCorrelationC(int32_t* cross_correlation,
                                  const int16_t* seq1,
                                  const int16_t* seq2,
@@ -663,7 +655,7 @@
                               size_t coefficients_length,
                               int factor,
                               size_t delay);
-extern DownsampleFast WebRtcSpl_DownsampleFast;
+extern const DownsampleFast WebRtcSpl_DownsampleFast;
 int WebRtcSpl_DownsampleFastC(const int16_t* data_in,
                               size_t data_in_length,
                               int16_t* data_out,
diff --git a/common_audio/signal_processing/real_fft_unittest.cc b/common_audio/signal_processing/real_fft_unittest.cc
index 3b43123..73fcb16 100644
--- a/common_audio/signal_processing/real_fft_unittest.cc
+++ b/common_audio/signal_processing/real_fft_unittest.cc
@@ -31,19 +31,14 @@
     1173,   6848,  -8688,  31980, -30295, 2522,  27085,  19410,
     -2629,  5607,  -3,     1178,  -23819, 1498,  -25772, 10076};
 
-class RealFFTTest : public ::testing::Test {
- protected:
-  RealFFTTest() { WebRtcSpl_Init(); }
-};
-
-TEST_F(RealFFTTest, CreateFailsOnBadInput) {
+TEST(RealFFTTest, CreateFailsOnBadInput) {
   RealFFT* fft = WebRtcSpl_CreateRealFFT(11);
   EXPECT_TRUE(fft == nullptr);
   fft = WebRtcSpl_CreateRealFFT(-1);
   EXPECT_TRUE(fft == nullptr);
 }
 
-TEST_F(RealFFTTest, RealAndComplexMatch) {
+TEST(RealFFTTest, RealAndComplexMatch) {
   int i = 0;
   int j = 0;
   int16_t real_fft_time[kTimeDataLength] = {0};
diff --git a/common_audio/signal_processing/signal_processing_unittest.cc b/common_audio/signal_processing/signal_processing_unittest.cc
index 0e316b9..3106c47 100644
--- a/common_audio/signal_processing/signal_processing_unittest.cc
+++ b/common_audio/signal_processing/signal_processing_unittest.cc
@@ -25,13 +25,7 @@
                                                 -3333,
                                                 345};
 
-class SplTest : public ::testing::Test {
- protected:
-  SplTest() { WebRtcSpl_Init(); }
-  ~SplTest() override {}
-};
-
-TEST_F(SplTest, MacroTest) {
+TEST(SplTest, MacroTest) {
   // Macros with inputs.
   int A = 10;
   int B = 21;
@@ -93,7 +87,7 @@
 #endif
 }
 
-TEST_F(SplTest, InlineTest) {
+TEST(SplTest, InlineTest) {
   int16_t a16 = 121;
   int16_t b16 = -17;
   int32_t a32 = 111121;
@@ -124,7 +118,7 @@
   EXPECT_EQ(138, WebRtcSpl_SubSatW16(a16, b16));
 }
 
-TEST_F(SplTest, AddSubSatW32) {
+TEST(SplTest, AddSubSatW32) {
   static constexpr int32_t kAddSubArgs[] = {
       INT32_MIN, INT32_MIN + 1, -3,       -2, -1, 0, 1, -1, 2,
       3,         INT32_MAX - 1, INT32_MAX};
@@ -143,7 +137,7 @@
   }
 }
 
-TEST_F(SplTest, CountLeadingZeros32) {
+TEST(SplTest, CountLeadingZeros32) {
   EXPECT_EQ(32, WebRtcSpl_CountLeadingZeros32(0));
   EXPECT_EQ(32, WebRtcSpl_CountLeadingZeros32_NotBuiltin(0));
   for (int i = 0; i < 32; ++i) {
@@ -156,7 +150,7 @@
   }
 }
 
-TEST_F(SplTest, CountLeadingZeros64) {
+TEST(SplTest, CountLeadingZeros64) {
   EXPECT_EQ(64, WebRtcSpl_CountLeadingZeros64(0));
   EXPECT_EQ(64, WebRtcSpl_CountLeadingZeros64_NotBuiltin(0));
   for (int i = 0; i < 64; ++i) {
@@ -169,7 +163,7 @@
   }
 }
 
-TEST_F(SplTest, MathOperationsTest) {
+TEST(SplTest, MathOperationsTest) {
   int A = 1134567892;
   int32_t num = 117;
   int32_t den = -5;
@@ -184,7 +178,7 @@
   EXPECT_EQ(0, WebRtcSpl_DivW32HiLow(128, 0, 256));
 }
 
-TEST_F(SplTest, BasicArrayOperationsTest) {
+TEST(SplTest, BasicArrayOperationsTest) {
   const size_t kVectorSize = 4;
   int B[] = {4, 12, 133, 1100};
   int16_t b16[kVectorSize];
@@ -249,7 +243,7 @@
   }
 }
 
-TEST_F(SplTest, MinMaxOperationsTest) {
+TEST(SplTest, MinMaxOperationsTest) {
   const size_t kVectorSize = 17;
 
   // Vectors to test the cases where minimum values have to be caught
@@ -340,7 +334,7 @@
   EXPECT_EQ(6u, WebRtcSpl_MinIndexW32(vector32, kVectorSize));
 }
 
-TEST_F(SplTest, VectorOperationsTest) {
+TEST(SplTest, VectorOperationsTest) {
   const size_t kVectorSize = 4;
   int B[] = {4, 12, 133, 1100};
   int16_t a16[kVectorSize];
@@ -402,7 +396,7 @@
   EXPECT_EQ(0, WebRtcSpl_GetScalingSquare(b16, kVectorSize, 1));
 }
 
-TEST_F(SplTest, EstimatorsTest) {
+TEST(SplTest, EstimatorsTest) {
   const size_t kOrder = 2;
   const int32_t unstable_filter[] = {4, 12, 133, 1100};
   const int32_t stable_filter[] = {1100, 133, 12, 4};
@@ -419,7 +413,7 @@
   }
 }
 
-TEST_F(SplTest, FilterTest) {
+TEST(SplTest, FilterTest) {
   const size_t kVectorSize = 4;
   const size_t kFilterOrder = 3;
   int16_t A[] = {1, 2, 33, 100};
@@ -457,7 +451,7 @@
                                             data_out, bTmp16Low, kVectorSize));
 }
 
-TEST_F(SplTest, RandTest) {
+TEST(SplTest, RandTest) {
   const int kVectorSize = 4;
   int16_t BU[] = {3653, 12446, 8525, 30691};
   int16_t b16[kVectorSize];
@@ -472,12 +466,12 @@
   }
 }
 
-TEST_F(SplTest, DotProductWithScaleTest) {
+TEST(SplTest, DotProductWithScaleTest) {
   EXPECT_EQ(605362796, WebRtcSpl_DotProductWithScale(vector16, vector16,
                                                      kVector16Size, 2));
 }
 
-TEST_F(SplTest, CrossCorrelationTest) {
+TEST(SplTest, CrossCorrelationTest) {
   // Note the function arguments relation specificed by API.
   const size_t kCrossCorrelationDimension = 3;
   const int kShift = 2;
@@ -509,7 +503,7 @@
   }
 }
 
-TEST_F(SplTest, AutoCorrelationTest) {
+TEST(SplTest, AutoCorrelationTest) {
   int scale = 0;
   int32_t vector32[kVector16Size];
   const int32_t expected[kVector16Size] = {302681398, 14223410,  -121705063,
@@ -525,7 +519,7 @@
   }
 }
 
-TEST_F(SplTest, SignalProcessingTest) {
+TEST(SplTest, SignalProcessingTest) {
   const size_t kVectorSize = 4;
   int A[] = {1, 2, 33, 100};
   const int16_t kHanning[4] = {2399, 8192, 13985, 16384};
@@ -565,7 +559,7 @@
   EXPECT_EQ(0, bScale);
 }
 
-TEST_F(SplTest, FFTTest) {
+TEST(SplTest, FFTTest) {
   int16_t B[] = {1, 2, 33, 100, 2, 3, 34, 101, 3, 4, 35, 102, 4, 5, 36, 103};
 
   EXPECT_EQ(0, WebRtcSpl_ComplexFFT(B, 3, 1));
@@ -582,7 +576,7 @@
   }
 }
 
-TEST_F(SplTest, Resample48WithSaturationTest) {
+TEST(SplTest, Resample48WithSaturationTest) {
   // The test resamples 3*kBlockSize number of samples to 2*kBlockSize number
   // of samples.
   const size_t kBlockSize = 16;
diff --git a/common_audio/signal_processing/spl_init.c b/common_audio/signal_processing/spl_init.c
index 80e9197..cf37d47 100644
--- a/common_audio/signal_processing/spl_init.c
+++ b/common_audio/signal_processing/spl_init.c
@@ -8,126 +8,62 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-/* The global function contained in this file initializes SPL function
- * pointers, currently only for ARM platforms.
- *
- * Some code came from common/rtcd.c in the WebM project.
- */
+// Some code came from common/rtcd.c in the WebM project.
 
 #include "common_audio/signal_processing/include/signal_processing_library.h"
-#include "system_wrappers/include/cpu_features_wrapper.h"
 
-/* Declare function pointers. */
-MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16;
-MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32;
-MaxValueW16 WebRtcSpl_MaxValueW16;
-MaxValueW32 WebRtcSpl_MaxValueW32;
-MinValueW16 WebRtcSpl_MinValueW16;
-MinValueW32 WebRtcSpl_MinValueW32;
-CrossCorrelation WebRtcSpl_CrossCorrelation;
-DownsampleFast WebRtcSpl_DownsampleFast;
-ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound;
-
-#if (!defined(WEBRTC_HAS_NEON)) && !defined(MIPS32_LE)
-/* Initialize function pointers to the generic C version. */
-static void InitPointersToC(void) {
-  WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16C;
-  WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C;
-  WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16C;
-  WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32C;
-  WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16C;
-  WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32C;
-  WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationC;
-  WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastC;
-  WebRtcSpl_ScaleAndAddVectorsWithRound =
-      WebRtcSpl_ScaleAndAddVectorsWithRoundC;
-}
-#endif
+// TODO(bugs.webrtc.org/9553): These function pointers are useless. Refactor
+// things so that we simply have a bunch of regular functions with different
+// implementations for different platforms.
 
 #if defined(WEBRTC_HAS_NEON)
-/* Initialize function pointers to the Neon version. */
-static void InitPointersToNeon(void) {
-  WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16Neon;
-  WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32Neon;
-  WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16Neon;
-  WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32Neon;
-  WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16Neon;
-  WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32Neon;
-  WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationNeon;
-  WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastNeon;
-  WebRtcSpl_ScaleAndAddVectorsWithRound =
-      WebRtcSpl_ScaleAndAddVectorsWithRoundC;
-}
-#endif
 
-#if defined(MIPS32_LE)
-/* Initialize function pointers to the MIPS version. */
-static void InitPointersToMIPS(void) {
-  WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16_mips;
-  WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16_mips;
-  WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32_mips;
-  WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16_mips;
-  WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32_mips;
-  WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelation_mips;
-  WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFast_mips;
-#if defined(MIPS_DSP_R1_LE)
-  WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32_mips;
-  WebRtcSpl_ScaleAndAddVectorsWithRound =
-      WebRtcSpl_ScaleAndAddVectorsWithRound_mips;
-#else
-  WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C;
-  WebRtcSpl_ScaleAndAddVectorsWithRound =
-      WebRtcSpl_ScaleAndAddVectorsWithRoundC;
-#endif
-}
-#endif
+const MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16Neon;
+const MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32Neon;
+const MaxValueW16 WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16Neon;
+const MaxValueW32 WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32Neon;
+const MinValueW16 WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16Neon;
+const MinValueW32 WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32Neon;
+const CrossCorrelation WebRtcSpl_CrossCorrelation =
+    WebRtcSpl_CrossCorrelationNeon;
+const DownsampleFast WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastNeon;
+const ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound =
+    WebRtcSpl_ScaleAndAddVectorsWithRoundC;
 
-static void InitFunctionPointers(void) {
-#if defined(WEBRTC_HAS_NEON)
-  InitPointersToNeon();
 #elif defined(MIPS32_LE)
-  InitPointersToMIPS();
+
+const MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16_mips;
+const MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32 =
+#ifdef MIPS_DSP_R1_LE
+    WebRtcSpl_MaxAbsValueW32_mips;
 #else
-  InitPointersToC();
-#endif  /* WEBRTC_HAS_NEON */
-}
+    WebRtcSpl_MaxAbsValueW32C;
+#endif
+const MaxValueW16 WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16_mips;
+const MaxValueW32 WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32_mips;
+const MinValueW16 WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16_mips;
+const MinValueW32 WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32_mips;
+const CrossCorrelation WebRtcSpl_CrossCorrelation =
+    WebRtcSpl_CrossCorrelation_mips;
+const DownsampleFast WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFast_mips;
+const ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound =
+#ifdef MIPS_DSP_R1_LE
+    WebRtcSpl_ScaleAndAddVectorsWithRound_mips;
+#else
+    WebRtcSpl_ScaleAndAddVectorsWithRoundC;
+#endif
 
-#if defined(WEBRTC_POSIX)
-#include <pthread.h>
+#else
 
-static void once(void (*func)(void)) {
-  static pthread_once_t lock = PTHREAD_ONCE_INIT;
-  pthread_once(&lock, func);
-}
+const MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16C;
+const MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C;
+const MaxValueW16 WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16C;
+const MaxValueW32 WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32C;
+const MinValueW16 WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16C;
+const MinValueW32 WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32C;
+const CrossCorrelation WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationC;
+const DownsampleFast WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastC;
+const ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound =
+    WebRtcSpl_ScaleAndAddVectorsWithRoundC;
 
-#elif defined(_WIN32)
-#include <windows.h>
-
-static void once(void (*func)(void)) {
-  /* Didn't use InitializeCriticalSection() since there's no race-free context
-   * in which to execute it.
-   *
-   * TODO(kma): Change to different implementation (e.g.
-   * InterlockedCompareExchangePointer) to avoid issues similar to
-   * http://code.google.com/p/webm/issues/detail?id=467.
-   */
-  static CRITICAL_SECTION lock = {(void *)((size_t)-1), -1, 0, 0, 0, 0};
-  static int done = 0;
-
-  EnterCriticalSection(&lock);
-  if (!done) {
-    func();
-    done = 1;
-  }
-  LeaveCriticalSection(&lock);
-}
-
-/* There's no fallback version as an #else block here to ensure thread safety.
- * In case of neither pthread for WEBRTC_POSIX nor _WIN32 is present, build
- * system should pick it up.
- */
-#endif  /* WEBRTC_POSIX */
-
-void WebRtcSpl_Init(void) {
-  once(InitFunctionPointers);
-}
+#endif
diff --git a/common_audio/vad/webrtc_vad.c b/common_audio/vad/webrtc_vad.c
index d8457ee..49e7682 100644
--- a/common_audio/vad/webrtc_vad.c
+++ b/common_audio/vad/webrtc_vad.c
@@ -24,7 +24,6 @@
 VadInst* WebRtcVad_Create() {
   VadInstT* self = (VadInstT*)malloc(sizeof(VadInstT));
 
-  WebRtcSpl_Init();
   self->init_flag = 0;
 
   return (VadInst*)self;
diff --git a/modules/audio_coding/codecs/cng/webrtc_cng.cc b/modules/audio_coding/codecs/cng/webrtc_cng.cc
index f18fb28..2acaf2b 100644
--- a/modules/audio_coding/codecs/cng/webrtc_cng.cc
+++ b/modules/audio_coding/codecs/cng/webrtc_cng.cc
@@ -51,7 +51,6 @@
 
 ComfortNoiseDecoder::ComfortNoiseDecoder() {
   /* Needed to get the right function pointers in SPLIB. */
-  WebRtcSpl_Init();
   Reset();
 }
 
@@ -217,8 +216,6 @@
       enc_seed_(7777) /* For debugging only. */ {
   RTC_CHECK_GT(quality, 0);
   RTC_CHECK_LE(quality, WEBRTC_CNG_MAX_LPC_ORDER);
-  /* Needed to get the right function pointers in SPLIB. */
-  WebRtcSpl_Init();
 }
 
 void ComfortNoiseEncoder::Reset(int fs, int interval, int quality) {
diff --git a/modules/audio_coding/codecs/ilbc/ilbc.c b/modules/audio_coding/codecs/ilbc/ilbc.c
index 21fc3f8..326c766 100644
--- a/modules/audio_coding/codecs/ilbc/ilbc.c
+++ b/modules/audio_coding/codecs/ilbc/ilbc.c
@@ -53,7 +53,6 @@
 int16_t WebRtcIlbcfix_EncoderCreate(IlbcEncoderInstance **iLBC_encinst) {
   *iLBC_encinst=(IlbcEncoderInstance*)malloc(sizeof(IlbcEncoder));
   if (*iLBC_encinst!=NULL) {
-    WebRtcSpl_Init();
     return(0);
   } else {
     return(-1);
@@ -63,7 +62,6 @@
 int16_t WebRtcIlbcfix_DecoderCreate(IlbcDecoderInstance **iLBC_decinst) {
   *iLBC_decinst=(IlbcDecoderInstance*)malloc(sizeof(IlbcDecoder));
   if (*iLBC_decinst!=NULL) {
-    WebRtcSpl_Init();
     return(0);
   } else {
     return(-1);
diff --git a/modules/audio_coding/codecs/isac/fix/source/isacfix.c b/modules/audio_coding/codecs/isac/fix/source/isacfix.c
index bbe9098..ef5655e 100644
--- a/modules/audio_coding/codecs/isac/fix/source/isacfix.c
+++ b/modules/audio_coding/codecs/isac/fix/source/isacfix.c
@@ -109,7 +109,6 @@
     (*(ISACFIX_SubStruct**)ISAC_main_inst)->errorcode = 0;
     (*(ISACFIX_SubStruct**)ISAC_main_inst)->initflag = 0;
     (*(ISACFIX_SubStruct**)ISAC_main_inst)->ISACenc_obj.SaveEnc_ptr = NULL;
-    WebRtcSpl_Init();
     WebRtcIsacfix_InitBandwidthEstimator(&tempo->bwestimator_obj);
     return(0);
   } else {
diff --git a/modules/audio_coding/codecs/isac/fix/source/transform_unittest.cc b/modules/audio_coding/codecs/isac/fix/source/transform_unittest.cc
index 473b7f8..433ec53 100644
--- a/modules/audio_coding/codecs/isac/fix/source/transform_unittest.cc
+++ b/modules/audio_coding/codecs/isac/fix/source/transform_unittest.cc
@@ -138,8 +138,6 @@
 
 class TransformTest : public ::testing::Test {
  protected:
-  TransformTest() { WebRtcSpl_Init(); }
-
   // Pass a function pointer to the Tester function.
   void Time2SpecTester(Time2Spec Time2SpecFunction) {
     // WebRtcIsacfix_Time2Spec functions hard coded the buffer lengths. It's a
diff --git a/modules/audio_coding/neteq/expand_unittest.cc b/modules/audio_coding/neteq/expand_unittest.cc
index 4c8c174..55a8866 100644
--- a/modules/audio_coding/neteq/expand_unittest.cc
+++ b/modules/audio_coding/neteq/expand_unittest.cc
@@ -83,7 +83,6 @@
                 &statistics_,
                 test_sample_rate_hz_,
                 num_channels_) {
-    WebRtcSpl_Init();
     input_file_.set_output_rate_hz(test_sample_rate_hz_);
   }
 
diff --git a/modules/audio_coding/neteq/neteq_impl.cc b/modules/audio_coding/neteq/neteq_impl.cc
index 82ec18d..6f36fb1 100644
--- a/modules/audio_coding/neteq/neteq_impl.cc
+++ b/modules/audio_coding/neteq/neteq_impl.cc
@@ -133,7 +133,6 @@
   last_output_sample_rate_hz_ = fs;
   output_size_samples_ = static_cast<size_t>(kOutputSizeMs * 8 * fs_mult_);
   decoder_frame_length_ = 3 * output_size_samples_;
-  WebRtcSpl_Init();
   if (create_components) {
     SetSampleRateAndChannels(fs, 1);  // Default is 1 channel.
   }
diff --git a/modules/audio_coding/neteq/normal_unittest.cc b/modules/audio_coding/neteq/normal_unittest.cc
index 106762a..222fcaa 100644
--- a/modules/audio_coding/neteq/normal_unittest.cc
+++ b/modules/audio_coding/neteq/normal_unittest.cc
@@ -55,7 +55,6 @@
 }
 
 TEST(Normal, AvoidDivideByZero) {
-  WebRtcSpl_Init();
   MockDecoderDatabase db;
   int fs = 8000;
   size_t channels = 1;
@@ -91,7 +90,6 @@
 }
 
 TEST(Normal, InputLengthAndChannelsDoNotMatch) {
-  WebRtcSpl_Init();
   MockDecoderDatabase db;
   int fs = 8000;
   size_t channels = 2;
@@ -116,7 +114,6 @@
 }
 
 TEST(Normal, LastModeExpand120msPacket) {
-  WebRtcSpl_Init();
   MockDecoderDatabase db;
   const int kFs = 48000;
   const size_t kPacketsizeBytes = 11520u;
diff --git a/modules/audio_coding/neteq/time_stretch_unittest.cc b/modules/audio_coding/neteq/time_stretch_unittest.cc
index 6fced38..6f875f0 100644
--- a/modules/audio_coding/neteq/time_stretch_unittest.cc
+++ b/modules/audio_coding/neteq/time_stretch_unittest.cc
@@ -65,7 +65,6 @@
         block_size_(30 * sample_rate_hz_ / 1000),  // 30 ms
         audio_(new int16_t[block_size_]),
         background_noise_(kNumChannels) {
-    WebRtcSpl_Init();
   }
 
   const int16_t* Next30Ms() {
diff --git a/modules/audio_device/audio_device_buffer.cc b/modules/audio_device/audio_device_buffer.cc
index 927f80a..37191fe 100644
--- a/modules/audio_device/audio_device_buffer.cc
+++ b/modules/audio_device/audio_device_buffer.cc
@@ -65,7 +65,6 @@
   phase_ = 0.0;
   RTC_LOG(WARNING) << "AUDIO_DEVICE_PLAYS_SINUS_TONE is defined!";
 #endif
-  WebRtcSpl_Init();
 }
 
 AudioDeviceBuffer::~AudioDeviceBuffer() {
diff --git a/modules/audio_processing/aecm/echo_control_mobile.cc b/modules/audio_processing/aecm/echo_control_mobile.cc
index 257dfbf..f556a30 100644
--- a/modules/audio_processing/aecm/echo_control_mobile.cc
+++ b/modules/audio_processing/aecm/echo_control_mobile.cc
@@ -85,8 +85,6 @@
 void* WebRtcAecm_Create() {
   AecMobile* aecm = static_cast<AecMobile*>(malloc(sizeof(AecMobile)));
 
-  WebRtcSpl_Init();
-
   aecm->aecmCore = WebRtcAecm_CreateCore();
   if (!aecm->aecmCore) {
     WebRtcAecm_Free(aecm);
diff --git a/modules/audio_processing/ns/noise_suppression_x.c b/modules/audio_processing/ns/noise_suppression_x.c
index 1fd3ebc..c6faf75 100644
--- a/modules/audio_processing/ns/noise_suppression_x.c
+++ b/modules/audio_processing/ns/noise_suppression_x.c
@@ -18,7 +18,6 @@
 
 NsxHandle* WebRtcNsx_Create() {
   NoiseSuppressionFixedC* self = malloc(sizeof(NoiseSuppressionFixedC));
-  WebRtcSpl_Init();
   self->real_fft = NULL;
   self->initFlag = 0;
   return (NsxHandle*)self;