Library / SDK
mborgerding/kissfft avatar
mborgerding/kissfft

KISS FFT: a 500-line C FFT library with fixed-point support and no assembly

a Fast Fourier Transform (FFT) library that tries to Keep it Simple, Stupid

1,995 stars363 forksCNOASSERTION

At a glance

What is it?
KISS FFT (mborgerding/kissfft) is a mixed-radix FFT in C described by its author as 'reasonably efficient, moderately useful' and roughly half the speed of peak-optimized alternatives. It supports float, double, int16_t, int32_t and SIMD datatypes compiled from the same source, designed to drop into a C project in minutes.
Who is it for?
Use KISS FFT when your C project needs a 1-D or multi-dimensional FFT and you cannot or do not want to link against a large, heavily optimized library. It is the right choice when fixed-point data types matter or when binary size is constrained.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 60 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.

Editorial analysis

KISS FFT trades peak speed for source simplicity

KISS FFT is a mixed-radix Fast Fourier Transform library written in C. Its name comes from the design principle: Keep It Simple, Stupid. According to the README, it is not trying to be better than other FFT libraries. It only attempts to be a reasonably efficient, moderately useful FFT that can use fixed or floating data types and can be incorporated into a C program in a few minutes.

Five data types are supported: float (the default), double, int16_t, int32_t, and simd. The simd option requires SSE instruction set support on the target CPU. All five compile from the same source, selected at build time via the KISSFFT_DATATYPE flag. No separate code paths or assembly files are needed for fixed-point support, which was the original motivation: the author started the project because no fixed-point FFT was available without assembly code.

The library ships with a C++ wrapper in kissfft.hh and kissfft_i32.hh alongside the C headers. A TIPS file at the repository root covers common use-case guidance. Core files for 1-D complex transforms are kiss_fft.c and kiss_fft.h.

The 1-D complex API allocates a config, calls kiss_fft in a loop, and frees the config

Three steps cover the core API. First, allocate a configuration object with kiss_fft_alloc, passing the transform size and a direction flag for inverse or forward. Second, call kiss_fft inside a loop, passing the config, input buffer, and output buffer. Third, free the configuration with kiss_fft_free when done.

The README gives this example:

c
    #include "kiss_fft.h"
    kiss_fft_cfg cfg = kiss_fft_alloc( nfft ,is_inverse_fft ,0,0 );
    while ...

        ... // put kth sample in cx_in[k].r and cx_in[k].i

        kiss_fft( cfg , cx_in , cx_out );

        ... // transformed. DC is in cx_out[0].r and cx_out[0].i

    kiss_fft_free(cfg);

Frequency-domain data is stored from DC up to 2pi. The DC bin is at cx_out[0] and the Nyquist bin, when it exists, is at cx_out[nfft/2]. Full API declarations are in kiss_fft.h, and the 1-D complex transform code is in kiss_fft.c.

Nothing in the API requires dynamic memory beyond the initial kiss_fft_alloc call. For embedded targets with a constrained heap, this matters. The KISSFFT_USE_ALLOCA=1 option (Make) or -DKISSFFT_USE_ALLOCA=ON (CMake) replaces malloc and free with alloca, removing heap allocation from the transform path entirely.

Choosing a datatype and build system before compiling

Two build systems are supported: Make for Unix and Linux, and CMake version 3.10 or newer. Supported compilers are GCC, Clang, and MSVC. The README notes that Cygwin and MinGW on Windows have not been tested.

The KISSFFT_DATATYPE flag selects the arithmetic type at compile time. To build a static library with int16_t samples and OpenMP enabled using Make:

bash
make KISSFFT_DATATYPE=int16_t KISSFFT_STATIC=1 KISSFFT_OPENMP=1 all

The equivalent CMake configuration:

bash
mkdir build && cd build
cmake -DKISSFFT_DATATYPE=int16_t -DKISSFFT_STATIC=ON -DKISSFFT_OPENMP=ON ..
make all

By default, the build produces a shared library (.so on Linux, .dll on Windows, .dylib on macOS) and includes the command-line tools in tools/. Setting KISSFFT_TOOLS=0 (Make) or -DKISSFFT_TOOLS=OFF (CMake) skips those tools. A prefix directory for installation is set with PREFIX=/path (Make) or -DCMAKE_INSTALL_PREFIX=/path (CMake).

tools/ adds real-valued FFT, N-dimensional transforms and fast convolution, but not for fixed point

Beyond the 1-D complex transform, the tools/ directory provides four extras. Multi-dimensional FFTs support any number of dimensions. Real-optimized FFTs exploit conjugate symmetry and return the positive half-spectrum, which is nfft/2+1 complex frequency bins rather than nfft. Fast convolution FIR filtering wraps the FFT for convolution workloads. Spectrum image creation produces visual output.

The real-valued FFT headers are kiss_fftr.h for 1-D and kiss_fftndr.h for N-dimensional real transforms. The N-dimensional complex transform header is kiss_fftnd.h.

A specific gap appears when reading the tools/ feature list carefully. Fast convolution FIR filtering is listed as an extra, but the README adds a parenthetical: it is not available for fixed point. A build configured for int16_t or int32_t cannot use the fastconv tool, even though those datatypes work fully for the core transforms and for multi-dimensional FFTs. A project that chooses a fixed-point datatype and later needs convolution filtering has to run that part of the pipeline with the floating-point build.

The README's benchmark puts KISS FFT at roughly half the speed of its unnamed comparison library

The README compares KISS FFT against a library it names only as FFT_BRANDX, explicitly declining to name it. Four figures appear in the background section. FFT_BRANDX has more than 100K lines of code, while the core of KISS FFT is about 500 lines for 1-D complex transforms. A simple program linking FFT_BRANDX compiles to 522 KB; the equivalent using kiss_fft comes to 18 KB. FFT_BRANDX is roughly twice as fast as KISS FFT in default mode.

The README does not name FFT_BRANDX and declines to criticize it. The comparison makes one point: peak performance comes at a cost in code volume and binary size, and KISS FFT is the choice for teams that prefer the smaller side of that trade.

The README also documents a FAQ about unexpected output. Two causes are named: a constant multiplier between the expected and actual result, which points to a scaling issue, and a mixed build environment where not all code was compiled with the same preprocessor definitions. Both failure modes require source-level investigation.

Validation against FFTW and NumPy requires additional dependencies

Testing kissfft results against a reference requires three optional dependencies: libfftw3 as a reference implementation for numerical validation, Python 3 with NumPy as a second validator, and libpng for the psdpng spectrum image tool. OpenMP for multi-core transforms requires a supported compiler and is off by default.

For a single build configuration, running the tests with CMake uses:

bash
make test

To test all possible build configurations, the extended test suite is:

bash
sh test/kissfft-testsuite.sh

The README states the extended suite takes around 20 to 40 minutes depending on the device. It is the recommended path for reporting bugs or reviewing pull requests.

Heap allocation and binary size are both configurable before the first build

The 18 KB binary size from the README comparison reflects a simple program, not a full application. Actual size depends on which transform modules are compiled in and whether the tools/ directory is included. A project that needs only 1-D complex transforms can omit the extras; the tools/ headers and their implementations are separate files.

For projects where the heap is absent, the KISSFFT_USE_ALLOCA option (available in both Make and CMake) removes malloc and free from the transform path. For multi-core workloads, OpenMP support covers GCC, Clang and MSVC when enabled at build time.

Release 131.2.0 arrived on 2025-10-22 and the last push to the repository was on 2026-08-12. GitHub classifies the license as Other because it is a custom text; the README calls the licensing trivial and the built-in FAQ states the library can be used in a project with any license.

Editorial conclusion

Use KISS FFT when your C project needs a 1-D or multi-dimensional FFT and you cannot or do not want to link against a large, heavily optimized library. It is the right choice when fixed-point data types matter or when binary size is constrained. Skip it when throughput is the primary requirement and the complexity of a larger alternative is acceptable. Before choosing the fixed-point path with int16_t or int32_t, confirm that the tools/ functionality you need is available for that datatype, since fast convolution FIR filtering is specifically excluded from fixed-point builds.

Frequently asked questions

What is KISS FFT and what makes it different from other FFT libraries?

KISS FFT is a C FFT library whose core is about 500 lines of code and compiles to around 18 KB in a simple program. The README states it is roughly half the speed of a comparable well-optimized library, but much simpler to integrate and producing far smaller binaries.

What datatypes does KISS FFT support?

The supported datatypes are float (the default), double, int16_t, int32_t, and simd. The simd option requires SSE instruction set support. Datatype selection is a build-time decision made through the KISSFFT_DATATYPE flag.

How do I include KISS FFT in a C project?

Include kiss_fft.h and compile kiss_fft.c alongside your project. Call kiss_fft_alloc to create a configuration, pass the result to kiss_fft for each input, and call kiss_fft_free when finished. The README says this can be done in a few minutes.

Does KISS FFT support multi-dimensional FFTs?

Multi-dimensional FFTs are available through kiss_fftnd.h (N-dimensional complex) and kiss_fftndr.h (N-dimensional real) in the tools/ directory. Real-optimized 1-D transforms in kiss_fftr.h return nfft/2+1 complex frequency bins.

Does KISS FFT support OpenMP multithreading?

OpenMP support is available as an opt-in build option: KISSFFT_OPENMP=1 for Make or -DKISSFFT_OPENMP=ON for CMake. A supported compiler is required and the option is off by default.

Official sources

  1. Issues
  2. mborgerding/kissfft on GitHub
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mborgerding-kissfft.svg)](https://hysenlabs.com/projects/mborgerding-kissfft)