annotate layer/ColourMapper.cpp @ 284:1284955856ab

* threshold, show-peaks properties in spectrum
author Chris Cannam
date Fri, 06 Jul 2007 15:17:35 +0000
parents b9380f679f70
children
rev   line source
Chris@196 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@196 2
Chris@196 3 /*
Chris@196 4 Sonic Visualiser
Chris@196 5 An audio file viewer and annotation editor.
Chris@196 6 Centre for Digital Music, Queen Mary, University of London.
Chris@196 7 This file copyright 2006-2007 Chris Cannam and QMUL.
Chris@196 8
Chris@196 9 This program is free software; you can redistribute it and/or
Chris@196 10 modify it under the terms of the GNU General Public License as
Chris@196 11 published by the Free Software Foundation; either version 2 of the
Chris@196 12 License, or (at your option) any later version. See the file
Chris@196 13 COPYING included with this distribution for more information.
Chris@196 14 */
Chris@196 15
Chris@196 16 #include "ColourMapper.h"
Chris@196 17
Chris@197 18 #include <iostream>
Chris@197 19
Chris@201 20 #include <cmath>
Chris@201 21
Chris@196 22 ColourMapper::ColourMapper(int map, float min, float max) :
Chris@196 23 QObject(),
Chris@196 24 m_map(map),
Chris@196 25 m_min(min),
Chris@196 26 m_max(max)
Chris@196 27 {
Chris@197 28 if (m_min == m_max) {
Chris@197 29 std::cerr << "WARNING: ColourMapper: min == max (== " << m_min
Chris@197 30 << "), adjusting" << std::endl;
Chris@197 31 m_max = m_min + 1;
Chris@197 32 }
Chris@196 33 }
Chris@196 34
Chris@196 35 ColourMapper::~ColourMapper()
Chris@196 36 {
Chris@196 37 }
Chris@196 38
Chris@196 39 int
Chris@196 40 ColourMapper::getColourMapCount()
Chris@196 41 {
Chris@274 42 return 11;
Chris@196 43 }
Chris@196 44
Chris@196 45 QString
Chris@196 46 ColourMapper::getColourMapName(int n)
Chris@196 47 {
Chris@197 48 if (n >= getColourMapCount()) return tr("<unknown>");
Chris@196 49 StandardMap map = (StandardMap)n;
Chris@196 50
Chris@196 51 switch (map) {
Chris@196 52 case DefaultColours: return tr("Default");
Chris@196 53 case WhiteOnBlack: return tr("White on Black");
Chris@196 54 case BlackOnWhite: return tr("Black on White");
Chris@196 55 case RedOnBlue: return tr("Red on Blue");
Chris@196 56 case YellowOnBlack: return tr("Yellow on Black");
Chris@196 57 case BlueOnBlack: return tr("Blue on Black");
Chris@196 58 case Sunset: return tr("Sunset");
Chris@196 59 case FruitSalad: return tr("Fruit Salad");
Chris@197 60 case Banded: return tr("Banded");
Chris@197 61 case Highlight: return tr("Highlight");
Chris@274 62 case Printer: return tr("Printer");
Chris@196 63 }
Chris@196 64
Chris@196 65 return tr("<unknown>");
Chris@196 66 }
Chris@196 67
Chris@196 68 QColor
Chris@196 69 ColourMapper::map(float value) const
Chris@196 70 {
Chris@196 71 float norm = (value - m_min) / (m_max - m_min);
Chris@196 72 if (norm < 0.f) norm = 0.f;
Chris@196 73 if (norm > 1.f) norm = 1.f;
Chris@196 74
Chris@196 75 float h = 0.f, s = 0.f, v = 0.f, r = 0.f, g = 0.f, b = 0.f;
Chris@196 76 bool hsv = true;
Chris@196 77
Chris@248 78 // float red = 0.f, green = 0.3333f;
Chris@248 79 float blue = 0.6666f, pieslice = 0.3333f;
Chris@196 80
Chris@197 81 if (m_map >= getColourMapCount()) return Qt::black;
Chris@196 82 StandardMap map = (StandardMap)m_map;
Chris@196 83
Chris@196 84 switch (map) {
Chris@196 85
Chris@196 86 case DefaultColours:
Chris@196 87 h = blue - norm * 2.f * pieslice;
Chris@196 88 s = 0.5f + norm/2.f;
Chris@196 89 v = norm;
Chris@196 90 break;
Chris@196 91
Chris@196 92 case WhiteOnBlack:
Chris@196 93 r = g = b = norm;
Chris@196 94 hsv = false;
Chris@196 95 break;
Chris@196 96
Chris@196 97 case BlackOnWhite:
Chris@196 98 r = g = b = 1.f - norm;
Chris@196 99 hsv = false;
Chris@196 100 break;
Chris@196 101
Chris@196 102 case RedOnBlue:
Chris@196 103 h = blue - pieslice/4.f + norm * (pieslice + pieslice/4.f);
Chris@196 104 s = 1.f;
Chris@196 105 v = norm;
Chris@196 106 break;
Chris@196 107
Chris@196 108 case YellowOnBlack:
Chris@196 109 h = 0.15f;
Chris@196 110 s = 1.f;
Chris@196 111 v = norm;
Chris@196 112 break;
Chris@196 113
Chris@196 114 case BlueOnBlack:
Chris@197 115 h = blue;
Chris@196 116 s = 1.f;
Chris@196 117 v = norm * 2.f;
Chris@197 118 if (v > 1.f) {
Chris@196 119 v = 1.f;
Chris@197 120 s = 1.f - (sqrtf(norm) - 0.707f) * 3.413f;
Chris@197 121 if (s < 0.f) s = 0.f;
Chris@197 122 if (s > 1.f) s = 1.f;
Chris@196 123 }
Chris@196 124 break;
Chris@196 125
Chris@196 126 case Sunset:
Chris@196 127 r = (norm - 0.24f) * 2.38f;
Chris@196 128 if (r > 1.f) r = 1.f;
Chris@196 129 if (r < 0.f) r = 0.f;
Chris@196 130 g = (norm - 0.64f) * 2.777f;
Chris@196 131 if (g > 1.f) g = 1.f;
Chris@196 132 if (g < 0.f) g = 0.f;
Chris@196 133 b = (3.6f * norm);
Chris@196 134 if (norm > 0.277f) b = 2.f - b;
Chris@196 135 if (b > 1.f) b = 1.f;
Chris@196 136 if (b < 0.f) b = 0.f;
Chris@196 137 hsv = false;
Chris@196 138 break;
Chris@196 139
Chris@196 140 case FruitSalad:
Chris@197 141 h = blue + (pieslice/6.f) - norm;
Chris@196 142 if (h < 0.f) h += 1.f;
Chris@196 143 s = 1.f;
Chris@196 144 v = 1.f;
Chris@196 145 break;
Chris@197 146
Chris@197 147 case Banded:
Chris@197 148 if (norm < 0.125) return Qt::darkGreen;
Chris@197 149 else if (norm < 0.25) return Qt::green;
Chris@197 150 else if (norm < 0.375) return Qt::darkBlue;
Chris@197 151 else if (norm < 0.5) return Qt::blue;
Chris@197 152 else if (norm < 0.625) return Qt::darkYellow;
Chris@197 153 else if (norm < 0.75) return Qt::yellow;
Chris@197 154 else if (norm < 0.875) return Qt::darkRed;
Chris@197 155 else return Qt::red;
Chris@197 156 break;
Chris@197 157
Chris@197 158 case Highlight:
Chris@197 159 if (norm > 0.99) return Qt::white;
Chris@197 160 else return Qt::darkBlue;
Chris@274 161
Chris@274 162 case Printer:
Chris@274 163 if (norm > 0.8) {
Chris@274 164 r = 1.f;
Chris@274 165 } else if (norm > 0.7) {
Chris@274 166 r = 0.9f;
Chris@274 167 } else if (norm > 0.6) {
Chris@274 168 r = 0.8f;
Chris@274 169 } else if (norm > 0.5) {
Chris@274 170 r = 0.7f;
Chris@274 171 } else if (norm > 0.4) {
Chris@274 172 r = 0.6f;
Chris@274 173 } else if (norm > 0.3) {
Chris@274 174 r = 0.5f;
Chris@274 175 } else if (norm > 0.2) {
Chris@274 176 r = 0.4f;
Chris@274 177 } else {
Chris@274 178 r = 0.f;
Chris@274 179 }
Chris@274 180 r = g = b = 1.f - r;
Chris@274 181 hsv = false;
Chris@274 182 break;
Chris@196 183 }
Chris@196 184
Chris@196 185 if (hsv) {
Chris@196 186 return QColor::fromHsvF(h, s, v);
Chris@196 187 } else {
Chris@196 188 return QColor::fromRgbF(r, g, b);
Chris@196 189 }
Chris@196 190 }
Chris@196 191
Chris@196 192 QColor
Chris@196 193 ColourMapper::getContrastingColour() const
Chris@196 194 {
Chris@197 195 if (m_map >= getColourMapCount()) return Qt::white;
Chris@196 196 StandardMap map = (StandardMap)m_map;
Chris@196 197
Chris@196 198 switch (map) {
Chris@196 199
Chris@196 200 case DefaultColours:
Chris@196 201 return QColor(255, 150, 50);
Chris@196 202
Chris@196 203 case WhiteOnBlack:
Chris@196 204 return Qt::red;
Chris@196 205
Chris@196 206 case BlackOnWhite:
Chris@196 207 return Qt::darkGreen;
Chris@196 208
Chris@196 209 case RedOnBlue:
Chris@196 210 return Qt::green;
Chris@196 211
Chris@196 212 case YellowOnBlack:
Chris@196 213 return QColor::fromHsv(240, 255, 255);
Chris@196 214
Chris@196 215 case BlueOnBlack:
Chris@196 216 return Qt::red;
Chris@196 217
Chris@196 218 case Sunset:
Chris@196 219 return Qt::white;
Chris@196 220
Chris@196 221 case FruitSalad:
Chris@196 222 return Qt::white;
Chris@197 223
Chris@197 224 case Banded:
Chris@197 225 return Qt::cyan;
Chris@197 226
Chris@197 227 case Highlight:
Chris@197 228 return Qt::red;
Chris@274 229
Chris@274 230 case Printer:
Chris@274 231 return Qt::red;
Chris@196 232 }
Chris@196 233
Chris@196 234 return Qt::white;
Chris@196 235 }
Chris@196 236
Chris@196 237