Mercurial > hg > svgui
diff layer/ColourScale.cpp @ 1216:dc2af6616c83
Merge from branch 3.0-integration
author | Chris Cannam |
---|---|
date | Fri, 13 Jan 2017 10:29:50 +0000 |
parents | c53ed1a6fcbd |
children | 822edd9bb665 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layer/ColourScale.cpp Fri Jan 13 10:29:50 2017 +0000 @@ -0,0 +1,160 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006-2016 Chris Cannam and QMUL. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "ColourScale.h" + +#include "base/AudioLevel.h" +#include "base/LogRange.h" + +#include <cmath> +#include <iostream> + +using namespace std; + +int ColourScale::m_maxPixel = 255; + +ColourScale::ColourScale(Parameters parameters) : + m_params(parameters), + m_mapper(m_params.colourMap, 1.f, double(m_maxPixel)) +{ + if (m_params.minValue >= m_params.maxValue) { + cerr << "ERROR: ColourScale::ColourScale: minValue = " + << m_params.minValue << ", maxValue = " << m_params.maxValue << endl; + throw std::logic_error("maxValue must be greater than minValue"); + } + + m_mappedMin = m_params.minValue; + m_mappedMax = m_params.maxValue; + + if (m_mappedMin < m_params.threshold) { + m_mappedMin = m_params.threshold; + } + + if (m_params.scaleType == ColourScaleType::Log) { + + LogRange::mapRange(m_mappedMin, m_mappedMax); + + } else if (m_params.scaleType == ColourScaleType::PlusMinusOne) { + + m_mappedMin = -1.0; + m_mappedMax = 1.0; + + } else if (m_params.scaleType == ColourScaleType::Absolute) { + + m_mappedMin = fabs(m_mappedMin); + m_mappedMax = fabs(m_mappedMax); + if (m_mappedMin >= m_mappedMax) { + std::swap(m_mappedMin, m_mappedMax); + } + } + + if (m_mappedMin >= m_mappedMax) { + cerr << "ERROR: ColourScale::ColourScale: minValue = " << m_params.minValue + << ", maxValue = " << m_params.maxValue + << ", threshold = " << m_params.threshold + << ", scale = " << int(m_params.scaleType) + << " resulting in mapped minValue = " << m_mappedMin + << ", mapped maxValue = " << m_mappedMax << endl; + throw std::logic_error("maxValue must be greater than minValue [after mapping]"); + } +} + +ColourScale::~ColourScale() +{ +} + +ColourScaleType +ColourScale::getScale() const +{ + return m_params.scaleType; +} + +int +ColourScale::getPixel(double value) const +{ + double maxPixF = m_maxPixel; + + if (m_params.scaleType == ColourScaleType::Phase) { + double half = (maxPixF - 1.f) / 2.f; + int pixel = 1 + int((value * half) / M_PI + half); +// cerr << "phase = " << value << " pixel = " << pixel << endl; + return pixel; + } + + value *= m_params.gain; + + if (value < m_params.threshold) return 0; + + double mapped = value; + + if (m_params.scaleType == ColourScaleType::Log) { + mapped = LogRange::map(value); + } else if (m_params.scaleType == ColourScaleType::PlusMinusOne) { + if (mapped < -1.f) mapped = -1.f; + if (mapped > 1.f) mapped = 1.f; + } else if (m_params.scaleType == ColourScaleType::Absolute) { + if (mapped < 0.f) mapped = -mapped; + } + + mapped *= m_params.multiple; + + if (mapped < m_mappedMin) { + mapped = m_mappedMin; + } + if (mapped > m_mappedMax) { + mapped = m_mappedMax; + } + + double proportion = (mapped - m_mappedMin) / (m_mappedMax - m_mappedMin); + + int pixel = 0; + + if (m_params.scaleType == ColourScaleType::Meter) { + pixel = AudioLevel::multiplier_to_preview(proportion, m_maxPixel-1) + 1; + } else { + pixel = int(proportion * maxPixF) + 1; + } + + if (pixel < 0) { + pixel = 0; + } + if (pixel > m_maxPixel) { + pixel = m_maxPixel; + } + return pixel; +} + +QColor +ColourScale::getColourForPixel(int pixel, int rotation) const +{ + if (pixel < 0) { + pixel = 0; + } + if (pixel > m_maxPixel) { + pixel = m_maxPixel; + } + if (pixel == 0) { + if (m_mapper.hasLightBackground()) { + return Qt::white; + } else { + return Qt::black; + } + } else { + int target = int(pixel) + rotation; + while (target < 1) target += m_maxPixel; + while (target > m_maxPixel) target -= m_maxPixel; + return m_mapper.map(double(target)); + } +}