diff --git a/ChangeLog b/ChangeLog index 8ce149ff1..843728a73 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2008-06-14 Tobias Doerffel + + * configure.in: + * plugins/Makefile.am: + * plugins/spectrum_analyzer/Makefile.am: + * plugins/spectrum_analyzer/logo.png: + * plugins/spectrum_analyzer/spectrum_analyzer.h: + * plugins/spectrum_analyzer/spectrum_analyzer.cpp: + * plugins/spectrum_analyzer/spectrumanalyzer_controls.h: + * plugins/spectrum_analyzer/spectrumanalyzer_controls.cpp: + * plugins/spectrum_analyzer/spectrumanalyzer_control_dialog.h: + * plugins/spectrum_analyzer/spectrumanalyzer_control_dialog.cpp: + added initial version of spectrum analyzer - very basic at the moment! + + * plugins/bass_booster/bass_booster.cpp: + * plugins/bass_booster/bass_booster.h: + * plugins/bass_booster/bassbooster_controls.h: + * plugins/ladspa_effect/ladspa_controls.h: + * plugins/peak_controller_effect/peak_controller_effect_controls.h: + * plugins/stereo_enhancer/stereoenhancer_controls.h: + * plugins/stereo_matrix/stereomatrix_controls.h: + * plugins/vst_effect/vst_effect_controls.h: + * include/dummy_effect.h: + * include/effect_controls.h: + changed return-type of effectControls::getControlCount() + 2008-06-12 Tobias Doerffel * include/project_renderer.h: diff --git a/configure.in b/configure.in index e38c7c7d0..a550aea3b 100644 --- a/configure.in +++ b/configure.in @@ -2,8 +2,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.50) -AC_INIT(lmms, 0.4.0-svn20080607, lmms-devel/at/lists/dot/sf/dot/net) -AM_INIT_AUTOMAKE(lmms, 0.4.0-svn20080607) +AC_INIT(lmms, 0.4.0-svn20080613, lmms-devel/at/lists/dot/sf/dot/net) +AM_INIT_AUTOMAKE(lmms, 0.4.0-svn20080613) AX_PREFIX_CONFIG_H([include/lmmsconfig.h]) AM_CONFIG_HEADER(config.h) @@ -729,6 +729,7 @@ AC_CONFIG_FILES([Makefile plugins/peak_controller_effect/Makefile plugins/sf2_player/Makefile plugins/singerbot/Makefile + plugins/spectrum_analyzer/Makefile plugins/stk/Makefile plugins/stk/mallets/Makefile plugins/triple_oscillator/Makefile diff --git a/plugins/Makefile.am b/plugins/Makefile.am index 3a1fa3871..aaff43a88 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -28,8 +28,9 @@ SUBDIRS = \ organic \ patman \ peak_controller_effect \ - $(SF2PLAYER_DIR) \ + $(SF2PLAYER_DIR) \ $(SINGERBOT_DIR) \ + spectrum_analyzer \ stereo_enhancer \ stereo_matrix \ $(STK_DIR) \ diff --git a/plugins/spectrum_analyzer/Makefile.am b/plugins/spectrum_analyzer/Makefile.am new file mode 100644 index 000000000..a15cf5bbb --- /dev/null +++ b/plugins/spectrum_analyzer/Makefile.am @@ -0,0 +1,54 @@ +AUTOMAKE_OPTIONS = foreign 1.4 + +PLUGIN_NAME = spectrumanalyzer + + +INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src/gui + + +AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="$(PLUGIN_NAME)" + + +%.moc: ./%.h + $(MOC) -o $@ $< + + +MOC_FILES = ./spectrumanalyzer_controls.moc + +if BUILD_WIN32 +DLL=$(PLUGIN_NAME).dll + +$(DLL): lib$(PLUGIN_NAME).la + $(CXX) *.o -L$(top_srcdir) -llmms-imp -shared -Wl,-no-undefined -o $@ $(QT_LDADD) && $(STRIP) $@ + +install-exec-hook: $(DLL) + cp $< $(pkglibdir) + rm $(pkglibdir)/lib$(PLUGIN_NAME).a $(pkglibdir)/lib$(PLUGIN_NAME).la +else +DLL= +endif + +BUILT_SOURCES = $(MOC_FILES) ./embedded_resources.h $(DLL) +EMBEDDED_RESOURCES = $(wildcard *png) + +./embedded_resources.h: $(EMBEDDED_RESOURCES) + $(BIN2RES) $(EMBEDDED_RESOURCES) > $@ + +EXTRA_DIST = $(EMBEDDED_RESOURCES) + + +CLEANFILES = $(MOC_FILES) ./embedded_resources.h + + + +pkglib_LTLIBRARIES = libspectrumanalyzer.la + +libspectrumanalyzer_la_SOURCES = spectrum_analyzer.cpp \ + spectrum_analyzer.h \ + spectrumanalyzer_controls.cpp \ + spectrumanalyzer_controls.h \ + spectrumanalyzer_control_dialog.cpp \ + spectrumanalyzer_control_dialog.h +libspectrumanalyzer_la_LDFLAGS = -lfftw3 + +$(libspectrumanalyzer_la_SOURCES): ./embedded_resources.h diff --git a/plugins/spectrum_analyzer/logo.png b/plugins/spectrum_analyzer/logo.png new file mode 100644 index 000000000..89e9f3680 Binary files /dev/null and b/plugins/spectrum_analyzer/logo.png differ diff --git a/plugins/spectrum_analyzer/spectrum_analyzer.cpp b/plugins/spectrum_analyzer/spectrum_analyzer.cpp new file mode 100644 index 000000000..493c9b4c5 --- /dev/null +++ b/plugins/spectrum_analyzer/spectrum_analyzer.cpp @@ -0,0 +1,398 @@ +/* + * spectrum_analyzer.cpp - spectrum analyzer plugin + * + * Copyright (c) 2008 Tobias Doerffel + * + * 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" + + +#undef SINGLE_SOURCE_COMPILE +#include "embed.cpp" + + +extern "C" +{ + +plugin::descriptor PLUGIN_EXPORT spectrumanalyzer_plugin_descriptor = +{ + STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ), + "Spectrum Analyzer", + QT_TRANSLATE_NOOP( "pluginBrowser", + "plugin for using arbitrary VST-effects " + "inside LMMS." ), + "Tobias Doerffel ", + 0x0100, + plugin::Effect, + new pluginPixmapLoader( "logo" ), + 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 ) +{ + m_specBuf = (fftw_complex *) fftw_malloc( ( BUFFER_SIZE + 1 ) * + sizeof( fftw_complex ) ); + m_fftPlan = fftw_plan_dft_r2c_1d( BUFFER_SIZE*2, m_buffer, + m_specBuf, FFTW_MEASURE ); +} + + + + +spectrumAnalyzer::~spectrumAnalyzer() +{ + fftw_destroy_plan( m_fftPlan ); + fftw_free( m_specBuf ); +} + + + +enum WINDOWS +{ + KAISER=1, + RECTANGLE, + HANNING, + HAMMING +}; + + +/* returns biggest value from abs_spectrum[spec_size] array + + returns -1 on error +*/ +double maximum(double *abs_spectrum, unsigned int spec_size) +{ + double maxi=0; + unsigned int i; + + if ( abs_spectrum==NULL ) + return -1; + + if (spec_size<=0) + return -1; + + for ( i=0; imaxi ) + maxi=abs_spectrum[i]; + } + + return maxi; +} + + +/* apply hanning or hamming window to channel + + returns -1 on error */ +int hanming(double *timebuffer, int length, int type) +{ + int i; + double alpha; + + if ( (timebuffer==NULL)||(length<=0) ) + return -1; + + switch (type) + { + case HAMMING: alpha=0.54; break; + case HANNING: + default: alpha=0.5; break; + } + + for ( i=0; i num_new + + returns 0 on success, else -1 */ +int compressbands(double *absspec_buffer, double *compressedband, int num_old, int num_new, int bottom, int top) +{ + double ratio; + int i, usefromold; + double j; + double j_min, j_max; + + if ( (absspec_buffer==NULL)||(compressedband==NULL) ) + return -1; + + if ( num_old=num_old ) + top=num_old-1; + + usefromold=num_old-(num_old-top)-bottom; + + ratio=(double)usefromold/(double)num_new; + + // foreach new subband + for ( i=0; i BUFFER_SIZE ) + { + m_framesFilledUp = 0; + f = _frames - 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 < BUFFER_SIZE ) + { + return( isRunning() ); + } + + + hanming( m_buffer, BUFFER_SIZE, HAMMING ); + + const sample_rate_t sr = engine::getMixer()->processingSampleRate(); + const int LOWEST_FREQ = 0; + const int HIGHEST_FREQ = 10000;//sr / 2; + + fftw_execute( m_fftPlan ); + absspec( m_specBuf, m_absSpecBuf, BUFFER_SIZE+1 ); + if( m_saControls.m_linearSpec.value() ) + { + compressbands( m_absSpecBuf, m_bands, BUFFER_SIZE+1, + MAX_BANDS, + LOWEST_FREQ*(BUFFER_SIZE+1)/(double)(sr/2), + HIGHEST_FREQ*(BUFFER_SIZE+1)/(double)(sr/2) ); + m_energy = maximum( m_bands, MAX_BANDS ); + } + else + { + calc13octaveband31( m_absSpecBuf, m_bands, BUFFER_SIZE+1, sr/2.0); + m_energy = signalpower( m_buffer, BUFFER_SIZE ); + } + + + m_framesFilledUp = 0; + + checkGate( 0 ); + + return( isRunning() ); +} + + + + + +extern "C" +{ + +// neccessary for getting instance out of shared lib +plugin * PLUGIN_EXPORT lmms_plugin_main( model * _parent, void * _data ) +{ + return( new spectrumAnalyzer( _parent, + static_cast( + _data ) ) ); +} + +} + diff --git a/plugins/spectrum_analyzer/spectrum_analyzer.h b/plugins/spectrum_analyzer/spectrum_analyzer.h new file mode 100644 index 000000000..b37521534 --- /dev/null +++ b/plugins/spectrum_analyzer/spectrum_analyzer.h @@ -0,0 +1,83 @@ +/* + * spectrum_analyzer.h - spectrum anaylzer + * + * Copyright (c) 2008 Tobias Doerffel + * + * 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. + * + */ + + +#ifndef _SPECTRUM_ANALYZER_H +#define _SPECTRUM_ANALYZER_H + +#include + +#include "effect.h" +#include "spectrumanalyzer_controls.h" + + +const int MAX_BANDS = 400; +const int BUFFER_SIZE = 2048; + + +class spectrumAnalyzer : public effect +{ +public: + enum ChannelModes + { + MergeChannels, + LeftChannel, + RightChannel + } ; + + spectrumAnalyzer( model * _parent, + const descriptor::subPluginFeatures::key * _key ); + virtual ~spectrumAnalyzer(); + virtual bool processAudioBuffer( sampleFrame * _buf, + const fpp_t _frames ); + + virtual effectControls * getControls( void ) + { + return( &m_saControls ); + } + + +private: + spectrumAnalyzerControls m_saControls; + + fftw_plan m_fftPlan; + + fftw_complex * m_specBuf; + double m_absSpecBuf[BUFFER_SIZE+1]; + double m_buffer[BUFFER_SIZE*2]; + int m_framesFilledUp; + + double m_bands[MAX_BANDS]; + double m_energy; + + friend class spectrumAnalyzerControls; + friend class spectrumView; + +} ; + + + + + +#endif diff --git a/plugins/spectrum_analyzer/spectrumanalyzer_control_dialog.cpp b/plugins/spectrum_analyzer/spectrumanalyzer_control_dialog.cpp new file mode 100644 index 000000000..3d28325d5 --- /dev/null +++ b/plugins/spectrum_analyzer/spectrumanalyzer_control_dialog.cpp @@ -0,0 +1,120 @@ +/* + * spectrumanaylzer_control_dialog.cpp - view for spectrum analyzer + * + * Copyright (c) 2008 Tobias Doerffel + * + * 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 +#include + +#include "spectrum_analyzer.h" +#include "song_editor.h" +#include "led_checkbox.h" + + +class spectrumView : public QWidget +{ +public: + spectrumView( spectrumAnalyzer * _s, QWidget * _parent ) : + QWidget( _parent ), + m_sa( _s ) + { + setFixedSize( 400, 200 ); + connect( engine::getSongEditor(), SIGNAL( periodicUpdate() ), + this, SLOT( update() ) ); + } + + virtual ~spectrumView() + { + } + + virtual void paintEvent( QPaintEvent * _pe ) + { + QPainter p( this ); + p.fillRect( rect(), Qt::black ); + const double e = m_sa->m_energy; + if( e <= 0 ) + { + return; + } + + const bool lin_y = m_sa->m_saControls.m_linearYAxis.value(); + double * b = m_sa->m_bands; + const int LOWER_Y = -60; // dB + int h; + if( m_sa->m_saControls.m_linearSpec.value() ) + { + p.setPen( QColor( 0, 255, 0 ) ); + for( int x = 0; x < MAX_BANDS; ++x, ++b ) + { + if( lin_y ) + { + h = height() * (*b / e ); + } + else + { + h = (int)( height() * (20*(log10( *b / e ) ) - LOWER_Y ) / (-LOWER_Y ) ); + } + p.drawLine( x, height(), x, height()-h ); + } + } + else + { + for( int x = 0; x < 31; ++x, ++b ) + { + if( lin_y ) + { + h = height() * (*b / e ); + } + else + { + h = (int)( height() * (20*(log10( *b / e ) ) - LOWER_Y ) / (-LOWER_Y ) ); + } + p.fillRect( x*13, height()-h, 11, h, QColor( 0, 255, 0 ) ); + } + } + } + +private: + spectrumAnalyzer * m_sa; + +} ; + + +spectrumAnalyzerControlDialog::spectrumAnalyzerControlDialog( + spectrumAnalyzerControls * _controls ) : + effectControlDialog( _controls ) +{ + QVBoxLayout * l = new QVBoxLayout( this ); + spectrumView * v = new spectrumView( _controls->m_effect, this ); + + ledCheckBox * lin_spec = new ledCheckBox( tr( "Linear spectrum" ), this ); + ledCheckBox * lin_y = new ledCheckBox( tr( "Linear Y axis" ), this ); + lin_spec->setModel( &_controls->m_linearSpec ); + lin_y->setModel( &_controls->m_linearYAxis ); + l->addWidget( v ); + l->addWidget( lin_spec ); + l->addWidget( lin_y ); + +} + + diff --git a/plugins/spectrum_analyzer/spectrumanalyzer_control_dialog.h b/plugins/spectrum_analyzer/spectrumanalyzer_control_dialog.h new file mode 100644 index 000000000..9a39d4466 --- /dev/null +++ b/plugins/spectrum_analyzer/spectrumanalyzer_control_dialog.h @@ -0,0 +1,44 @@ +/* + * spectrumanalyzer_control_dialog.h - view for spectrum analyzer + * + * Copyright (c) 2008 Tobias Doerffel + * + * 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. + * + */ + +#ifndef _SPECTRUMANALYZER_CONTROL_DIALOG_H +#define _SPECTRUMANALYZER_CONTROL_DIALOG_H + +#include "effect_control_dialog.h" + + +class spectrumAnalyzerControls; + + +class spectrumAnalyzerControlDialog : public effectControlDialog +{ +public: + spectrumAnalyzerControlDialog( spectrumAnalyzerControls * _controls ); + virtual ~spectrumAnalyzerControlDialog() + { + } + +} ; + +#endif diff --git a/plugins/spectrum_analyzer/spectrumanalyzer_controls.cpp b/plugins/spectrum_analyzer/spectrumanalyzer_controls.cpp new file mode 100644 index 000000000..160cf7829 --- /dev/null +++ b/plugins/spectrum_analyzer/spectrumanalyzer_controls.cpp @@ -0,0 +1,59 @@ +/* + * spectrumanaylzer_controls.cpp - controls for spectrum analyzer + * + * Copyright (c) 2008 Tobias Doerffel + * + * 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" + + + +spectrumAnalyzerControls::spectrumAnalyzerControls( spectrumAnalyzer * _eff ) : + effectControls( _eff ), + m_effect( _eff ), + m_linearSpec( FALSE, this, tr( "Linear spectrum" ) ), + m_linearYAxis( TRUE, this, tr( "Linear Y-axis" ) ), + m_channelMode( spectrumAnalyzer::MergeChannels, spectrumAnalyzer::MergeChannels, spectrumAnalyzer::RightChannel, this, tr( "Channel mode" ) ) +{ +} + + + + +void spectrumAnalyzerControls::loadSettings( const QDomElement & _this ) +{ +// m_freqModel.setValue( _this.attribute( "freq" ).toFloat() ); +} + + + + +void spectrumAnalyzerControls::saveSettings( QDomDocument & _doc, + QDomElement & _this ) +{ +// _this.setAttribute( "freq", m_freqModel.value() ); +} + + + +#include "spectrumanalyzer_controls.moc" + diff --git a/plugins/spectrum_analyzer/spectrumanalyzer_controls.h b/plugins/spectrum_analyzer/spectrumanalyzer_controls.h new file mode 100644 index 000000000..68536c820 --- /dev/null +++ b/plugins/spectrum_analyzer/spectrumanalyzer_controls.h @@ -0,0 +1,75 @@ +/* + * spectrumanaylzer_controls.h - controls for spectrum-analyzer + * + * Copyright (c) 2008 Tobias Doerffel + * + * 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. + * + */ + +#ifndef _SPECTRUMANALYZER_CONTROLS_H +#define _SPECTRUMANALYZER_CONTROLS_H + +#include "effect_controls.h" +#include "spectrumanalyzer_control_dialog.h" +#include "knob.h" + + +class spectrumAnalyzer; + + +class spectrumAnalyzerControls : public effectControls +{ + Q_OBJECT +public: + spectrumAnalyzerControls( spectrumAnalyzer * _eff ); + virtual ~spectrumAnalyzerControls() + { + } + + virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); + virtual void loadSettings( const QDomElement & _this ); + inline virtual QString nodeName( void ) const + { + return( "spectrumanaylzercontrols" ); + } + + virtual int getControlCount( void ) + { + return( 1 ); + } + + virtual effectControlDialog * createView( void ) + { + return( new spectrumAnalyzerControlDialog( this ) ); + } + + +private: + spectrumAnalyzer * m_effect; + boolModel m_linearSpec; + boolModel m_linearYAxis; + intModel m_channelMode; + + friend class spectrumAnalyzer; + friend class spectrumAnalyzerControlDialog; + friend class spectrumView; + +} ; + +#endif