Files
lmms/plugins/spectrum_analyzer/spectrum_analyzer.cpp
Tobias Doerffel 0ff1f91c1b Mixer: renamed class and file name
The mixer class is now named "Mixer" and accessible via engine::mixer().
2014-01-08 22:35:14 +01:00

183 lines
3.9 KiB
C++

/*
* spectrum_analyzer.cpp - spectrum analyzer plugin
*
* Copyright (c) 2008-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* 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
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#include "spectrum_analyzer.h"
#include "embed.cpp"
extern "C"
{
Plugin::Descriptor PLUGIN_EXPORT spectrumanalyzer_plugin_descriptor =
{
STRINGIFY( PLUGIN_NAME ),
"Spectrum Analyzer",
QT_TRANSLATE_NOOP( "pluginBrowser",
"plugin for using arbitrary VST-effects "
"inside LMMS." ),
"Tobias Doerffel <tobydox/at/users.sf.net>",
0x0100,
Plugin::Effect,
new PluginPixmapLoader( "logo" ),
NULL,
NULL
} ;
}
spectrumAnalyzer::spectrumAnalyzer( Model * _parent,
const Descriptor::SubPluginFeatures::Key * _key ) :
Effect( &spectrumanalyzer_plugin_descriptor, _parent, _key ),
m_saControls( this ),
m_framesFilledUp( 0 ),
m_energy( 0 )
{
memset( m_buffer, 0, sizeof( m_buffer ) );
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 );
}
spectrumAnalyzer::~spectrumAnalyzer()
{
fftwf_destroy_plan( m_fftPlan );
fftwf_free( m_specBuf );
}
bool spectrumAnalyzer::processAudioBuffer( sampleFrame * _buf,
const fpp_t _frames )
{
if( !isEnabled() || !isRunning () )
{
return( false );
}
if( !m_saControls.isViewVisible() )
{
return true;
}
fpp_t f = 0;
if( _frames > FFT_BUFFER_SIZE )
{
m_framesFilledUp = 0;
f = _frames - FFT_BUFFER_SIZE;
}
const int cm = m_saControls.m_channelMode.value();
switch( cm )
{
case MergeChannels:
for( ; f < _frames; ++f )
{
m_buffer[m_framesFilledUp] =
( _buf[f][0] + _buf[f][1] ) * 0.5;
++m_framesFilledUp;
}
break;
case LeftChannel:
for( ; f < _frames; ++f )
{
m_buffer[m_framesFilledUp] = _buf[f][0];
++m_framesFilledUp;
}
break;
case RightChannel:
for( ; f < _frames; ++f )
{
m_buffer[m_framesFilledUp] = _buf[f][1];
++m_framesFilledUp;
}
break;
}
if( m_framesFilledUp < FFT_BUFFER_SIZE )
{
return( isRunning() );
}
// hanming( m_buffer, FFT_BUFFER_SIZE, HAMMING );
const sample_rate_t sr = engine::mixer()->processingSampleRate();
const int LOWEST_FREQ = 0;
const int HIGHEST_FREQ = sr / 2;
fftwf_execute( m_fftPlan );
absspec( m_specBuf, m_absSpecBuf, FFT_BUFFER_SIZE+1 );
if( m_saControls.m_linearSpec.value() )
{
compressbands( m_absSpecBuf, m_bands, FFT_BUFFER_SIZE+1,
MAX_BANDS,
(int)(LOWEST_FREQ*(FFT_BUFFER_SIZE+1)/(float)(sr/2)),
(int)(HIGHEST_FREQ*(FFT_BUFFER_SIZE+1)/(float)(sr/2)));
m_energy = maximum( m_bands, MAX_BANDS ) /
maximum( m_buffer, FFT_BUFFER_SIZE );
}
else
{
calc13octaveband31( m_absSpecBuf, m_bands,
FFT_BUFFER_SIZE+1, sr/2.0 );
m_energy = signalpower( m_buffer, FFT_BUFFER_SIZE ) /
maximum( m_buffer, FFT_BUFFER_SIZE );
}
m_framesFilledUp = 0;
checkGate( 0 );
return( isRunning() );
}
extern "C"
{
// necessary for getting instance out of shared lib
Plugin * PLUGIN_EXPORT lmms_plugin_main( Model * _parent, void * _data )
{
return( new spectrumAnalyzer( _parent,
static_cast<const Plugin::Descriptor::SubPluginFeatures::Key *>(
_data ) ) );
}
}