Was commented out anyway, see line 137...
[audit:audit.git] / interface / SpectralView.cpp
1 #include <sndfile.h>
2 #include <QApplication>
3 #include <QImage>
4 #include <QGraphicsScene>
5 #include <QGraphicsView>
6 #include <QMouseEvent>
7 #include <QPixmap>
8 #include <QPushButton>
9 #include <QPainter>
10 #include <vector>
11 #include <stk/BiQuad.h>
12
13 #include "STFTProcessor.cpp"
14 #include "SpectrumPixmap.cpp"
15
16 #include "colors.h"
17
18 struct LocalToneInfo {
19   float time;
20   float time_stddev;
21   float frequency;
22   float frequency_stddev;
23 };
24
25 class SpectralView : public QGraphicsView {
26   std::vector<std::vector<fftw_complex> > spectrum_buffer;
27   std::vector<std::vector<float> > dt_buffer;
28   std::vector<std::vector<float> > dw_buffer;
29   SpectrumPixmap spm;
30
31   QGraphicsPixmapItem *qgi;
32   QPixmap qp2;
33   QGraphicsScene *qs;  
34   void InitBuffers(int frames,int coeffs) {
35     spectrum_buffer.resize(frames);
36     dt_buffer.resize(frames);
37     dw_buffer.resize(frames);
38
39     for (int i = 0; i < frames; i++) {
40       spectrum_buffer[i].resize(coeffs);
41       dt_buffer[i].resize(coeffs);
42       dw_buffer[i].resize(coeffs);
43     }
44     
45   }
46 public:
47   SpectralView(QWidget *parent,int frames,int coeffs):QGraphicsView::QGraphicsView(parent) {
48     InitBuffers(frames,coeffs);
49
50     QImage *qi=new QImage(frames,coeffs,QImage::Format_RGB32);
51
52     spm=SpectrumPixmap::fromImage(*qi,0);
53
54     qs=new QGraphicsScene(parent);
55     qs->addPixmap(spm);
56
57     QImage *qi2=new QImage(frames,coeffs,QImage::Format_ARGB32);
58     //    QSize qsz(frames,coeffs);
59     qp2=QPixmap::fromImage(*qi2,0);
60
61     qgi=qs->addPixmap(qp2);
62
63     this->setScene(qs);
64     this->resize(frames+20,coeffs+20);
65
66   }
67
68   SpectralView(QWidget *parent,SNDFILE * sf):QGraphicsView::QGraphicsView(parent) {
69     float * buffer=STFTProcessor::getBuffer(sf);
70     
71     int frames=40000/64;
72     int coeffs=256;
73
74     InitBuffers(frames,coeffs);
75
76     STFTProcessor::stft(buffer,
77                         40000,
78                         STFTProcessor::gaussian_window(coeffs),
79                         coeffs*2,
80                         64,
81                         &spectrum_buffer,
82                         &dt_buffer,
83                         &dw_buffer);
84
85     unsigned char * data= new unsigned char [frames*coeffs*4];
86
87     float v,v_;
88     int r,g,b;
89     for (int i=0;i<frames;i++) {
90       for (int j=0;j<coeffs;j++) {
91         v=max(min(floor((log(cabs(spectrum_buffer[i][j]*j))+2)*40),240),0);
92         v_=min(max(cabs(spectrum_buffer[i][j]*j),0)*2,HLSMAX);
93         //      printf("%f\n",(carg(spectrum_buffer[i][j]/spectrum_buffer[(i+1)%frames][j])+M_PI)*((HLSMAX-1)/(2*M_PI)));
94
95         HLStoRGB((carg(spectrum_buffer[i][j]/spectrum_buffer[(i+1)%frames][j])+M_PI)*((HLSMAX-1)/(2*M_PI)),
96                  v/2,
97                  v_,
98                  &r,&g,&b);
99
100                  /*
101         HLStoRGB((dw_buffer[i][j])*((HLSMAX-1)/100),
102                  v/3+HLSMAX/3,
103                  min(max(cabs(spectrum_buffer[i][j]*j),0)*500,HLSMAX),
104                  &r,&g,&b);
105         */
106         data[(i+j*frames)*4+2]=r;
107         data[(i+j*frames)*4+1]=g;
108         data[(i+j*frames)*4+0]=b;
109         //      data[(i+j*frames)*4  ]=0; //b
110         //      data[(i+j*frames)*4+1]=c; //g
111         //      data[(i+j*frames)*4+2]=0; //r
112         data[(i+j*frames)*4+3]=255;
113       }
114     }
115
116
117     QImage *qi=new QImage(data,frames,coeffs,QImage::Format_RGB32);
118
119     spm=SpectrumPixmap::fromImage(*qi,0);
120
121     qs=new QGraphicsScene(parent);
122     qs->addPixmap(spm);
123
124     QImage *qi2=new QImage(frames,coeffs,QImage::Format_ARGB32);
125     //    QSize qsz(frames,coeffs);
126     qp2=QPixmap::fromImage(*qi2,0);
127
128     /*    QPainter *qp;
129     qp=new QPainter(&qp2);
130     //    qp->begin();
131     qp->drawPoint(10,10);
132     qp->end();*/
133
134     qgi=qs->addPixmap(qp2);
135
136     this->setScene(qs);
137     this->resize(frames+20,coeffs+20);
138   }
139
140   void mousePressEvent(QMouseEvent *event) {
141     //    printf("P %i %i",event->x(),event->y());
142
143     QPainter qp(&qp2);
144     //    qp->begin();
145     
146     int x=event->x()-10;
147     int y=event->y()-10;
148     //    qp.drawPoint(x+dt_buffer[x][y],y+dw_buffer[x][y]);
149
150     std::list<struct LocalToneInfo *> tone;
151     //    printf("%i %i\n",x,y); 
152     tone=trackTone(x,y);
153
154     std::list<struct LocalToneInfo *>::iterator i=tone.begin();
155
156     for(i=tone.begin(); i != tone.end(); ++i) {
157       //      printf("%f %f\n",(*i)->time,(*i)->frequency); 
158       qp.drawPoint((*i)->time,(*i)->frequency);      
159     }
160
161     qp.end();
162
163     qs->removeItem((QGraphicsItem *)qgi);
164     qs->update(1,1,100,100);
165     qgi=qs->addPixmap(qp2);
166   }
167
168   std::list<struct LocalToneInfo *> trackTone(int frame,int coeff) {
169     printf("%i\t%i\n",frame,coeff);
170     std::list<struct LocalToneInfo *> result;
171     
172     int end=0;
173     float x=frame;
174     float y=coeff;
175     //    int skip=1;
176     int t=0;
177
178     float cum=0;
179     float weight=0;
180     for (int i=-5;i<5;i++) {
181       cum+=(coeff+i-dw_buffer[frame][coeff+i])*cabs(spectrum_buffer[frame][coeff+i]);
182       weight+=cabs(spectrum_buffer[frame][coeff+i]);
183     }
184
185     do {
186       struct LocalToneInfo * lti=new LocalToneInfo();
187       lti->time=x;
188       lti->time_stddev=-1;
189       lti->frequency=y;
190       lti->frequency_stddev=-1;
191       result.push_back(lti);
192       //      x+=dt_buffer[x][y];
193       //      printf("%f %f\n",creal(spectrum_buffer[x][y]),cimag(spectrum_buffer[x][y]));
194       //      printf("%f\t%f\n",cabs(spectrum_buffer[x][y]),dw_buffer[x][y]);
195       x++;
196       printf("%f %i %i\n",dw_buffer[x][y],(int)x,(int)y);
197       if (dw_buffer[x][y]<0)
198         y+=max(dw_buffer[x][y],-2);
199       else
200         y+=min(dw_buffer[x][y],2);
201       if (x>600 || ((t++)>60))
202         end=1;
203     } while (!end);
204
205     return result;
206   }
207
208   void test() {
209     stk::BiQuad notch;
210
211     notch.setNotch(0.1,0.01);
212     for (int i=0;i<100;i++)
213       notch.tick(0.5);
214     
215   }
216
217   /*  void mouseReleaseEvent(QMouseEvent *event) {
218     //    printf("R %i %i",event->x()-10,event->y()-10);
219     }*/
220   /*
221   bool event(QEvent * e) {
222     printf(".");
223     if (e->type()==QEvent::MouseButtonPress)
224       printf("p");
225     if (e->type()==QEvent::MouseButtonRelease)
226       printf("r");
227     return QGraphicsView::event(e);
228   }
229   */
230 };