moved FFT-helper functions from Spectrum Analyzer plugin to core to make it also usable by other plugins
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1407 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
10
ChangeLog
10
ChangeLog
@@ -1,3 +1,13 @@
|
||||
2008-07-29 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
|
||||
|
||||
* plugins/spectrum_analyzer/spectrum_analyzer.cpp:
|
||||
* plugins/spectrum_analyzer/spectrum_analyzer.h:
|
||||
* include/fft_helpers.h:
|
||||
* src/core/fft_helpers.cpp:
|
||||
* lmmsconfig.h.in:
|
||||
moved FFT-helper functions from Spectrum Analyzer plugin to core to
|
||||
make it also usable by other plugins
|
||||
|
||||
2008-07-28 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
|
||||
|
||||
* plugins/ladspa_effect/ladspa_controls.cpp:
|
||||
|
||||
88
include/fft_helpers.h
Normal file
88
include/fft_helpers.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* fft_helpers.h - some functions around FFT analysis
|
||||
*
|
||||
* Copyright (c) 2008 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _FFT_HELPERS_H
|
||||
#define _FFT_HELPERS_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#ifdef LMMS_HAVE_FFTW3F
|
||||
|
||||
#include <fftw3.h>
|
||||
|
||||
const int FFT_BUFFER_SIZE = 2048;
|
||||
|
||||
enum WINDOWS
|
||||
{
|
||||
KAISER=1,
|
||||
RECTANGLE,
|
||||
HANNING,
|
||||
HAMMING
|
||||
};
|
||||
|
||||
/* returns biggest value from abs_spectrum[spec_size] array
|
||||
*
|
||||
* returns -1 on error
|
||||
*/
|
||||
float maximum( float * _abs_spectrum, unsigned int _spec_size );
|
||||
|
||||
/* apply hanning or hamming window to channel
|
||||
*
|
||||
* returns -1 on error
|
||||
*/
|
||||
int hanming( float * _timebuffer, int _length, WINDOWS _type );
|
||||
|
||||
/* compute absolute values of complex_buffer, save to absspec_buffer
|
||||
* take care that - compl_len is not bigger than complex_buffer!
|
||||
* - absspec buffer is big enough!
|
||||
*
|
||||
* returns 0 on success, else -1
|
||||
*/
|
||||
int absspec( fftwf_complex * _complex_buffer, float * _absspec_buffer,
|
||||
int _compl_length );
|
||||
|
||||
/* build fewer subbands from many absolute spectrum values
|
||||
* take care that - compressedbands[] array num_new elements long
|
||||
* - num_old > num_new
|
||||
*
|
||||
* returns 0 on success, else -1
|
||||
*/
|
||||
int compressbands( float * _absspec_buffer, float * _compressedband,
|
||||
int _num_old, int _num_new, int _bottom, int _top );
|
||||
|
||||
|
||||
int calc13octaveband31( float * _absspec_buffer, float * _subbands,
|
||||
int _num_spec, float _max_frequency );
|
||||
|
||||
/* compute power of finite time sequence
|
||||
* take care num_values is length of timesignal[]
|
||||
*
|
||||
* returns power on success, else -1
|
||||
*/
|
||||
float signalpower(float *timesignal, int num_values);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -3,6 +3,7 @@
|
||||
#cmakedefine LMMS_BUILD_APPLE
|
||||
|
||||
#cmakedefine LMMS_HAVE_ALSA
|
||||
#cmakedefine LMMS_HAVE_FFTW3F
|
||||
#cmakedefine LMMS_HAVE_JACK
|
||||
#cmakedefine LMMS_HAVE_OGGVORBIS
|
||||
#cmakedefine LMMS_HAVE_OSS
|
||||
|
||||
@@ -58,9 +58,9 @@ spectrumAnalyzer::spectrumAnalyzer( model * _parent,
|
||||
m_framesFilledUp( 0 ),
|
||||
m_energy( 0 )
|
||||
{
|
||||
m_specBuf = (fftwf_complex *) fftwf_malloc( ( BUFFER_SIZE + 1 ) *
|
||||
m_specBuf = (fftwf_complex *) fftwf_malloc( ( FFT_BUFFER_SIZE + 1 ) *
|
||||
sizeof( fftwf_complex ) );
|
||||
m_fftPlan = fftwf_plan_dft_r2c_1d( BUFFER_SIZE*2, m_buffer,
|
||||
m_fftPlan = fftwf_plan_dft_r2c_1d( FFT_BUFFER_SIZE*2, m_buffer,
|
||||
m_specBuf, FFTW_MEASURE );
|
||||
}
|
||||
|
||||
@@ -75,228 +75,6 @@ spectrumAnalyzer::~spectrumAnalyzer()
|
||||
|
||||
|
||||
|
||||
enum WINDOWS
|
||||
{
|
||||
KAISER=1,
|
||||
RECTANGLE,
|
||||
HANNING,
|
||||
HAMMING
|
||||
};
|
||||
|
||||
|
||||
/* returns biggest value from abs_spectrum[spec_size] array
|
||||
|
||||
returns -1 on error
|
||||
*/
|
||||
float maximum(float *abs_spectrum, unsigned int spec_size)
|
||||
{
|
||||
float maxi=0;
|
||||
unsigned int i;
|
||||
|
||||
if ( abs_spectrum==NULL )
|
||||
return -1;
|
||||
|
||||
if (spec_size<=0)
|
||||
return -1;
|
||||
|
||||
for ( i=0; i<spec_size; i++ )
|
||||
{
|
||||
if ( abs_spectrum[i]>maxi )
|
||||
maxi=abs_spectrum[i];
|
||||
}
|
||||
|
||||
return maxi;
|
||||
}
|
||||
|
||||
|
||||
/* apply hanning or hamming window to channel
|
||||
|
||||
returns -1 on error */
|
||||
int hanming(float *timebuffer, int length, int type)
|
||||
{
|
||||
int i;
|
||||
float 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<length; i++ )
|
||||
{
|
||||
timebuffer[i]=timebuffer[i]*(alpha+(1-alpha)*cos(2*M_PI*i/((float)length-1.0)));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* compute absolute values of complex_buffer, save to absspec_buffer
|
||||
take care that - compl_len is not bigger than complex_buffer!
|
||||
- absspec buffer is big enough!
|
||||
|
||||
returns 0 on success, else -1 */
|
||||
int absspec(fftwf_complex *complex_buffer, float *absspec_buffer, int compl_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( (complex_buffer==NULL)||(absspec_buffer==NULL) )
|
||||
return -1;
|
||||
if ( compl_length<=0 )
|
||||
return -1;
|
||||
|
||||
for (i=0; i<compl_length; i++)
|
||||
{
|
||||
absspec_buffer[i]=(float )sqrt(complex_buffer[i][0]*complex_buffer[i][0] + complex_buffer[i][1]*complex_buffer[i][1]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* build fewer subbands from many absolute spectrum values
|
||||
take care that - compressedbands[] array num_new elements long
|
||||
- num_old > num_new
|
||||
|
||||
returns 0 on success, else -1 */
|
||||
int compressbands(float *absspec_buffer, float *compressedband, int num_old, int num_new, int bottom, int top)
|
||||
{
|
||||
float ratio;
|
||||
int i, usefromold;
|
||||
float j;
|
||||
float j_min, j_max;
|
||||
|
||||
if ( (absspec_buffer==NULL)||(compressedband==NULL) )
|
||||
return -1;
|
||||
|
||||
if ( num_old<num_new )
|
||||
return -1;
|
||||
|
||||
if ( (num_old<=0)||(num_new<=0) )
|
||||
return -1;
|
||||
|
||||
if ( bottom<0 )
|
||||
bottom=0;
|
||||
|
||||
if ( top>=num_old )
|
||||
top=num_old-1;
|
||||
|
||||
usefromold=num_old-(num_old-top)-bottom;
|
||||
|
||||
ratio=(float)usefromold/(float)num_new;
|
||||
|
||||
// foreach new subband
|
||||
for ( i=0; i<num_new; i++ )
|
||||
{
|
||||
compressedband[i]=0;
|
||||
|
||||
j_min=(i*ratio)+bottom;
|
||||
|
||||
if ( j_min<0 )
|
||||
j_min=bottom;
|
||||
|
||||
j_max=j_min+ratio;
|
||||
|
||||
for ( j=(int)j_min; j<=j_max; j++ )
|
||||
{
|
||||
compressedband[i]+=absspec_buffer[(int)j];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int calc13octaveband31(float *absspec_buffer, float *subbands, int num_spec, float max_frequency)
|
||||
{
|
||||
static const int onethirdoctavecenterfr[] = {20, 25, 31, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000, 6300, 8000, 10000, 12500, 16000, 20000};
|
||||
int i, j;
|
||||
float f_min, f_max, frequency, bandwith;
|
||||
int j_min, j_max=0;
|
||||
float fpower;
|
||||
|
||||
|
||||
if ( (absspec_buffer==NULL)||(subbands==NULL) )
|
||||
return -1;
|
||||
|
||||
if ( num_spec<31 )
|
||||
return -1;
|
||||
|
||||
if ( max_frequency<=0 )
|
||||
return -1;
|
||||
|
||||
/*** energy ***/
|
||||
fpower=0;
|
||||
for ( i=0; i<num_spec; i++ )
|
||||
{
|
||||
absspec_buffer[i]=(absspec_buffer[i]*absspec_buffer[i])/BUFFER_SIZE;
|
||||
fpower=fpower+(2*absspec_buffer[i]);
|
||||
}
|
||||
fpower=fpower-(absspec_buffer[0]); //dc not mirrored
|
||||
|
||||
|
||||
/*** for each subband: sum up power ***/
|
||||
for ( i=0; i<31; i++ )
|
||||
{
|
||||
subbands[i]=0;
|
||||
|
||||
// calculate bandwith for subband
|
||||
frequency=onethirdoctavecenterfr[i];
|
||||
|
||||
bandwith=(pow(2, 1.0/3.0)-1)*frequency;
|
||||
|
||||
f_min=frequency-bandwith/2.0;
|
||||
f_max=frequency+bandwith/2.0;
|
||||
|
||||
j_min=(int)(f_min/max_frequency*(float)num_spec);
|
||||
|
||||
j_max=(int)(f_max/max_frequency*(float)num_spec);
|
||||
|
||||
|
||||
if ( (j_min<0)||(j_max<0) )
|
||||
{
|
||||
fprintf(stderr, "Error: calc13octaveband31() in %s line %d failed.\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for ( j=j_min; j<=j_max; j++ )
|
||||
{
|
||||
if( j_max<num_spec )
|
||||
subbands[i]+=absspec_buffer[j];
|
||||
}
|
||||
|
||||
} //for
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* compute power of finite time sequence
|
||||
take care num_values is length of timesignal[]
|
||||
|
||||
returns power on success, else -1 */
|
||||
float signalpower(float *timesignal, int num_values)
|
||||
{
|
||||
if ( num_values<=0 )
|
||||
return -1;
|
||||
|
||||
if( timesignal==NULL )
|
||||
return -1;
|
||||
|
||||
float power=0;
|
||||
for ( int i=0; i<num_values; i++ )
|
||||
{
|
||||
power+=timesignal[i]*timesignal[i];
|
||||
}
|
||||
|
||||
return power;
|
||||
}
|
||||
|
||||
|
||||
bool spectrumAnalyzer::processAudioBuffer( sampleFrame * _buf,
|
||||
const fpp_t _frames )
|
||||
@@ -307,10 +85,10 @@ bool spectrumAnalyzer::processAudioBuffer( sampleFrame * _buf,
|
||||
}
|
||||
|
||||
fpp_t f = 0;
|
||||
if( _frames > BUFFER_SIZE )
|
||||
if( _frames > FFT_BUFFER_SIZE )
|
||||
{
|
||||
m_framesFilledUp = 0;
|
||||
f = _frames - BUFFER_SIZE;
|
||||
f = _frames - FFT_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
const int cm = m_saControls.m_channelMode.value();
|
||||
@@ -341,32 +119,35 @@ bool spectrumAnalyzer::processAudioBuffer( sampleFrame * _buf,
|
||||
break;
|
||||
}
|
||||
|
||||
if( m_framesFilledUp < BUFFER_SIZE )
|
||||
if( m_framesFilledUp < FFT_BUFFER_SIZE )
|
||||
{
|
||||
return( isRunning() );
|
||||
}
|
||||
|
||||
|
||||
// hanming( m_buffer, BUFFER_SIZE, HAMMING );
|
||||
// hanming( m_buffer, FFT_BUFFER_SIZE, HAMMING );
|
||||
|
||||
const sample_rate_t sr = engine::getMixer()->processingSampleRate();
|
||||
const int LOWEST_FREQ = 0;
|
||||
const int HIGHEST_FREQ = sr / 2;
|
||||
|
||||
fftwf_execute( m_fftPlan );
|
||||
absspec( m_specBuf, m_absSpecBuf, BUFFER_SIZE+1 );
|
||||
absspec( m_specBuf, m_absSpecBuf, FFT_BUFFER_SIZE+1 );
|
||||
if( m_saControls.m_linearSpec.value() )
|
||||
{
|
||||
compressbands( m_absSpecBuf, m_bands, BUFFER_SIZE+1,
|
||||
compressbands( m_absSpecBuf, m_bands, FFT_BUFFER_SIZE+1,
|
||||
MAX_BANDS,
|
||||
(int)(LOWEST_FREQ*(BUFFER_SIZE+1)/(float)(sr/2)),
|
||||
(int)(HIGHEST_FREQ*(BUFFER_SIZE+1)/(float)(sr/2)));
|
||||
m_energy = maximum( m_bands, MAX_BANDS ) / maximum( m_buffer, BUFFER_SIZE );
|
||||
(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, BUFFER_SIZE+1, sr/2.0);
|
||||
m_energy = signalpower( m_buffer, BUFFER_SIZE ) / maximum( m_buffer, BUFFER_SIZE );
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,14 +26,12 @@
|
||||
#ifndef _SPECTRUM_ANALYZER_H
|
||||
#define _SPECTRUM_ANALYZER_H
|
||||
|
||||
#include <fftw3.h>
|
||||
|
||||
#include "effect.h"
|
||||
#include "fft_helpers.h"
|
||||
#include "spectrumanalyzer_controls.h"
|
||||
|
||||
|
||||
const int MAX_BANDS = 249;
|
||||
const int BUFFER_SIZE = 2048;
|
||||
|
||||
|
||||
class spectrumAnalyzer : public effect
|
||||
@@ -64,8 +62,8 @@ private:
|
||||
fftwf_plan m_fftPlan;
|
||||
|
||||
fftwf_complex * m_specBuf;
|
||||
float m_absSpecBuf[BUFFER_SIZE+1];
|
||||
float m_buffer[BUFFER_SIZE*2];
|
||||
float m_absSpecBuf[FFT_BUFFER_SIZE+1];
|
||||
float m_buffer[FFT_BUFFER_SIZE*2];
|
||||
int m_framesFilledUp;
|
||||
|
||||
float m_bands[MAX_BANDS];
|
||||
|
||||
247
src/core/fft_helpers.cpp
Normal file
247
src/core/fft_helpers.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* fft_helpers.cpp - some functions around FFT analysis
|
||||
*
|
||||
* Copyright (c) 2008 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 "fft_helpers.h"
|
||||
|
||||
#ifdef LMMS_HAVE_FFTW3F
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
/* returns biggest value from abs_spectrum[spec_size] array
|
||||
|
||||
returns -1 on error
|
||||
*/
|
||||
float maximum(float *abs_spectrum, unsigned int spec_size)
|
||||
{
|
||||
float maxi=0;
|
||||
unsigned int i;
|
||||
|
||||
if ( abs_spectrum==NULL )
|
||||
return -1;
|
||||
|
||||
if (spec_size<=0)
|
||||
return -1;
|
||||
|
||||
for ( i=0; i<spec_size; i++ )
|
||||
{
|
||||
if ( abs_spectrum[i]>maxi )
|
||||
maxi=abs_spectrum[i];
|
||||
}
|
||||
|
||||
return maxi;
|
||||
}
|
||||
|
||||
|
||||
/* apply hanning or hamming window to channel
|
||||
|
||||
returns -1 on error */
|
||||
int hanming(float *timebuffer, int length, WINDOWS type)
|
||||
{
|
||||
int i;
|
||||
float 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<length; i++ )
|
||||
{
|
||||
timebuffer[i]=timebuffer[i]*(alpha+(1-alpha)*cos(2*M_PI*i/((float)length-1.0)));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* compute absolute values of complex_buffer, save to absspec_buffer
|
||||
take care that - compl_len is not bigger than complex_buffer!
|
||||
- absspec buffer is big enough!
|
||||
|
||||
returns 0 on success, else -1 */
|
||||
int absspec(fftwf_complex *complex_buffer, float *absspec_buffer, int compl_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( (complex_buffer==NULL)||(absspec_buffer==NULL) )
|
||||
return -1;
|
||||
if ( compl_length<=0 )
|
||||
return -1;
|
||||
|
||||
for (i=0; i<compl_length; i++)
|
||||
{
|
||||
absspec_buffer[i]=(float )sqrt(complex_buffer[i][0]*complex_buffer[i][0] + complex_buffer[i][1]*complex_buffer[i][1]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* build fewer subbands from many absolute spectrum values
|
||||
take care that - compressedbands[] array num_new elements long
|
||||
- num_old > num_new
|
||||
|
||||
returns 0 on success, else -1 */
|
||||
int compressbands(float *absspec_buffer, float *compressedband, int num_old, int num_new, int bottom, int top)
|
||||
{
|
||||
float ratio;
|
||||
int i, usefromold;
|
||||
float j;
|
||||
float j_min, j_max;
|
||||
|
||||
if ( (absspec_buffer==NULL)||(compressedband==NULL) )
|
||||
return -1;
|
||||
|
||||
if ( num_old<num_new )
|
||||
return -1;
|
||||
|
||||
if ( (num_old<=0)||(num_new<=0) )
|
||||
return -1;
|
||||
|
||||
if ( bottom<0 )
|
||||
bottom=0;
|
||||
|
||||
if ( top>=num_old )
|
||||
top=num_old-1;
|
||||
|
||||
usefromold=num_old-(num_old-top)-bottom;
|
||||
|
||||
ratio=(float)usefromold/(float)num_new;
|
||||
|
||||
// foreach new subband
|
||||
for ( i=0; i<num_new; i++ )
|
||||
{
|
||||
compressedband[i]=0;
|
||||
|
||||
j_min=(i*ratio)+bottom;
|
||||
|
||||
if ( j_min<0 )
|
||||
j_min=bottom;
|
||||
|
||||
j_max=j_min+ratio;
|
||||
|
||||
for ( j=(int)j_min; j<=j_max; j++ )
|
||||
{
|
||||
compressedband[i]+=absspec_buffer[(int)j];
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int calc13octaveband31(float *absspec_buffer, float *subbands, int num_spec, float max_frequency)
|
||||
{
|
||||
static const int onethirdoctavecenterfr[] = {20, 25, 31, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000, 5000, 6300, 8000, 10000, 12500, 16000, 20000};
|
||||
int i, j;
|
||||
float f_min, f_max, frequency, bandwith;
|
||||
int j_min, j_max=0;
|
||||
float fpower;
|
||||
|
||||
|
||||
if ( (absspec_buffer==NULL)||(subbands==NULL) )
|
||||
return -1;
|
||||
|
||||
if ( num_spec<31 )
|
||||
return -1;
|
||||
|
||||
if ( max_frequency<=0 )
|
||||
return -1;
|
||||
|
||||
/*** energy ***/
|
||||
fpower=0;
|
||||
for ( i=0; i<num_spec; i++ )
|
||||
{
|
||||
absspec_buffer[i]=(absspec_buffer[i]*absspec_buffer[i])/FFT_BUFFER_SIZE;
|
||||
fpower=fpower+(2*absspec_buffer[i]);
|
||||
}
|
||||
fpower=fpower-(absspec_buffer[0]); //dc not mirrored
|
||||
|
||||
|
||||
/*** for each subband: sum up power ***/
|
||||
for ( i=0; i<31; i++ )
|
||||
{
|
||||
subbands[i]=0;
|
||||
|
||||
// calculate bandwith for subband
|
||||
frequency=onethirdoctavecenterfr[i];
|
||||
|
||||
bandwith=(pow(2, 1.0/3.0)-1)*frequency;
|
||||
|
||||
f_min=frequency-bandwith/2.0;
|
||||
f_max=frequency+bandwith/2.0;
|
||||
|
||||
j_min=(int)(f_min/max_frequency*(float)num_spec);
|
||||
|
||||
j_max=(int)(f_max/max_frequency*(float)num_spec);
|
||||
|
||||
|
||||
if ( (j_min<0)||(j_max<0) )
|
||||
{
|
||||
fprintf(stderr, "Error: calc13octaveband31() in %s line %d failed.\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for ( j=j_min; j<=j_max; j++ )
|
||||
{
|
||||
if( j_max<num_spec )
|
||||
subbands[i]+=absspec_buffer[j];
|
||||
}
|
||||
|
||||
} //for
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* compute power of finite time sequence
|
||||
take care num_values is length of timesignal[]
|
||||
|
||||
returns power on success, else -1 */
|
||||
float signalpower(float *timesignal, int num_values)
|
||||
{
|
||||
if ( num_values<=0 )
|
||||
return -1;
|
||||
|
||||
if( timesignal==NULL )
|
||||
return -1;
|
||||
|
||||
float power=0;
|
||||
for ( int i=0; i<num_values; i++ )
|
||||
{
|
||||
power+=timesignal[i]*timesignal[i];
|
||||
}
|
||||
|
||||
return power;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user