LMMS
Loading...
Searching...
No Matches
Fl_EQGraph.cpp
Go to the documentation of this file.
1/*
2 ZynAddSubFX - a software synthesizer
3
4 Fl_EQGraph.cpp - Equalizer Graphical View
5 Copyright (C) 2016 Mark McCurry
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11*/
12#include <FL/Fl.H>
13#include <FL/fl_draw.H>
14#include "Fl_EQGraph.H"
15#include "common.H"
17#include "../DSP/FFTwrapper.h"
18#include "../globals.h"
19
20#include <rtosc/rtosc.h>
21
22using namespace zyncarla;
23
24#define MAX_DB 30
25
26Fl_EQGraph::Fl_EQGraph(int x,int y, int w, int h, const char *label)
27 :Fl_Box(x,y,w,h,label), Fl_Osc_Widget(this), samplerate(48000), gain(0.5f)
28{
29 memset(num, 0, sizeof(num));
30 memset(dem, 0, sizeof(dem));
31 num[0] = 1;
32 dem[0] = 1;
33 ext = "eq-coeffs";
34 osc->createLink("/samplerate", this);
35 osc->requestValue("/samplerate");
36 oscRegister("eq-coeffs");
37 oscRegister("parameter0");
38}
39
42
43void Fl_EQGraph::OSC_raw(const char *msg)
44{
45 if(strstr(msg, "samplerate") && !strcmp("f", rtosc_argument_string(msg))) {
47 } else if(strstr(msg, "parameter0") && !strcmp("i", rtosc_argument_string(msg))) {
48 gain = powf(0.005f, (1.0f-rtosc_argument(msg, 0).i/127.0f)) * 10.0f;
49 } else {
50 memcpy(dem, rtosc_argument(msg, 0).b.data, sizeof(dem));
51 memcpy(num, rtosc_argument(msg, 1).b.data, sizeof(num));
52 redraw();
53 }
54}
55
57{
58 oscWrite("eq-coeffs");
59}
60
62{
63 fl_color(FL_GRAY);
64 float freqx=getfreqpos(freq);
65 switch(type){
66 case 0:if (active_r()) fl_color(FL_WHITE);
67 else fl_color(205,205,205);
68 fl_line_style(FL_SOLID);
69 break;
70 case 1:fl_line_style(FL_DOT);break;
71 case 2:fl_line_style(FL_DASH);break;
72 };
73
74
75 if ((freqx>0.0)&&(freqx<1.0))
76 fl_line(x()+(int) (freqx*w()),y(),
77 x()+(int) (freqx*w()),y()+h());
78}
79
81{
82 int ox=x(),oy=y(),lx=w(),ly=h(),i;
83 double iy,oiy;
84 float freqx;
85
86 if (active_r()) fl_color(fl_darker(FL_GRAY));
87 else fl_color(FL_GRAY);
88 fl_rectf(ox,oy,lx,ly);
89
90
91 //draw the lines
92 fl_color(fl_lighter(FL_GRAY));
93
94 fl_line_style(FL_SOLID);
95 fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2);
96
97 freqx=getfreqpos(1000.0);
98 if ((freqx>0.0)&&(freqx<1.0))
99 fl_line(ox+(int) (freqx*lx),oy,
100 ox+(int) (freqx*lx),oy+ly);
101
102 for (i=1;i<10;i++) {
103 if(i==1) {
104 draw_freq_line(i*100.0,0);
105 draw_freq_line(i*1000.0,0);
106 } else
107 if (i==5) {
108 draw_freq_line(i*10.0,2);
109 draw_freq_line(i*100.0,2);
110 draw_freq_line(i*1000.0,2);
111 } else {
112 draw_freq_line(i*10.0,1);
113 draw_freq_line(i*100.0,1);
114 draw_freq_line(i*1000.0,1);
115 };
116 };
117
118 draw_freq_line(10000.0,0);
119 draw_freq_line(20000.0,1);
120
121
122 fl_line_style(FL_DOT);
123 int GY=6;if (ly<GY*3) GY=-1;
124 for (i=1;i<GY;i++){
125 int tmp=(int)(ly/(float)GY*i);
126 fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp);
127 };
128
129
130 //draw the frequency response
131 if (active_r()) fl_color(FL_YELLOW);
132 else fl_color(200,200,80);
133 fl_line_style(FL_SOLID,2);
134 //fl_color( fl_color_add_alpha( fl_color(), 127 ) );
135 oiy=getresponse(ly,getfreqx(0.0));
136 fl_begin_line();
137 for (i=1;i<lx;i++){
138 float frq=getfreqx(i/(float) lx);
139 if (frq>samplerate/2) break;
140 iy=getresponse(ly,frq);
141 if ((oiy>=0) && (oiy<ly) &&
142 (iy>=0) && (iy<ly) )
143 fl_vertex(ox+i,oy+ly-iy);
144 oiy=iy;
145 };
146 fl_end_line();
147 fl_line_style(FL_SOLID,0);
148}
149
150/*
151 * For those not too familiar with digital filters, what is happening here is an
152 * evaluation of the filter's frequency response through the evaluation of
153 * H(z^{-1}) via z^{-1}=e^{j\omega}.
154 * This will yield a complex result which will indicate the phase and magnitude
155 * transformation of the input at the set frequency denoted by \omega
156 */
157double Fl_EQGraph::getresponse(int maxy,float freq) const
158{
159 const float angle = 2*PI*freq/samplerate;
160 float mag = 1;
161 //std::complex<float> num_res = 0;
162 //std::complex<float> dem_res = 0;
163
164
165 for(int i = 0; i < MAX_EQ_BANDS*MAX_FILTER_STAGES; ++i) {
166 if(num[3*i] == 0)
167 break;
168 std::complex<float> num_res= 0;
169 std::complex<float> dem_res= 0;
170 for(int j=0; j<3; ++j) {
171 num_res += FFTpolar<float>(num[3*i+j], j*angle);
172 dem_res += FFTpolar<float>(dem[3*i+j], j*angle);
173 }
174 mag *= abs(num_res/dem_res);
175 }
176
177 float dbresp=20*log(mag*gain)/log(10);
178
179 //rescale
180 return (int) ((dbresp/MAX_DB+1.0)*maxy/2.0);
181}
182
183float Fl_EQGraph::getfreqx(float x) const
184{
185 if(x>1.0)
186 x=1.0;
187 return(20.0*pow((float)1000.0,x));
188}
189
190float Fl_EQGraph::getfreqpos(float freq) const
191{
192 if(freq<0.00001)
193 freq=0.00001;
194 return(log(freq/20.0)/log(1000.0));
195}
#define MAX_FILTER_STAGES
Definition globals.h:168
#define MAX_EQ_BANDS
Definition globals.h:159
#define MAX_DB
Definition Fl_EQGraph.cpp:24
CAdPlugDatabase::CRecord::RecordType type
Definition adplugdb.cpp:93
void draw(void)
Definition Fl_EQGraph.cpp:80
float num[MAX_EQ_BANDS *MAX_FILTER_STAGES *3]
Definition Fl_EQGraph.H:39
void update(void)
Definition Fl_EQGraph.cpp:56
virtual ~Fl_EQGraph(void)
Definition Fl_EQGraph.cpp:40
void OSC_raw(const char *msg)
Definition Fl_EQGraph.cpp:43
float gain
Definition Fl_EQGraph.H:38
float dem[MAX_EQ_BANDS *MAX_FILTER_STAGES *3]
Definition Fl_EQGraph.H:40
float getfreqx(float x) const
Definition Fl_EQGraph.cpp:183
double getresponse(int maxy, float freq) const
Definition Fl_EQGraph.cpp:157
float samplerate
Definition Fl_EQGraph.H:37
Fl_EQGraph(int x, int y, int w, int h, const char *label=0)
Definition Fl_EQGraph.cpp:26
void draw_freq_line(float freq, int type)
Definition Fl_EQGraph.cpp:61
float getfreqpos(float freq) const
Definition Fl_EQGraph.cpp:190
Fl_Osc_Interface * osc
Definition Fl_Osc_Widget.H:65
std::string ext
Definition Fl_Osc_Widget.H:64
Fl_Osc_Widget(void)
Definition Fl_Osc_Widget.cpp:16
void oscRegister(const char *path)
Definition Fl_Osc_Widget.cpp:91
void oscWrite(std::string path, const char *args,...)
Definition Fl_Osc_Widget.cpp:60
UINT_D64 w
Definition inflate.c:942
register unsigned j
Definition inflate.c:1576
int y
Definition inflate.c:1588
int lx[BMAX+1]
Definition inflate.c:1578
register unsigned i
Definition inflate.c:1575
unsigned x[BMAX+1]
Definition inflate.c:1586
#define PI
Definition eel_mdct.h:18
JHUFF_TBL long freq[]
Definition jchuff.h:50
const char * msg
Definition missing_descriptor.c:20
Definition zynaddsubfx-src.cpp:569
std::complex< _Tp > FFTpolar(const _Tp &__rho, const _Tp &__theta=_Tp(0))
Definition FFTwrapper.h:51
float abs(const fft_t *freqs, off_t x)
Definition OscilGen.cpp:280
const char * rtosc_argument_string(const char *msg)
Definition rtosc.c:11
rtosc_arg_t rtosc_argument(const char *msg, unsigned idx)
Definition rtosc.c:732
Definition globals.h:33
float f
Definition rtosc.h:49
memcpy(hh, h, RAND_HEAD_LEN)
uch h[RAND_HEAD_LEN]
Definition crypt.c:459
b
Definition crypt.c:628
typedef int(UZ_EXP MsgFn)()