UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
radaudio_mdct_internal.h
Go to the documentation of this file.
1// Copyright Epic Games Tools, LLC. All Rights Reserved.
2#ifndef RADAUDIO_MDCT_INTERNAL_H
3#define RADAUDIO_MDCT_INTERNAL_H
4
5#include <stddef.h>
6#include "rrCore.h"
7#include "radaudio_mdct.h"
8
10{
11 FftSign_Negative = 0, // Negative exponential (the customary "forward" FFT)
12 FftSign_Positive, // Positive exponential (customary "inverse" FFT)
13};
14
15
16#ifdef RADAUDIO_WRAP
17#define WRAPPED_NAME(name) RR_STRING_JOIN(RADAUDIO_WRAP, name##_)
18
19#define radaudio_fft_impl WRAPPED_NAME(radaudio_fft_impl)
20
21#endif
22
23
24namespace radaudio_fft_impl {
25
26static size_t const kMaxFFTLog2 = 9;
27static size_t const kMaxFFTN = 1 << kMaxFFTLog2; // This is the largest straight FFT we support
28
29
30// Main twiddle array:
31// sine of N values for N=1,2,4,8,...,kMaxN
32//
33// First radix2 level uses N/4 twiddles from N/2 twiddle array (so 1/2 the table);
34// cosine table is offset by N/8 from it (another 1/4 the table); for inverse
35// transform, we just start into the sine table from offset N/4 (halfway into the
36// circle). That means we use all of the sine table.
37//
38// Second radix2 level uses N/4 twiddles from N twiddle array (1/4 the table)
39// and has the cosine table offset by 1/4; for an inverse FFT the sine table is
40// accessed offset by N/2. In total, we end up using 3/4 of that larger sine table.
41extern FFT_ALIGN(float, s_fft_twiddles[kMaxFFTN * 2]);
42
43// A size-N MDCT/IMDCT needs N/2 complex twiddles, which are just scaled complex
44// exponentials. We store first all the real parts then all the imaginary parts.
47
48static_assert(kMaxFFTN <= 65536, "Have to increase FFTIndex size");
49typedef U16 FFTIndex;
50
51extern FFTIndex s_bit_reverse[kMaxFFTN];
52
53// Burst-layout radix 2 FFTs
54// First kBurstSize real values, then kBurstSize corresponding imaginary values, then kBurstSize reals again, and so forth.
55static size_t constexpr kBurstSize = 16;
56static size_t constexpr kBurstMask = kBurstSize - 1;
57
58static constexpr inline size_t burst_swizzle(size_t i)
59{
60 // logically, this is:
61 // return (i & kBurstMask) + ((i & ~kBurstMask) << 1);
62 // but note that i = (i & kBurstMask) + (i & ~kBurstMask)
63 // and ((i & ~kBurstMask) << 1) == (i & ~kBurstMask) + (i & ~kBurstMask)
64 // therefore:
65 return i + (i & ~kBurstMask);
66}
67
68// Bit reverse and initial passes, returns stride of next pass to run
69typedef size_t InitialPassesKernel(float * out, float const * in, size_t N, FftSign sign);
70// Complex FFT radix-4 (actually 2^2) pass
71typedef void CFftKernel(float * out, size_t step, size_t swiz_N, FftSign sign);
72// IMDCT pre-FFT pass
73typedef void ImdctPreFftKernel(float * dest, float const * coeffs, float const * tw_re, float const * tw_im, size_t N);
74// IMDCT post-FFT pass
75typedef void ImdctPostFftKernel(float * signal0, float * signal1, float const * dft, float const * tw_re, float const * tw_im, size_t N);
76
78{
79 InitialPassesKernel * initial; // Initial bit reverse and first few passes
80 CFftKernel * cfft_pass; // Complex FFT passes
81 ImdctPreFftKernel * imdct_pre; // Pre-FFT IMDCT kernel
82 ImdctPostFftKernel * imdct_post; // Post-FFT IMDCT kernel
83};
84
85// available kernel sets
86extern FftKernelSet const kernels_scalar;
87extern FftKernelSet const kernels_sse2;
88extern FftKernelSet const kernels_avx2;
89extern FftKernelSet const kernels_neon;
90
91} // namespace radaudio_fft_impl
92
93#endif // RADAUDIO_MDCT_INTERNAL_H
94
RAD_U16 U16
Definition egttypes.h:491
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
char * dest
Definition lz4.h:709
Definition radaudio_mdct.cpp:49
FftKernelSet const kernels_neon
U16 FFTIndex
Definition radaudio_mdct_internal.h:49
size_t InitialPassesKernel(float *out, float const *in, size_t N, FftSign sign)
Definition radaudio_mdct_internal.h:69
FftKernelSet const kernels_scalar
Definition radaudio_mdct.cpp:176
FftKernelSet const kernels_avx2
void CFftKernel(float *out, size_t step, size_t swiz_N, FftSign sign)
Definition radaudio_mdct_internal.h:71
FftKernelSet const kernels_sse2
void ImdctPostFftKernel(float *signal0, float *signal1, float const *dft, float const *tw_re, float const *tw_im, size_t N)
Definition radaudio_mdct_internal.h:75
FFTIndex s_bit_reverse[kMaxFFTN]
void ImdctPreFftKernel(float *dest, float const *coeffs, float const *tw_re, float const *tw_im, size_t N)
Definition radaudio_mdct_internal.h:73
#define RADAUDIO_LONG_BLOCK_LEN
Definition radaudio_common.h:26
#define FFT_ALIGN(type, name)
Definition radaudio_common.h:17
#define RADAUDIO_SHORT_BLOCK_LEN
Definition radaudio_common.h:27
FftSign
Definition radaudio_mdct_internal.h:10
@ FftSign_Positive
Definition radaudio_mdct_internal.h:12
@ FftSign_Negative
Definition radaudio_mdct_internal.h:11
Definition radaudio_mdct_internal.h:78
ImdctPreFftKernel * imdct_pre
Definition radaudio_mdct_internal.h:81
InitialPassesKernel * initial
Definition radaudio_mdct_internal.h:79
CFftKernel * cfft_pass
Definition radaudio_mdct_internal.h:80
ImdctPostFftKernel * imdct_post
Definition radaudio_mdct_internal.h:82