aboutsummaryrefslogtreecommitdiff
path: root/Src/Winamp/benskiQ/EqBand.cpp
blob: ea9d40378f5db3863529f9f52fddef89c9f911f2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include "EqBand.h"
#include <assert.h>
#include <math.h>

EqBand::EqBand() : sampleRate(44100), centerFrequency(1000), gain(1), _q(0.5), nch(0), channels(0), bypass(true)
{
}

void EqBand::set_num_channels(int num_channels)
{
	if (nch < num_channels)
	{
		nch = num_channels;
		delete[]channels;
		channels = new Biquad[nch];
		clear_buffers();
		set_parameters(centerFrequency, gain, _q);
	}
}

void EqBand::SetSampleRate(double sample_freq)
{
	if (sample_freq != sampleRate)
	{
		sampleRate = sample_freq;
		for (int chn = 0; chn < nch; ++chn)
		{
			channels[chn].SetSampleRate(sampleRate);
		}
		clear_buffers();
		set_parameters(centerFrequency, gain, _q);
	}
}

void EqBand::set_parameters(double freq, double newGain, double q)
{
	centerFrequency = freq;
	gain = newGain;
	_q = q;

	if (nch > 0)
	{
		Biquad & ref_filter = channels[0];

		ref_filter.set_freq(centerFrequency);

		double a[3] = { 1, 1/_q, 1 };
		double b[3] = {1, gain / _q, 1};
		ref_filter.set_s_eq(b, a);

		ref_filter.transform_s_to_z();

		for (int chn = 1; chn < nch; ++chn)
			channels[chn].copy_filter(ref_filter);
	}

	bypass = (fabs(gain - 1.0) < 0.02); // About 1/4 dB
}

void EqBand::process(float ** const out, float ** in, long nbr_spl, int nbr_chn)
{
	assert(nbr_chn >= 0);
	assert(nbr_chn <= nch);

	if (!bypass)
	{
		for (int chn = 0; chn < nbr_chn; ++chn)
		{
			channels[chn].process_block(out[chn], in[chn], nbr_spl);
		}
	}
}

void EqBand::clear_buffers()
{
	for (int chn = 0; chn < nch; ++chn)
	{
		channels[chn].clear_buffers();
	}
}