annotate view/AlignmentView.cpp @ 1127:9fb8dfd7ce4c spectrogram-minor-refactor

Fix threshold in spectrogram -- it wasn't working in the last release. There is a new protocol for this. Formerly the threshold parameter had a range from -50dB to 0 with the default at -50, and -50 treated internally as "no threshold". However, there was a hardcoded, hidden internal threshold for spectrogram colour mapping at -80dB with anything below this being rounded to zero. Now the threshold parameter has range -81 to -1 with the default at -80, -81 is treated internally as "no threshold", and there is no hidden internal threshold. So the default behaviour is the same as before, an effective -80dB threshold, but it is now possible to change this in both directions. Sessions reloaded from prior versions may look slightly different because, if the session says there should be no threshold, there will now actually be no threshold instead of having the hidden internal one. Still need to do something in the UI to make it apparent that the -81dB setting removes the threshold entirely. This is at least no worse than the previous, also obscured, magic -50dB setting.
author Chris Cannam
date Mon, 01 Aug 2016 16:21:01 +0100
parents f2c63ec85901
children 57d192e26331 a34a2a25907c
rev   line source
Chris@867 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@867 2
Chris@867 3 /*
Chris@867 4 Sonic Visualiser
Chris@867 5 An audio file viewer and annotation editor.
Chris@867 6 Centre for Digital Music, Queen Mary, University of London.
Chris@867 7 This file copyright 2006-2014 Chris Cannam and QMUL.
Chris@867 8
Chris@867 9 This program is free software; you can redistribute it and/or
Chris@867 10 modify it under the terms of the GNU General Public License as
Chris@867 11 published by the Free Software Foundation; either version 2 of the
Chris@867 12 License, or (at your option) any later version. See the file
Chris@867 13 COPYING included with this distribution for more information.
Chris@867 14 */
Chris@867 15
Chris@867 16 #include "AlignmentView.h"
Chris@867 17
Chris@867 18 #include <QPainter>
Chris@867 19
Chris@868 20 #include "data/model/SparseOneDimensionalModel.h"
Chris@868 21
Chris@868 22 #include "layer/TimeInstantLayer.h"
Chris@868 23
Chris@867 24 using std::vector;
Chris@867 25
Chris@867 26 AlignmentView::AlignmentView(QWidget *w) :
Chris@867 27 View(w, false),
Chris@867 28 m_above(0),
Chris@867 29 m_below(0)
Chris@867 30 {
Chris@867 31 setObjectName(tr("AlignmentView"));
Chris@867 32 }
Chris@867 33
Chris@867 34 void
Chris@976 35 AlignmentView::globalCentreFrameChanged(sv_frame_t f)
Chris@867 36 {
Chris@867 37 View::globalCentreFrameChanged(f);
Chris@867 38 update();
Chris@867 39 }
Chris@867 40
Chris@867 41 void
Chris@976 42 AlignmentView::viewCentreFrameChanged(View *v, sv_frame_t f)
Chris@867 43 {
Chris@867 44 View::viewCentreFrameChanged(v, f);
Chris@867 45 if (v == m_above) {
Chris@867 46 m_centreFrame = f;
Chris@867 47 update();
Chris@867 48 } else if (v == m_below) {
Chris@867 49 update();
Chris@867 50 }
Chris@867 51 }
Chris@867 52
Chris@867 53 void
Chris@976 54 AlignmentView::viewManagerPlaybackFrameChanged(sv_frame_t)
Chris@867 55 {
Chris@867 56 update();
Chris@867 57 }
Chris@867 58
Chris@867 59 void
Chris@867 60 AlignmentView::viewAboveZoomLevelChanged(int level, bool)
Chris@867 61 {
Chris@867 62 m_zoomLevel = level;
Chris@867 63 update();
Chris@867 64 }
Chris@867 65
Chris@867 66 void
Chris@867 67 AlignmentView::viewBelowZoomLevelChanged(int, bool)
Chris@867 68 {
Chris@867 69 update();
Chris@867 70 }
Chris@867 71
Chris@867 72 void
Chris@867 73 AlignmentView::setViewAbove(View *v)
Chris@867 74 {
Chris@867 75 if (m_above) {
Chris@867 76 disconnect(m_above, 0, this, 0);
Chris@867 77 }
Chris@867 78
Chris@867 79 m_above = v;
Chris@867 80
Chris@867 81 if (m_above) {
Chris@867 82 connect(m_above,
Chris@867 83 SIGNAL(zoomLevelChanged(int, bool)),
Chris@867 84 this,
Chris@867 85 SLOT(viewAboveZoomLevelChanged(int, bool)));
Chris@867 86 }
Chris@867 87 }
Chris@867 88
Chris@867 89 void
Chris@867 90 AlignmentView::setViewBelow(View *v)
Chris@867 91 {
Chris@867 92 if (m_below) {
Chris@867 93 disconnect(m_below, 0, this, 0);
Chris@867 94 }
Chris@867 95
Chris@867 96 m_below = v;
Chris@867 97
Chris@867 98 if (m_below) {
Chris@867 99 connect(m_below,
Chris@867 100 SIGNAL(zoomLevelChanged(int, bool)),
Chris@867 101 this,
Chris@867 102 SLOT(viewBelowZoomLevelChanged(int, bool)));
Chris@867 103 }
Chris@867 104 }
Chris@867 105
Chris@867 106 void
Chris@867 107 AlignmentView::paintEvent(QPaintEvent *)
Chris@867 108 {
Chris@867 109 if (m_above == 0 || m_below == 0 || !m_manager) return;
Chris@867 110
Chris@867 111 bool darkPalette = false;
Chris@867 112 if (m_manager) darkPalette = m_manager->getGlobalDarkBackground();
Chris@867 113
Chris@881 114 QColor fg, bg;
Chris@881 115 if (darkPalette) {
Chris@881 116 fg = Qt::gray;
Chris@881 117 bg = Qt::black;
Chris@881 118 } else {
Chris@881 119 fg = Qt::black;
Chris@881 120 bg = Qt::gray;
Chris@881 121 }
Chris@867 122
Chris@867 123 QPainter paint(this);
Chris@867 124 paint.setPen(QPen(fg, 2));
Chris@867 125 paint.setBrush(Qt::NoBrush);
Chris@867 126 paint.setRenderHint(QPainter::Antialiasing, true);
Chris@867 127
Chris@867 128 paint.fillRect(rect(), bg);
Chris@867 129
Chris@976 130 vector<sv_frame_t> keyFrames = getKeyFrames();
Chris@867 131
Chris@976 132 foreach (sv_frame_t f, keyFrames) {
Chris@882 133 int ax = m_above->getXForFrame(f);
Chris@976 134 sv_frame_t rf = m_above->alignToReference(f);
Chris@976 135 sv_frame_t bf = m_below->alignFromReference(rf);
Chris@867 136 int bx = m_below->getXForFrame(bf);
Chris@867 137 paint.drawLine(ax, 0, bx, height());
Chris@867 138 }
Chris@867 139
Chris@867 140 paint.end();
Chris@867 141 }
Chris@867 142
Chris@976 143 vector<sv_frame_t>
Chris@868 144 AlignmentView::getKeyFrames()
Chris@868 145 {
Chris@868 146 if (!m_above) {
Chris@868 147 return getDefaultKeyFrames();
Chris@868 148 }
Chris@868 149
Chris@868 150 SparseOneDimensionalModel *m = 0;
Chris@868 151
Chris@868 152 // get the topmost such
Chris@868 153 for (int i = 0; i < m_above->getLayerCount(); ++i) {
Chris@868 154 if (qobject_cast<TimeInstantLayer *>(m_above->getLayer(i))) {
Chris@868 155 SparseOneDimensionalModel *mm =
Chris@868 156 qobject_cast<SparseOneDimensionalModel *>
Chris@868 157 (m_above->getLayer(i)->getModel());
Chris@868 158 if (mm) m = mm;
Chris@868 159 }
Chris@868 160 }
Chris@868 161
Chris@868 162 if (!m) {
Chris@868 163 return getDefaultKeyFrames();
Chris@868 164 }
Chris@868 165
Chris@976 166 vector<sv_frame_t> keyFrames;
Chris@868 167
Chris@868 168 const SparseOneDimensionalModel::PointList pp = m->getPoints();
Chris@868 169 for (SparseOneDimensionalModel::PointList::const_iterator pi = pp.begin();
Chris@868 170 pi != pp.end(); ++pi) {
Chris@868 171 keyFrames.push_back(pi->frame);
Chris@868 172 }
Chris@868 173
Chris@868 174 return keyFrames;
Chris@868 175 }
Chris@868 176
Chris@976 177 vector<sv_frame_t>
Chris@868 178 AlignmentView::getDefaultKeyFrames()
Chris@868 179 {
Chris@976 180 vector<sv_frame_t> keyFrames;
Chris@868 181
Chris@868 182 if (!m_above || !m_manager) return keyFrames;
Chris@868 183
Chris@976 184 sv_samplerate_t rate = m_manager->getMainModelSampleRate();
Chris@868 185 if (rate == 0) return keyFrames;
Chris@868 186
Chris@976 187 for (sv_frame_t f = m_above->getModelsStartFrame();
Chris@868 188 f <= m_above->getModelsEndFrame();
Chris@976 189 f += sv_frame_t(rate * 5 + 0.5)) {
Chris@868 190 keyFrames.push_back(f);
Chris@868 191 }
Chris@868 192
Chris@868 193 return keyFrames;
Chris@868 194 }
Chris@868 195
Chris@868 196
Chris@868 197
Chris@868 198
Chris@868 199
Chris@868 200