File indexing completed on 2024-04-28 04:51:59

0001 /*
0002     SPDX-FileCopyrightText: 2010 Simon Andreas Eugster <simon.eu@gmail.com>
0003     This file is part of kdenlive. See www.kdenlive.org.
0004 
0005 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006 */
0007 
0008 #pragma once
0009 
0010 #include "../../definitions.h"
0011 #include "../external/kiss_fft/tools/kiss_fftr.h"
0012 #include <QHash>
0013 #include <QVector>
0014 
0015 class FFTTools
0016 {
0017 public:
0018     FFTTools();
0019     ~FFTTools();
0020 
0021     enum WindowType { Window_Rect, Window_Triangle, Window_Hamming };
0022 
0023     /** Creates a vector containing the factors for the selected window functions.
0024         The last element in the vector (at position size+1) contains the area of
0025         this window function compared to the rectangular window (e.g. for a triangular
0026         window the factor will be 0.5).
0027         Knowing this factor is important for the Fourier Transformation as the
0028         values in the frequency domain will be scaled by this factor and need to be
0029         re-scaled for proper dB display.
0030         The additional parameter describes:
0031         * Nothing for the Rectangular window
0032         * The left and right start values for the Triangular window (i.e. ranges between param and 1;
0033           default is 0)
0034         * Nothing for the Hamming window
0035     */
0036     static const QVector<float> window(const WindowType windowType, const int size, const float param = 0);
0037 
0038     static const QString windowSignature(const WindowType windowType, const int size, const float param = 0);
0039 
0040     /** Returns a signature for a kiss_fft configuration
0041         used as a hash in the cache */
0042     static const QString cfgSignature(const int size);
0043 
0044     /** Calculates the Fourier Transformation of the input audio frame.
0045         The resulting values will be given in relative decibel: The maximum power is 0 dB, lower powers have
0046         negative dB values.
0047         * audioFrame: Interleaved format with #numChannels channels
0048         * freqSpectrum: Array pointer to write the data into
0049         * windowSize must be divisible by 2,
0050         * freqSpectrum has to be of size windowSize/2
0051         For windowType and param see the FFTTools::window() function above.
0052     */
0053     void fftNormalized(const audioShortVector &audioFrame, const uint channel, const uint numChannels, float *freqSpectrum, const WindowType windowType,
0054                        const uint windowSize, const float param = 0);
0055 
0056     /** This is linear interpolation with the special property that it preserves peaks, which is required
0057         for e.g. showing correct Decibel values (where the peak values are of interest because of clipping which
0058         may occur for too strong frequencies; The lower values are smeared by the window function anyway).
0059         Consider f = {0, 100, 0}
0060                  x = {0.5,  1.5}: With default linear interpolation x0 and x1 would both be mapped to 50.
0061         This function maps x1 (the first position after the peak) to 100.
0062 
0063         @param in           The source vector containing the data
0064         @param targetSize   Number of interpolation nodes between ...
0065         @param left         the left array index in the in-vector and ...
0066         @param right        the right array index (both inclusive).
0067         @param fill         If right lies outside of the array bounds (which is perfectly fine here) then this value
0068                             will be used for filling the missing information.
0069         */
0070     static const QVector<float> interpolatePeakPreserving(const QVector<float> &in, const uint targetSize, uint left = 0, uint right = 0, float fill = 0.0);
0071 
0072 private:
0073     QHash<QString, kiss_fftr_cfg> m_fftCfgs;          // FFT cfg cache
0074     QHash<QString, QVector<float>> m_windowFunctions; // Window function cache
0075 };