From b3054fd6398b1ec51fbee8087f6378c8c9f32d49 Mon Sep 17 00:00:00 2001 From: Dave French Date: Sat, 15 Jul 2017 22:27:30 +0100 Subject: [PATCH] Equalizer plugin, refinement to analysis display (#3530) The spectural analysis was using a rectangle window, leading to high spectural leakage. This pull request uses the Blackman-Harris window to give a display more representative of the audio. --- plugins/Eq/EqSpectrumView.cpp | 23 +++++++++++++++++++++-- plugins/Eq/EqSpectrumView.h | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/plugins/Eq/EqSpectrumView.cpp b/plugins/Eq/EqSpectrumView.cpp index 0f29ffec307..d44e01ece3c 100644 --- a/plugins/Eq/EqSpectrumView.cpp +++ b/plugins/Eq/EqSpectrumView.cpp @@ -1,9 +1,8 @@ /* eqspectrumview.cpp - implementation of EqSpectrumView class. * -* Copyright (c) 2014 David French +* Copyright (c) 2014-2017, David French * * This file is part of LMMS - https://lmms.io -* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either @@ -38,6 +37,20 @@ EqAnalyser::EqAnalyser() : m_inProgress=false; m_specBuf = ( fftwf_complex * ) fftwf_malloc( ( FFT_BUFFER_SIZE + 1 ) * sizeof( fftwf_complex ) ); m_fftPlan = fftwf_plan_dft_r2c_1d( FFT_BUFFER_SIZE*2, m_buffer, m_specBuf, FFTW_MEASURE ); + + //initialize Blackman-Harris window, constants taken from + //https://en.wikipedia.org/wiki/Window_function#A_list_of_window_functions + const float a0 = 0.35875; + const float a1 = 0.48829; + const float a2 = 0.14128; + const float a3 = 0.01168; + + for(int i = 0; i < FFT_BUFFER_SIZE; i++) + { + m_fftWindow[i] = ( a0 - a1 * cosf( 2 * F_PI * i / (float)FFT_BUFFER_SIZE - 1 ) + + a2 * cosf( 4 * F_PI * i / (float)FFT_BUFFER_SIZE-1) + - a3 * cos( 6 * F_PI * i / (float)FFT_BUFFER_SIZE - 1.0 )); + } clear(); } @@ -84,6 +97,12 @@ void EqAnalyser::analyze( sampleFrame *buf, const fpp_t frames ) const int LOWEST_FREQ = 0; const int HIGHEST_FREQ = m_sampleRate / 2; + //apply FFT window + for( int i = 0; i < FFT_BUFFER_SIZE; i++ ) + { + m_buffer[i] = m_buffer[i] * m_fftWindow[i]; + } + fftwf_execute( m_fftPlan ); absspec( m_specBuf, m_absSpecBuf, FFT_BUFFER_SIZE+1 ); diff --git a/plugins/Eq/EqSpectrumView.h b/plugins/Eq/EqSpectrumView.h index 2c615d888ac..cd3f1775863 100644 --- a/plugins/Eq/EqSpectrumView.h +++ b/plugins/Eq/EqSpectrumView.h @@ -32,7 +32,6 @@ const int MAX_BANDS = 2048; - class EqAnalyser { public: @@ -61,6 +60,7 @@ class EqAnalyser int m_sampleRate; bool m_active; bool m_inProgress; + float m_fftWindow[FFT_BUFFER_SIZE]; };