annotate layer/PianoScale.cpp @ 1245:f0e291fa7b9c

Use Range01 normalisation in Colour 3D Plot. This gives us the same column normalisation behaviour as in 2.5 (better than the Max1 option).
author Chris Cannam
date Tue, 28 Feb 2017 14:06:24 +0000
parents 4d0ca1ab4cd0
children a34a2a25907c
rev   line source
Chris@690 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@690 2
Chris@690 3 /*
Chris@690 4 Sonic Visualiser
Chris@690 5 An audio file viewer and annotation editor.
Chris@690 6 Centre for Digital Music, Queen Mary, University of London.
Chris@690 7 This file copyright 2006-2013 Chris Cannam and QMUL.
Chris@690 8
Chris@690 9 This program is free software; you can redistribute it and/or
Chris@690 10 modify it under the terms of the GNU General Public License as
Chris@690 11 published by the Free Software Foundation; either version 2 of the
Chris@690 12 License, or (at your option) any later version. See the file
Chris@690 13 COPYING included with this distribution for more information.
Chris@690 14 */
Chris@690 15
Chris@690 16 #include "PianoScale.h"
Chris@690 17
Chris@690 18 #include <QPainter>
Chris@690 19
Chris@690 20 #include <cmath>
Chris@690 21
Chris@690 22 #include "base/Pitch.h"
Chris@690 23
Chris@1077 24 #include "LayerGeometryProvider.h"
Chris@690 25
Chris@1238 26 #include <iostream>
Chris@1238 27 using namespace std;
Chris@1238 28
Chris@690 29 void
Chris@918 30 PianoScale::paintPianoVertical(LayerGeometryProvider *v,
Chris@690 31 QPainter &paint,
Chris@690 32 QRect r,
Chris@904 33 double minf,
Chris@904 34 double maxf)
Chris@690 35 {
Chris@690 36 int x0 = r.x(), y0 = r.y(), x1 = r.x() + r.width(), y1 = r.y() + r.height();
Chris@690 37
Chris@690 38 paint.drawLine(x0, y0, x0, y1);
Chris@690 39
Chris@690 40 int py = y1, ppy = y1;
Chris@690 41 paint.setBrush(paint.pen().color());
Chris@690 42
Chris@690 43 for (int i = 0; i < 128; ++i) {
Chris@690 44
Chris@904 45 double f = Pitch::getFrequencyForPitch(i);
Chris@905 46 int y = int(lrint(v->getYForFrequency(f, minf, maxf, true)));
Chris@690 47
Chris@690 48 if (y < y0 - 2) break;
Chris@690 49 if (y > y1 + 2) {
Chris@690 50 continue;
Chris@690 51 }
Chris@690 52
Chris@690 53 int n = (i % 12);
Chris@690 54
Chris@690 55 if (n == 1) {
Chris@690 56 // C# -- fill the C from here
Chris@690 57 QColor col = Qt::gray;
Chris@690 58 if (i == 61) { // filling middle C
Chris@690 59 col = Qt::blue;
Chris@690 60 col = col.light(150);
Chris@690 61 }
Chris@690 62 if (ppy - y > 2) {
Chris@690 63 paint.fillRect(x0 + 1,
Chris@690 64 y,
Chris@690 65 x1 - x0,
Chris@690 66 (py + ppy) / 2 - y,
Chris@690 67 col);
Chris@690 68 }
Chris@690 69 }
Chris@690 70
Chris@690 71 if (n == 1 || n == 3 || n == 6 || n == 8 || n == 10) {
Chris@690 72 // black notes
Chris@690 73 paint.drawLine(x0 + 1, y, x1, y);
Chris@690 74 int rh = ((py - y) / 4) * 2;
Chris@690 75 if (rh < 2) rh = 2;
Chris@690 76 paint.drawRect(x0 + 1, y - (py-y)/4, (x1 - x0) / 2, rh);
Chris@690 77 } else if (n == 0 || n == 5) {
Chris@690 78 // C, F
Chris@690 79 if (py < y1) {
Chris@690 80 paint.drawLine(x0 + 1, (y + py) / 2, x1, (y + py) / 2);
Chris@690 81 }
Chris@690 82 }
Chris@690 83
Chris@690 84 ppy = py;
Chris@690 85 py = y;
Chris@690 86 }
Chris@690 87 }
Chris@690 88
Chris@1238 89 void
Chris@1238 90 PianoScale::paintPianoHorizontal(LayerGeometryProvider *v,
Chris@1238 91 const HorizontalScaleProvider *p,
Chris@1238 92 QPainter &paint,
Chris@1238 93 QRect r)
Chris@1238 94 {
Chris@1238 95 int x0 = r.x(), y0 = r.y(), x1 = r.x() + r.width(), y1 = r.y() + r.height();
Chris@1238 96
Chris@1238 97 paint.drawLine(x0, y0, x1, y0);
Chris@1238 98
Chris@1238 99 int px = x0, ppx = x0;
Chris@1238 100 paint.setBrush(paint.pen().color());
Chris@1238 101
Chris@1238 102 for (int i = 0; i < 128; ++i) {
Chris@1238 103
Chris@1238 104 double f = Pitch::getFrequencyForPitch(i);
Chris@1238 105 int x = int(lrint(p->getXForFrequency(v, f)));
Chris@1238 106
Chris@1238 107 if (i == 0) {
Chris@1238 108 px = ppx = x;
Chris@1238 109 }
Chris@1238 110 if (i == 1) {
Chris@1238 111 ppx = px - (x - px);
Chris@1238 112 }
Chris@1238 113
Chris@1238 114 if (x < x0) {
Chris@1238 115 ppx = px;
Chris@1238 116 px = x;
Chris@1238 117 continue;
Chris@1238 118 }
Chris@1238 119
Chris@1238 120 if (x > x1) {
Chris@1238 121 break;
Chris@1238 122 }
Chris@1238 123
Chris@1238 124 int n = (i % 12);
Chris@1238 125
Chris@1238 126 if (n == 1) {
Chris@1238 127 // C# -- fill the C from here
Chris@1238 128 QColor col = Qt::gray;
Chris@1238 129 if (i == 61) { // filling middle C
Chris@1238 130 col = Qt::blue;
Chris@1238 131 col = col.light(150);
Chris@1238 132 }
Chris@1238 133 if (x - ppx > 2) {
Chris@1238 134 paint.fillRect((px + ppx) / 2 + 1,
Chris@1238 135 y0 + 1,
Chris@1238 136 x - (px + ppx) / 2 - 1,
Chris@1238 137 y1 - y0,
Chris@1238 138 col);
Chris@1238 139 }
Chris@1238 140 }
Chris@1238 141
Chris@1238 142 if (n == 1 || n == 3 || n == 6 || n == 8 || n == 10) {
Chris@1238 143 // black notes
Chris@1238 144 paint.drawLine(x, y0, x, y1);
Chris@1238 145 int rw = int(lrint(double(x - px) / 4) * 2);
Chris@1238 146 if (rw < 2) rw = 2;
Chris@1238 147 paint.drawRect(x - rw/2, (y0 + y1) / 2, rw, (y1 - y0) / 2);
Chris@1238 148 } else if (n == 0 || n == 5) {
Chris@1238 149 // C, F
Chris@1238 150 if (px < x1) {
Chris@1238 151 paint.drawLine((x + px) / 2, y0, (x + px) / 2, y1);
Chris@1238 152 }
Chris@1238 153 }
Chris@1238 154
Chris@1238 155 ppx = px;
Chris@1238 156 px = x;
Chris@1238 157 }
Chris@1238 158 }
Chris@1238 159
Chris@1238 160