Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 14:04:28 +01:00
parent 81b91f4139
commit f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
#define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
#include <stdint.h>
// For ComplexFFT(), the maximum fft order is 10;
// WebRTC APM uses orders of only 7 and 8.
enum { kMaxFFTOrder = 10 };
struct RealFFT;
#ifdef __cplusplus
extern "C" {
#endif
struct RealFFT* WebRtcSpl_CreateRealFFT(int order);
void WebRtcSpl_FreeRealFFT(struct RealFFT* self);
// Compute an FFT for a real-valued signal of length of 2^order,
// where 1 < order <= MAX_FFT_ORDER. Transform length is determined by the
// specification structure, which must be initialized prior to calling the FFT
// function with WebRtcSpl_CreateRealFFT().
// The relationship between the input and output sequences can
// be expressed in terms of the DFT, i.e.:
// x[n] = (2^(-scalefactor)/N) . SUM[k=0,...,N-1] X[k].e^(jnk.2.pi/N)
// n=0,1,2,...N-1
// N=2^order.
// The conjugate-symmetric output sequence is represented using a CCS vector,
// which is of length N+2, and is organized as follows:
// Index: 0 1 2 3 4 5 . . . N-2 N-1 N N+1
// Component: R0 0 R1 I1 R2 I2 . . . R[N/2-1] I[N/2-1] R[N/2] 0
// where R[n] and I[n], respectively, denote the real and imaginary components
// for FFT bin 'n'. Bins are numbered from 0 to N/2, where N is the FFT length.
// Bin index 0 corresponds to the DC component, and bin index N/2 corresponds to
// the foldover frequency.
//
// Input Arguments:
// self - pointer to preallocated and initialized FFT specification structure.
// real_data_in - the input signal. For an ARM Neon platform, it must be
// aligned on a 32-byte boundary.
//
// Output Arguments:
// complex_data_out - the output complex signal with (2^order + 2) 16-bit
// elements. For an ARM Neon platform, it must be different
// from real_data_in, and aligned on a 32-byte boundary.
//
// Return Value:
// 0 - FFT calculation is successful.
// -1 - Error with bad arguments (null pointers).
int WebRtcSpl_RealForwardFFT(struct RealFFT* self,
const int16_t* real_data_in,
int16_t* complex_data_out);
// Compute the inverse FFT for a conjugate-symmetric input sequence of length of
// 2^order, where 1 < order <= MAX_FFT_ORDER. Transform length is determined by
// the specification structure, which must be initialized prior to calling the
// FFT function with WebRtcSpl_CreateRealFFT().
// For a transform of length M, the input sequence is represented using a packed
// CCS vector of length M+2, which is explained in the comments for
// WebRtcSpl_RealForwardFFTC above.
//
// Input Arguments:
// self - pointer to preallocated and initialized FFT specification structure.
// complex_data_in - the input complex signal with (2^order + 2) 16-bit
// elements. For an ARM Neon platform, it must be aligned on
// a 32-byte boundary.
//
// Output Arguments:
// real_data_out - the output real signal. For an ARM Neon platform, it must
// be different to complex_data_in, and aligned on a 32-byte
// boundary.
//
// Return Value:
// 0 or a positive number - a value that the elements in the `real_data_out`
// should be shifted left with in order to get
// correct physical values.
// -1 - Error with bad arguments (null pointers).
int WebRtcSpl_RealInverseFFT(struct RealFFT* self,
const int16_t* complex_data_in,
int16_t* real_data_out);
#ifdef __cplusplus
}
#endif
#endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_

View file

@ -0,0 +1,155 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// This header file includes the inline functions in
// the fix point signal processing library.
#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_
#define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_
#include <stdint.h>
#include "rtc_base/compile_assert_c.h"
extern const int8_t kWebRtcSpl_CountLeadingZeros32_Table[64];
// Don't call this directly except in tests!
static __inline int WebRtcSpl_CountLeadingZeros32_NotBuiltin(uint32_t n) {
// Normalize n by rounding up to the nearest number that is a sequence of 0
// bits followed by a sequence of 1 bits. This number has the same number of
// leading zeros as the original n. There are exactly 33 such values.
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
// Multiply the modified n with a constant selected (by exhaustive search)
// such that each of the 33 possible values of n give a product whose 6 most
// significant bits are unique. Then look up the answer in the table.
return kWebRtcSpl_CountLeadingZeros32_Table[(n * 0x8c0b2891) >> 26];
}
// Don't call this directly except in tests!
static __inline int WebRtcSpl_CountLeadingZeros64_NotBuiltin(uint64_t n) {
const int leading_zeros = n >> 32 == 0 ? 32 : 0;
return leading_zeros + WebRtcSpl_CountLeadingZeros32_NotBuiltin(
(uint32_t)(n >> (32 - leading_zeros)));
}
// Returns the number of leading zero bits in the argument.
static __inline int WebRtcSpl_CountLeadingZeros32(uint32_t n) {
#ifdef __GNUC__
RTC_COMPILE_ASSERT(sizeof(unsigned int) == sizeof(uint32_t));
return n == 0 ? 32 : __builtin_clz(n);
#else
return WebRtcSpl_CountLeadingZeros32_NotBuiltin(n);
#endif
}
// Returns the number of leading zero bits in the argument.
static __inline int WebRtcSpl_CountLeadingZeros64(uint64_t n) {
#ifdef __GNUC__
RTC_COMPILE_ASSERT(sizeof(unsigned long long) == sizeof(uint64_t)); // NOLINT
return n == 0 ? 64 : __builtin_clzll(n);
#else
return WebRtcSpl_CountLeadingZeros64_NotBuiltin(n);
#endif
}
#ifdef WEBRTC_ARCH_ARM_V7
#include "common_audio/signal_processing/include/spl_inl_armv7.h"
#else
#if defined(MIPS32_LE)
#include "common_audio/signal_processing/include/spl_inl_mips.h"
#endif
#if !defined(MIPS_DSP_R1_LE)
static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
int16_t out16 = (int16_t)value32;
if (value32 > 32767)
out16 = 32767;
else if (value32 < -32768)
out16 = -32768;
return out16;
}
static __inline int32_t WebRtcSpl_AddSatW32(int32_t a, int32_t b) {
// Do the addition in unsigned numbers, since signed overflow is undefined
// behavior.
const int32_t sum = (int32_t)((uint32_t)a + (uint32_t)b);
// a + b can't overflow if a and b have different signs. If they have the
// same sign, a + b also has the same sign iff it didn't overflow.
if ((a < 0) == (b < 0) && (a < 0) != (sum < 0)) {
// The direction of the overflow is obvious from the sign of a + b.
return sum < 0 ? INT32_MAX : INT32_MIN;
}
return sum;
}
static __inline int32_t WebRtcSpl_SubSatW32(int32_t a, int32_t b) {
// Do the subtraction in unsigned numbers, since signed overflow is undefined
// behavior.
const int32_t diff = (int32_t)((uint32_t)a - (uint32_t)b);
// a - b can't overflow if a and b have the same sign. If they have different
// signs, a - b has the same sign as a iff it didn't overflow.
if ((a < 0) != (b < 0) && (a < 0) != (diff < 0)) {
// The direction of the overflow is obvious from the sign of a - b.
return diff < 0 ? INT32_MAX : INT32_MIN;
}
return diff;
}
static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
return WebRtcSpl_SatW32ToW16((int32_t)a + (int32_t)b);
}
static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
return WebRtcSpl_SatW32ToW16((int32_t)var1 - (int32_t)var2);
}
#endif // #if !defined(MIPS_DSP_R1_LE)
#if !defined(MIPS32_LE)
static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
return 32 - WebRtcSpl_CountLeadingZeros32(n);
}
// Return the number of steps a can be left-shifted without overflow,
// or 0 if a == 0.
static __inline int16_t WebRtcSpl_NormW32(int32_t a) {
return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a : a) - 1;
}
// Return the number of steps a can be left-shifted without overflow,
// or 0 if a == 0.
static __inline int16_t WebRtcSpl_NormU32(uint32_t a) {
return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a);
}
// Return the number of steps a can be left-shifted without overflow,
// or 0 if a == 0.
static __inline int16_t WebRtcSpl_NormW16(int16_t a) {
const int32_t a32 = a;
return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a32 : a32) - 17;
}
static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) {
return (a * b + c);
}
#endif // #if !defined(MIPS32_LE)
#endif // WEBRTC_ARCH_ARM_V7
#endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_

View file

@ -0,0 +1,138 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/* This header file includes the inline functions for ARM processors in
* the fix point signal processing library.
*/
#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_ARMV7_H_
#define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_ARMV7_H_
#include <stdint.h>
/* TODO(kma): Replace some assembly code with GCC intrinsics
* (e.g. __builtin_clz).
*/
/* This function produces result that is not bit exact with that by the generic
* C version in some cases, although the former is at least as accurate as the
* later.
*/
static __inline int32_t WEBRTC_SPL_MUL_16_32_RSFT16(int16_t a, int32_t b) {
int32_t tmp = 0;
__asm __volatile("smulwb %0, %1, %2" : "=r"(tmp) : "r"(b), "r"(a));
return tmp;
}
static __inline int32_t WEBRTC_SPL_MUL_16_16(int16_t a, int16_t b) {
int32_t tmp = 0;
__asm __volatile("smulbb %0, %1, %2" : "=r"(tmp) : "r"(a), "r"(b));
return tmp;
}
// TODO(kma): add unit test.
static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) {
int32_t tmp = 0;
__asm __volatile("smlabb %0, %1, %2, %3"
: "=r"(tmp)
: "r"(a), "r"(b), "r"(c));
return tmp;
}
static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
int32_t s_sum = 0;
__asm __volatile("qadd16 %0, %1, %2" : "=r"(s_sum) : "r"(a), "r"(b));
return (int16_t)s_sum;
}
static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) {
int32_t l_sum = 0;
__asm __volatile("qadd %0, %1, %2" : "=r"(l_sum) : "r"(l_var1), "r"(l_var2));
return l_sum;
}
static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) {
int32_t l_sub = 0;
__asm __volatile("qsub %0, %1, %2" : "=r"(l_sub) : "r"(l_var1), "r"(l_var2));
return l_sub;
}
static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
int32_t s_sub = 0;
__asm __volatile("qsub16 %0, %1, %2" : "=r"(s_sub) : "r"(var1), "r"(var2));
return (int16_t)s_sub;
}
static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
int32_t tmp = 0;
__asm __volatile("clz %0, %1" : "=r"(tmp) : "r"(n));
return (int16_t)(32 - tmp);
}
static __inline int16_t WebRtcSpl_NormW32(int32_t a) {
int32_t tmp = 0;
if (a == 0) {
return 0;
} else if (a < 0) {
a ^= 0xFFFFFFFF;
}
__asm __volatile("clz %0, %1" : "=r"(tmp) : "r"(a));
return (int16_t)(tmp - 1);
}
static __inline int16_t WebRtcSpl_NormU32(uint32_t a) {
int tmp = 0;
if (a == 0)
return 0;
__asm __volatile("clz %0, %1" : "=r"(tmp) : "r"(a));
return (int16_t)tmp;
}
static __inline int16_t WebRtcSpl_NormW16(int16_t a) {
int32_t tmp = 0;
int32_t a_32 = a;
if (a_32 == 0) {
return 0;
} else if (a_32 < 0) {
a_32 ^= 0xFFFFFFFF;
}
__asm __volatile("clz %0, %1" : "=r"(tmp) : "r"(a_32));
return (int16_t)(tmp - 17);
}
// TODO(kma): add unit test.
static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
int32_t out = 0;
__asm __volatile("ssat %0, #16, %1" : "=r"(out) : "r"(value32));
return (int16_t)out;
}
#endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_ARMV7_H_

View file

@ -0,0 +1,204 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// This header file includes the inline functions in
// the fix point signal processing library.
#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_MIPS_H_
#define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_MIPS_H_
static __inline int32_t WEBRTC_SPL_MUL_16_16(int32_t a, int32_t b) {
int32_t value32 = 0;
int32_t a1 = 0, b1 = 0;
__asm __volatile(
#if defined(MIPS32_R2_LE)
"seh %[a1], %[a] \n\t"
"seh %[b1], %[b] \n\t"
#else
"sll %[a1], %[a], 16 \n\t"
"sll %[b1], %[b], 16 \n\t"
"sra %[a1], %[a1], 16 \n\t"
"sra %[b1], %[b1], 16 \n\t"
#endif
"mul %[value32], %[a1], %[b1] \n\t"
: [value32] "=r"(value32), [a1] "=&r"(a1), [b1] "=&r"(b1)
: [a] "r"(a), [b] "r"(b)
: "hi", "lo");
return value32;
}
static __inline int32_t WEBRTC_SPL_MUL_16_32_RSFT16(int16_t a, int32_t b) {
int32_t value32 = 0, b1 = 0, b2 = 0;
int32_t a1 = 0;
__asm __volatile(
#if defined(MIPS32_R2_LE)
"seh %[a1], %[a] \n\t"
#else
"sll %[a1], %[a], 16 \n\t"
"sra %[a1], %[a1], 16 \n\t"
#endif
"andi %[b2], %[b], 0xFFFF \n\t"
"sra %[b1], %[b], 16 \n\t"
"sra %[b2], %[b2], 1 \n\t"
"mul %[value32], %[a1], %[b1] \n\t"
"mul %[b2], %[a1], %[b2] \n\t"
"addiu %[b2], %[b2], 0x4000 \n\t"
"sra %[b2], %[b2], 15 \n\t"
"addu %[value32], %[value32], %[b2] \n\t"
: [value32] "=&r"(value32), [b1] "=&r"(b1), [b2] "=&r"(b2), [a1] "=&r"(a1)
: [a] "r"(a), [b] "r"(b)
: "hi", "lo");
return value32;
}
#if defined(MIPS_DSP_R1_LE)
static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
__asm __volatile(
"shll_s.w %[value32], %[value32], 16 \n\t"
"sra %[value32], %[value32], 16 \n\t"
: [value32] "+r"(value32)
:);
int16_t out16 = (int16_t)value32;
return out16;
}
static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
int32_t value32 = 0;
__asm __volatile("addq_s.ph %[value32], %[a], %[b] \n\t"
: [value32] "=r"(value32)
: [a] "r"(a), [b] "r"(b));
return (int16_t)value32;
}
static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) {
int32_t l_sum;
__asm __volatile(
"addq_s.w %[l_sum], %[l_var1], %[l_var2] \n\t"
: [l_sum] "=r"(l_sum)
: [l_var1] "r"(l_var1), [l_var2] "r"(l_var2));
return l_sum;
}
static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
int32_t value32;
__asm __volatile("subq_s.ph %[value32], %[var1], %[var2] \n\t"
: [value32] "=r"(value32)
: [var1] "r"(var1), [var2] "r"(var2));
return (int16_t)value32;
}
static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) {
int32_t l_diff;
__asm __volatile(
"subq_s.w %[l_diff], %[l_var1], %[l_var2] \n\t"
: [l_diff] "=r"(l_diff)
: [l_var1] "r"(l_var1), [l_var2] "r"(l_var2));
return l_diff;
}
#endif
static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
int bits = 0;
int i32 = 32;
__asm __volatile(
"clz %[bits], %[n] \n\t"
"subu %[bits], %[i32], %[bits] \n\t"
: [bits] "=&r"(bits)
: [n] "r"(n), [i32] "r"(i32));
return (int16_t)bits;
}
static __inline int16_t WebRtcSpl_NormW32(int32_t a) {
int zeros = 0;
__asm __volatile(
".set push \n\t"
".set noreorder \n\t"
"bnez %[a], 1f \n\t"
" sra %[zeros], %[a], 31 \n\t"
"b 2f \n\t"
" move %[zeros], $zero \n\t"
"1: \n\t"
"xor %[zeros], %[a], %[zeros] \n\t"
"clz %[zeros], %[zeros] \n\t"
"addiu %[zeros], %[zeros], -1 \n\t"
"2: \n\t"
".set pop \n\t"
: [zeros] "=&r"(zeros)
: [a] "r"(a));
return (int16_t)zeros;
}
static __inline int16_t WebRtcSpl_NormU32(uint32_t a) {
int zeros = 0;
__asm __volatile("clz %[zeros], %[a] \n\t"
: [zeros] "=r"(zeros)
: [a] "r"(a));
return (int16_t)(zeros & 0x1f);
}
static __inline int16_t WebRtcSpl_NormW16(int16_t a) {
int zeros = 0;
int a0 = a << 16;
__asm __volatile(
".set push \n\t"
".set noreorder \n\t"
"bnez %[a0], 1f \n\t"
" sra %[zeros], %[a0], 31 \n\t"
"b 2f \n\t"
" move %[zeros], $zero \n\t"
"1: \n\t"
"xor %[zeros], %[a0], %[zeros] \n\t"
"clz %[zeros], %[zeros] \n\t"
"addiu %[zeros], %[zeros], -1 \n\t"
"2: \n\t"
".set pop \n\t"
: [zeros] "=&r"(zeros)
: [a0] "r"(a0));
return (int16_t)zeros;
}
static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) {
int32_t res = 0, c1 = 0;
__asm __volatile(
#if defined(MIPS32_R2_LE)
"seh %[a], %[a] \n\t"
"seh %[b], %[b] \n\t"
#else
"sll %[a], %[a], 16 \n\t"
"sll %[b], %[b], 16 \n\t"
"sra %[a], %[a], 16 \n\t"
"sra %[b], %[b], 16 \n\t"
#endif
"mul %[res], %[a], %[b] \n\t"
"addu %[c1], %[c], %[res] \n\t"
: [c1] "=r"(c1), [res] "=&r"(res)
: [a] "r"(a), [b] "r"(b), [c] "r"(c)
: "hi", "lo");
return (c1);
}
#endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_MIPS_H_