view sv/filter/EqualizerFilter.cpp @ 235:7ab3e81f52d4

enable/disable alternatively draw curve and simple mode in the equalizer filter
author lbajardsilogic
date Fri, 07 Mar 2008 15:01:27 +0000
parents 628531da16ef
children d97cd5461220
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */

/*	Sound Access	
		EASAIER client application.	
		Silogic 2007. Laure Bajard. 
	
	Integration of the filter provided by:
	Dublin Institute of Technology - Audio Research Group 2007
	www.audioresearchgroup.com
	Author: Dan Barry

	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.  See the file    
	COPYING included with this distribution for more information.
*/

#include <math.h>
#include <iostream>

#include "EqualizerFilter.h"

#include  "FFTReal.h"
#include  "DSP.h"

#include "system/System.h"
#include "main/MainWindow.h"


EqualizerFilter::EqualizerFilter(size_t	framesize, QMutex *mutex) : PropertyContainer() ,
	m_simpleMode(true) ,
	m_nbBand(5),
	m_framesize(framesize),
	m_mutex(mutex),
	m_resolution(400)
{
	for (int i=0; i<m_nbBand; i++) {
		m_gainband[i] = 0;
	}
	
	setObjectName("Equalizer");

	m_curve = (float *) calloc(m_resolution, sizeof(float));

	band = (float **)calloc(m_nbBand, sizeof(float*));
	for(int i = 0 ; i < m_nbBand ; i++){
		band[i]=(float *)calloc((m_framesize/2), sizeof(float));
	}

	m_plotbandcurve=(float *)malloc(sizeof(float)*(m_resolution));
	
	if (m_simpleMode)
	{	
		create_filterbands();	
	}
	else
	{
		for(int i = 0 ; i < m_resolution ; i++){
			m_eqcurve.push_back(0);
		}
	}
		
	setFilterEnabled(false);		
}

EqualizerFilter::~EqualizerFilter()
{
	m_eqcurve.clear();

	for(int i = 0 ; i < m_nbBand ; i++){
		delete band[i];
	}
	delete band;
}

EqualizerFilter::PropertyList EqualizerFilter::getProperties() const
{
	PropertyList list;
    list.push_back("Enable");
	for (int i=0; i<m_nbBand; i++) {
		QString name = "GainBand" + QString::number(i);
		list.push_back(name); 
	}
	list.push_back("DrawCurve"); 
	list.push_back("Equalizer");
	return list;
}

QString EqualizerFilter::getPropertyLabel(const PropertyName &name) const
{
    if (name == "Equalizer") return tr("Equalizer");
	if (name == "SimpleMode") return tr("Simple Mode");
	if (name == "DrawCurve") return tr("Draw Curve");
    return "";
}

EqualizerFilter::PropertyType EqualizerFilter::getPropertyType(const PropertyName &name) const
{
	if (name == "Equalizer") return PlotProperty;
    if (name == "Enable") return InvalidProperty;
	if (name == "DrawCurve") return ToggleProperty;
	if (name.left(8) == "GainBand") return RangeProperty;
	return InvalidProperty;
}

QString EqualizerFilter::getPropertyGroupName(const PropertyName &name) const
{
	if (name.left(8) == "GainBand") return "GainBand";
	if ((name == "Equalizer") || (name == "DrawCurve")) return "Draw Curve";
    return QString();
}

int EqualizerFilter::getPropertyRangeAndValue(const PropertyName &name,
                                    int *min, int *max, int *deflt) const
{
    //!!! factor this colour handling stuff out into a colour manager class
	int val = 0;

	if (name == "Equalizer") {
        /*if (deflt) *deflt = 0;
		val = (m_peakcheck ? 1 : 0);*/
    }

	if (name == "Enable") {
        if (deflt) *deflt = 0;
		val = (m_enabled ? 1 : 0);
    }

	if (name == "DrawCurve") {
        if (deflt) *deflt = 0;
		val = (m_simpleMode ? 0 : 1);
    }

	if (name.left(8) == "GainBand") {
		if (min) *min = -100;
		if (max) *max = 100;
		if (deflt) *deflt = 0;
		int i = name.right(1).toInt();
		val = m_gainband[i];
	}

#ifdef DEBUG_FILTERS
	std::cerr << "EqualizerFilter::getPropertyRangeAndValue = " << val << std::endl;
#endif
    return val;
}

QString EqualizerFilter::getPropertyValueLabel(const PropertyName &name,
				    int value) const
{
    return tr("<unknown>");
}

void EqualizerFilter::setProperty(const PropertyName &name, int value)
{
    if (name == "Equalizer"){
		
	} else if (name == "Enable"){
		if (value > 0)
		{
			m_enabled = true;
		} else 
		{
			m_enabled = false;
		}
		emit propertyChanged("Enable");
	} else if (name == "DrawCurve"){
		m_simpleMode = (value > 0) ? false : true;
		if (m_simpleMode)
		{
			create_filterbands();	
		}
		emit enableDrawCurve(!m_simpleMode);
	} else if (name.left(8) == "GainBand"){
		int i = name.right(1).toInt();
		m_gainband[i] = value;
		create_filterbands();	
	} 

#ifdef DEBUG_FILTERS
	std::cerr << "EqualizerFilter::hopfactor = " << hopfactor << std::endl;
	std::cerr << "EqualizerFilter::m_interpfactor = " << m_interpfactor << std::endl;
	std::cerr << "EqualizerFilter::m_hop = " << m_hop << std::endl;
	std::cerr << "EqualizerFilter::skip = " << getRequiredSkipSamples() << std::endl;
#endif

}

void EqualizerFilter::setProperty(const PropertyName &name , QVector<float> value)
{
	if (name == "Equalizer"){
		m_eqcurve.clear();
		for (int i = 0; i < value.size(); i++)
		{
			m_eqcurve.push_back(value.at(i));
		}
	}
}

void EqualizerFilter::setFilterEnabled(bool b){
	m_enabled=b;
	emit filterEnabled(m_enabled);
}

void EqualizerFilter::setFilterEnabled(int b){
	m_enabled=b;
	emit filterEnabled(m_enabled);
}

void EqualizerFilter::emitPlotFFTArray(float *signal, int framesize)
{
	log10plot(signal, m_curve, framesize, m_resolution);	

	emit signalChanged(m_curve);	
}
	

void EqualizerFilter::create_filterbands()
{
	m_mutex->lock();

	float binwidth = 44100/4096;
	
	float xover1 = 80; //100
	float xover2 = 700; //700
	float xover3 = 3000; //3000
	float xover4 = 9000; //9000

	float width1 = 50; //50
	float width2 = 300; //100
	float width3 = 3000; //300
	float width4 = 1900; //900

	int w;

	xover1=(xover1/binwidth);
	xover2=(xover2/binwidth);
	xover3=(xover3/binwidth);
	xover4=(xover4/binwidth);

	width1=(width1/binwidth);
	width2=(width2/binwidth);
	width3=(width3/binwidth);
	width4=(width4/binwidth);

	int p1 = 0;
	int p2 = floor(xover1-(width1/2));
	int p3 = floor(xover1+(width1/2));
	int p4 = floor(xover2-(width2/2));
	int p5 = floor(xover2+(width2/2));
	int p6 = floor(xover3-(width3/2));
	int p7 = floor(xover3+(width3/2));
	int p8 = floor(xover4-(width4/2));
	int p9 = floor(xover4+(width4/2));
	int p10 = 2048;

	float maxcut=190; //18db of attenuation
	float inc_cut=(1-(1/maxcut))/100;
	
	float maxboost=2; //6 db of gain
	float inc_boost=(maxboost-1)/100;
	float g1=1,g2=1,g3=1,g4=1,g5=1,instgain=1;

	if (m_gainband[0] < 0){g1=(1/maxcut)+((100+ (float)m_gainband[0])*inc_cut);} //not finished!!!!
	if (m_gainband[0] == 0){g1=1;}
	if (m_gainband[0] > 0){g1=1+(((float)m_gainband[0])*inc_boost);}

	if (m_gainband[1] < 0){g2=(1/maxcut)+((100+ (float)m_gainband[1])*inc_cut);} //not finished!!!!
	if (m_gainband[1] == 0){g2=1;}
	if (m_gainband[1] > 0){g2=1+(((float)m_gainband[1])*inc_boost);}

	if (m_gainband[2] < 0){g3=(1/maxcut)+((100+ (float)m_gainband[2])*inc_cut);} //not finished!!!!
	if (m_gainband[2] == 0){g3=1;}
	if (m_gainband[2] > 0){g3=1+(((float)m_gainband[2])*inc_boost);}

	if (m_gainband[3] < 0){g4=(1/maxcut)+((100+ (float)m_gainband[3])*inc_cut);} //not finished!!!!
	if (m_gainband[3] == 0){g4=1;}
	if (m_gainband[3] > 0){g4=1+(((float)m_gainband[3])*inc_boost);}

	if (m_gainband[4] < 0){g5=(1/maxcut)+((100+ (float)m_gainband[4])*inc_cut);} //not finished!!!!
	if (m_gainband[4] == 0){g5=1;}
	if (m_gainband[4] > 0){g5=1+(((float)m_gainband[4])*inc_boost);}

	m_eqcurve.clear();

	
	for (int i=0;i<m_framesize/2;i++)
	{
		if (i < p2)
		{
			band[0][i]=1;
			band[1][i]=0;
			band[2][i]=0;
			band[3][i]=0;
			band[4][i]=0;
		}

		if (i >= p2 && i <= p3)
		{	
			w = p3-p2+1;
			band[0][i]= (0.5*(1-cos(2*PI*((i-p2+w)+1)/((2*w)))));
			band[1][i]= (0.5*(1-cos(2*PI*((i-p2)+1)/((2*w)))));
			band[2][i]=0;
			band[3][i]=0;
			band[4][i]=0;
		}


		if (i > p3 && i < p4)
		{
			band[0][i]=0;
			band[1][i]=1;
			band[2][i]=0;
			band[3][i]=0;
			band[4][i]=0;
		}

		if (i >= p4 && i <= p5)
		{	
			w = p4-p5+1;
			band[0][i]=0;
			band[1][i]= (0.5*(1-cos(2*PI*((i-p4+w)+1)/((2*w)))));
			band[2][i]= (0.5*(1-cos(2*PI*((i-p4)+1)/((2*w)))));
			band[3][i]=0;
			band[4][i]=0;
		}

		if (i > p5 && i < p6)
		{
			band[0][i]=0;
			band[1][i]=0;
			band[2][i]=1;
			band[3][i]=0;
			band[4][i]=0;
		}

		if (i >= p6 && i <= p7)
		{	
			w = p6-p7+1;
			band[0][i]=0;
			band[1][i]=0;
			band[2][i]= (0.5*(1-cos(2*PI*((i-p6+w)+1)/((2*w)))));
			band[3][i]= (0.5*(1-cos(2*PI*((i-p6)+1)/((2*w)))));
			band[4][i]=0;
		}

		if (i > p7 && i < p8)
		{
			band[0][i]=0;
			band[1][i]=0;
			band[2][i]=0;
			band[3][i]=1;
			band[4][i]=0;
		}

		if (i >= p8 && i <= p9)
		{	
			w = p8-p9+1;
			band[0][i]=0;
			band[1][i]=0;
			band[2][i]=0;
			band[3][i]= (0.5*(1-cos(2*PI*((i-p8+w)+1)/((2*w)))));
			band[4][i]= (0.5*(1-cos(2*PI*((i-p8)+1)/((2*w)))));
		
		}
	
		if (i > p9 && i < p10)
		{
			band[0][i]=0;
			band[1][i]=0;
			band[2][i]=0;
			band[3][i]=0;
			band[4][i]=1;
		}

		instgain=(g1*band[0][i])+(g2*band[1][i])+(g3*band[2][i])+(g4*band[3][i])+(g5*band[4][i]);
		m_eqcurve.push_back(instgain);
	}	
	
	m_mutex->unlock();

	log10plot2(m_eqcurve,m_plotbandcurve, m_framesize, m_resolution);

	emit filterChanged(m_plotbandcurve);
	
}