PianoScale.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2006-2013 Chris Cannam and QMUL.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #include "PianoScale.h"
17 
18 #include <QPainter>
19 
20 #include <cmath>
21 
22 #include "base/Pitch.h"
23 
24 #include "LayerGeometryProvider.h"
26 
27 #include <iostream>
28 using namespace std;
29 
30 void
32  QPainter &paint,
33  QRect r,
34  double minf,
35  double maxf)
36 {
37  int x0 = r.x(), y0 = r.y(), x1 = r.x() + r.width(), y1 = r.y() + r.height();
38 
39  paint.drawLine(x0, y0, x0, y1);
40 
41  int py = y1, ppy = y1;
42  paint.setBrush(paint.pen().color());
43 
44  for (int i = 0; i < 128; ++i) {
45 
46  double f = Pitch::getFrequencyForPitch(i);
47  int y = int(lrint(v->getYForFrequency(f, minf, maxf, true)));
48 
49  if (y < y0 - 2) break;
50  if (y > y1 + 2) {
51  continue;
52  }
53 
54  int n = (i % 12);
55 
56  if (n == 1) {
57  // C# -- fill the C from here
58  QColor col = Qt::gray;
59  if (i == 61) { // filling middle C
60  col = Qt::blue;
61  col = col.lighter(150);
62  }
63  if (ppy - y > 2) {
64  paint.fillRect(x0 + 1,
65  y,
66  x1 - x0,
67  (py + ppy) / 2 - y,
68  col);
69  }
70  }
71 
72  if (n == 1 || n == 3 || n == 6 || n == 8 || n == 10) {
73  // black notes
74  paint.drawLine(x0 + 1, y, x1, y);
75  int rh = ((py - y) / 4) * 2;
76  if (rh < 2) rh = 2;
77  paint.drawRect(x0 + 1, y - (py-y)/4, (x1 - x0) / 2, rh);
78  } else if (n == 0 || n == 5) {
79  // C, F
80  if (py < y1) {
81  paint.drawLine(x0 + 1, (y + py) / 2, x1, (y + py) / 2);
82  }
83  }
84 
85  ppy = py;
86  py = y;
87  }
88 }
89 
90 void
92  const HorizontalScaleProvider *p,
93  QPainter &paint,
94  QRect r)
95 {
96  int x0 = r.x(), y0 = r.y(), x1 = r.x() + r.width(), y1 = r.y() + r.height();
97 
98  paint.drawLine(x0, y0, x1, y0);
99 
100  int px = x0, ppx = x0;
101  paint.setBrush(paint.pen().color());
102 
103  for (int i = 0; i < 128; ++i) {
104 
105  double f = Pitch::getFrequencyForPitch(i);
106  int x = int(lrint(p->getXForFrequency(v, f)));
107 
108  if (i == 0) {
109  px = ppx = x;
110  }
111  if (i == 1) {
112  ppx = px - (x - px);
113  }
114 
115  if (x < x0) {
116  ppx = px;
117  px = x;
118  continue;
119  }
120 
121  if (x > x1) {
122  break;
123  }
124 
125  int n = (i % 12);
126 
127  if (n == 1) {
128  // C# -- fill the C from here
129  QColor col = Qt::gray;
130  if (i == 61) { // filling middle C
131  col = Qt::blue;
132  col = col.lighter(150);
133  }
134  if (x - ppx > 2) {
135  paint.fillRect((px + ppx) / 2 + 1,
136  y0 + 1,
137  x - (px + ppx) / 2 - 1,
138  y1 - y0,
139  col);
140  }
141  }
142 
143  if (n == 1 || n == 3 || n == 6 || n == 8 || n == 10) {
144  // black notes
145  paint.drawLine(x, y0, x, y1);
146  int rw = int(lrint(double(x - px) / 4) * 2);
147  if (rw < 2) rw = 2;
148  paint.drawRect(x - rw/2, (y0 + y1) / 2, rw, (y1 - y0) / 2);
149  } else if (n == 0 || n == 5) {
150  // C, F
151  if (px < x1) {
152  paint.drawLine((x + px) / 2, y0, (x + px) / 2, y1);
153  }
154  }
155 
156  ppx = px;
157  px = x;
158  }
159 }
160 
161 
Interface for classes that provide geometry information (such as size, start frame, and a large number of other properties) about the disposition of a layer.
virtual double getYForFrequency(double frequency, double minFreq, double maxFreq, bool logarithmic) const =0
Return the (maybe fractional) pixel y-coordinate corresponding to a given frequency, if the frequency range is as specified.
void paintPianoVertical(LayerGeometryProvider *v, QPainter &paint, QRect rect, double minf, double maxf)
Definition: PianoScale.cpp:31
void paintPianoHorizontal(LayerGeometryProvider *v, const HorizontalScaleProvider *p, QPainter &paint, QRect rect)
Definition: PianoScale.cpp:91
virtual double getXForFrequency(const LayerGeometryProvider *, double freq) const =0
Interface to be implemented by objects, such as layers or objects they delegate to, in which the X axis corresponds to frequency.