annotate widgets/Fader.cpp @ 37:21d061e66177

* Make the frequency estimation mode in the spectrogram layer actually useful, and make sure it gets mostly the right results... Still some tidying to do in here.
author Chris Cannam
date Wed, 22 Feb 2006 17:45:18 +0000
parents 37b110168acf
children 01ab51f72e84
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@0 4 A waveform viewer and audio annotation editor.
Chris@5 5 Chris Cannam, Queen Mary University of London, 2005-2006
Chris@0 6
Chris@0 7 This is experimental software. Not for distribution.
Chris@0 8 */
Chris@0 9
Chris@0 10 /**
Chris@0 11 * Horizontal audio fader and meter widget.
Chris@0 12 *
Chris@0 13 * Based on the vertical fader and meter widget from the Hydrogen drum
Chris@0 14 * machine. (Any poor taste that has crept in during the
Chris@0 15 * modifications for this application is entirely my own, however.)
Chris@0 16 * The following copyright notice applies to code from this file, and
Chris@0 17 * also to the files in icons/fader_*.png (also modified by me). --cc
Chris@0 18 */
Chris@0 19
Chris@0 20 /**
Chris@0 21 * Hydrogen
Chris@0 22 * Copyright(c) 2002-2005 by Alex >Comix< Cominu [comix@users.sourceforge.net]
Chris@0 23 *
Chris@0 24 * http://www.hydrogen-music.org
Chris@0 25 *
Chris@0 26 * This program is free software; you can redistribute it and/or modify
Chris@0 27 * it under the terms of the GNU General Public License as published by
Chris@0 28 * the Free Software Foundation; either version 2 of the License, or
Chris@0 29 * (at your option) any later version.
Chris@0 30 *
Chris@0 31 * This program is distributed in the hope that it will be useful,
Chris@0 32 * but WITHOUT ANY WARRANTY, without even the implied warranty of
Chris@0 33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 34 * GNU General Public License for more details.
Chris@0 35 *
Chris@0 36 * You should have received a copy of the GNU General Public License
Chris@0 37 * along with this program; if not, write to the Free Software
Chris@0 38 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Chris@0 39 */
Chris@0 40
Chris@0 41
Chris@0 42 #include "Fader.h"
Chris@0 43
Chris@0 44 #include "base/AudioLevel.h"
Chris@0 45
Chris@0 46 #include <QMouseEvent>
Chris@0 47 #include <QPixmap>
Chris@0 48 #include <QWheelEvent>
Chris@0 49 #include <QPaintEvent>
Chris@0 50 #include <QPainter>
Chris@0 51
Chris@0 52 Fader::Fader(QWidget *parent, bool withoutKnob) :
Chris@0 53 QWidget(parent),
Chris@0 54 m_withoutKnob(withoutKnob),
Chris@0 55 m_value(1.0),
Chris@0 56 m_peakLeft(0.0),
Chris@0 57 m_peakRight(0.0)
Chris@0 58 {
Chris@0 59 setMinimumSize(116, 23);
Chris@0 60 setMaximumSize(116, 23);
Chris@0 61 resize(116, 23);
Chris@0 62
Chris@0 63 QString background_path = ":/icons/fader_background.png";
Chris@0 64 bool ok = m_back.load(background_path);
Chris@0 65 if (ok == false) {
Chris@0 66 std::cerr << "Fader: Error loading pixmap" << std::endl;
Chris@0 67 }
Chris@0 68
Chris@0 69 QString leds_path = ":/icons/fader_leds.png";
Chris@0 70 ok = m_leds.load(leds_path);
Chris@0 71 if (ok == false) {
Chris@0 72 std::cerr << "Error loading pixmap" << std::endl;
Chris@0 73 }
Chris@0 74
Chris@0 75 QString knob_path = ":/icons/fader_knob.png";
Chris@0 76 ok = m_knob.load(knob_path);
Chris@0 77 if (ok == false) {
Chris@0 78 std::cerr << "Error loading pixmap" << std::endl;
Chris@0 79 }
Chris@0 80
Chris@0 81 QString clip_path = ":/icons/fader_knob_red.png";
Chris@0 82 ok = m_clip.load(clip_path);
Chris@0 83 if (ok == false) {
Chris@0 84 std::cerr << "Error loading pixmap" << std::endl;
Chris@0 85 }
Chris@0 86 }
Chris@0 87
Chris@0 88 Fader::~Fader()
Chris@0 89 {
Chris@0 90
Chris@0 91 }
Chris@0 92
Chris@0 93 void
Chris@0 94 Fader::mouseMoveEvent(QMouseEvent *ev)
Chris@0 95 {
Chris@0 96 int x = ev->x() - 6;
Chris@0 97 const int max_x = 116 - 12;
Chris@0 98
Chris@0 99 int value = x;
Chris@0 100
Chris@0 101 if (value > max_x) {
Chris@0 102 value = max_x;
Chris@0 103 } else if (value < 0) {
Chris@0 104 value = 0;
Chris@0 105 }
Chris@0 106
Chris@0 107 // float fval = float(value) / float(max_x);
Chris@0 108 float fval = AudioLevel::fader_to_multiplier
Chris@0 109 (value, max_x, AudioLevel::LongFader);
Chris@0 110
Chris@0 111 setValue(fval);
Chris@0 112 emit valueChanged(fval);
Chris@0 113
Chris@0 114 update();
Chris@0 115 }
Chris@0 116
Chris@0 117
Chris@0 118 void
Chris@0 119 Fader::mouseDoubleClickEvent(QMouseEvent *)
Chris@0 120 {
Chris@0 121 setValue(1.0);
Chris@0 122 emit valueChanged(1.0);
Chris@0 123 update();
Chris@0 124 }
Chris@0 125
Chris@0 126 void
Chris@0 127 Fader::mousePressEvent(QMouseEvent *ev)
Chris@0 128 {
Chris@0 129 int x = ev->x() - 6;
Chris@0 130 const int max_x = 116 - 12;
Chris@0 131
Chris@0 132 int value = x;
Chris@0 133
Chris@0 134 if (value > max_x) {
Chris@0 135 value = max_x;
Chris@0 136 } else if (value < 0) {
Chris@0 137 value = 0;
Chris@0 138 }
Chris@0 139
Chris@0 140 float fval = AudioLevel::fader_to_multiplier
Chris@0 141 (value, max_x, AudioLevel::LongFader);
Chris@0 142
Chris@0 143 setValue(fval);
Chris@0 144 emit valueChanged(fval);
Chris@0 145
Chris@0 146 update();
Chris@0 147 }
Chris@0 148
Chris@0 149
Chris@0 150 void
Chris@0 151 Fader::wheelEvent(QWheelEvent *ev)
Chris@0 152 {
Chris@0 153 ev->accept();
Chris@0 154
Chris@0 155 //!!! needs improvement
Chris@0 156
Chris@0 157 if (ev->delta() > 0) {
Chris@0 158 setValue(m_value * 1.1);
Chris@0 159 } else {
Chris@0 160 setValue(m_value / 1.1);
Chris@0 161 }
Chris@0 162
Chris@0 163 update();
Chris@0 164 emit valueChanged(getValue());
Chris@0 165 }
Chris@0 166
Chris@0 167
Chris@0 168 void
Chris@0 169 Fader::setValue(float v)
Chris@0 170 {
Chris@0 171 float max = AudioLevel::dB_to_multiplier(10.0);
Chris@0 172
Chris@0 173 if (v > max) {
Chris@0 174 v = max;
Chris@0 175 } else if (v < 0.0) {
Chris@0 176 v = 0.0;
Chris@0 177 }
Chris@0 178
Chris@0 179 if (m_value != v) {
Chris@0 180 m_value = v;
Chris@0 181 float db = AudioLevel::multiplier_to_dB(m_value);
Chris@0 182 if (db <= AudioLevel::DB_FLOOR) {
Chris@0 183 setToolTip(tr("Level: Off"));
Chris@0 184 } else {
Chris@0 185 setToolTip(tr("Level: %1%2.%3%4 dB")
Chris@0 186 .arg(db < 0.0 ? "-" : "")
Chris@0 187 .arg(abs(int(db)))
Chris@0 188 .arg(abs(int(db * 10.0) % 10))
Chris@0 189 .arg(abs(int(db * 100.0) % 10)));
Chris@0 190 }
Chris@0 191 update();
Chris@0 192 }
Chris@0 193 }
Chris@0 194
Chris@0 195
Chris@0 196 float
Chris@0 197 Fader::getValue()
Chris@0 198 {
Chris@0 199 return m_value;
Chris@0 200 }
Chris@0 201
Chris@0 202
Chris@0 203
Chris@0 204 void
Chris@0 205 Fader::setPeakLeft(float peak)
Chris@0 206 {
Chris@0 207 if (this->m_peakLeft != peak) {
Chris@0 208 this->m_peakLeft = peak;
Chris@0 209 update();
Chris@0 210 }
Chris@0 211 }
Chris@0 212
Chris@0 213
Chris@0 214 void
Chris@0 215 Fader::setPeakRight(float peak)
Chris@0 216 {
Chris@0 217 if (this->m_peakRight != peak) {
Chris@0 218 this->m_peakRight = peak;
Chris@0 219 update();
Chris@0 220 }
Chris@0 221 }
Chris@0 222
Chris@0 223
Chris@0 224 void
Chris@0 225 Fader::paintEvent(QPaintEvent *)
Chris@0 226 {
Chris@0 227 QPainter painter(this);
Chris@0 228
Chris@0 229 // background
Chris@0 230 painter.drawPixmap(rect(), m_back, QRect(0, 0, 116, 23));
Chris@0 231
Chris@0 232 int offset_L = AudioLevel::multiplier_to_fader(m_peakLeft, 116,
Chris@0 233 AudioLevel::IEC268LongMeter);
Chris@0 234
Chris@0 235 painter.drawPixmap(QRect(0, 0, offset_L, 11), m_leds,
Chris@0 236 QRect(0, 0, offset_L, 11));
Chris@0 237
Chris@0 238 int offset_R = AudioLevel::multiplier_to_fader(m_peakRight, 116,
Chris@0 239 AudioLevel::IEC268LongMeter);
Chris@0 240
Chris@0 241 painter.drawPixmap(QRect(0, 11, offset_R, 11), m_leds,
Chris@0 242 QRect(0, 11, offset_R, 11));
Chris@0 243
Chris@0 244 if (m_withoutKnob == false) {
Chris@0 245
Chris@0 246 static const uint knob_width = 29;
Chris@0 247 static const uint knob_height = 9;
Chris@0 248
Chris@0 249 int x = AudioLevel::multiplier_to_fader(m_value, 116 - knob_width,
Chris@0 250 AudioLevel::LongFader);
Chris@0 251
Chris@0 252 bool clipping = (m_peakLeft > 1.0 || m_peakRight > 1.0);
Chris@0 253
Chris@0 254 painter.drawPixmap(QRect(x, 7, knob_width, knob_height),
Chris@0 255 clipping ? m_clip : m_knob,
Chris@0 256 QRect(0, 0, knob_width, knob_height));
Chris@0 257 }
Chris@0 258 }
Chris@0 259
Chris@0 260