annotate base/Preferences.cpp @ 266:2268963dabd1

* FFT: fix invalid write of normalisation factor in compact mode of disc cache * FFT: fix range problem for normalisation factor in compact mode (it was stored as an unsigned scaled from an assumed float range of 0->1, which is not very plausible and not accurate enough even if true -- use a float instead) * Spectrogram: fix vertical zoom behaviour for log frequency spectrograms: make the thing in the middle of the display remain in the middle after zoom * Overview widget: don't update the detailed waveform if still decoding the audio file (too expensive to do all those redraws)
author Chris Cannam
date Fri, 08 Jun 2007 15:19:50 +0000
parents d7eeffbb8aaf
children 3b8008d09541
rev   line source
Chris@136 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@136 2
Chris@136 3 /*
Chris@136 4 Sonic Visualiser
Chris@136 5 An audio file viewer and annotation editor.
Chris@136 6 Centre for Digital Music, Queen Mary, University of London.
Chris@202 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@136 8
Chris@136 9 This program is free software; you can redistribute it and/or
Chris@136 10 modify it under the terms of the GNU General Public License as
Chris@136 11 published by the Free Software Foundation; either version 2 of the
Chris@136 12 License, or (at your option) any later version. See the file
Chris@136 13 COPYING included with this distribution for more information.
Chris@136 14 */
Chris@136 15
Chris@136 16 #include "Preferences.h"
Chris@136 17
Chris@145 18 #include "Exceptions.h"
Chris@145 19
Chris@145 20 #include "TempDirectory.h"
Chris@145 21
Chris@145 22 #include <QDir>
Chris@145 23 #include <QFileInfo>
Chris@156 24 #include <QMutex>
Chris@156 25 #include <QSettings>
Chris@145 26
Chris@136 27 Preferences *
Chris@156 28 Preferences::m_instance = 0;
Chris@156 29
Chris@156 30 Preferences *
Chris@156 31 Preferences::getInstance()
Chris@156 32 {
Chris@156 33 if (!m_instance) m_instance = new Preferences();
Chris@156 34 return m_instance;
Chris@156 35 }
Chris@136 36
Chris@136 37 Preferences::Preferences() :
Chris@246 38 m_spectrogramSmoothing(SpectrogramZeroPadded),
Chris@140 39 m_tuningFrequency(440),
Chris@140 40 m_propertyBoxLayout(VerticallyStacked),
Chris@164 41 m_windowType(HanningWindow),
Chris@164 42 m_resampleQuality(1)
Chris@136 43 {
Chris@156 44 QSettings settings;
Chris@156 45 settings.beginGroup("Preferences");
Chris@246 46 m_spectrogramSmoothing = SpectrogramSmoothing
Chris@246 47 (settings.value("spectrogram-smoothing", int(m_spectrogramSmoothing)).toInt());
Chris@156 48 m_tuningFrequency = settings.value("tuning-frequency", 440.f).toDouble();
Chris@145 49 m_propertyBoxLayout = PropertyBoxLayout
Chris@156 50 (settings.value("property-box-layout", int(VerticallyStacked)).toInt());
Chris@145 51 m_windowType = WindowType
Chris@156 52 (settings.value("window-type", int(HanningWindow)).toInt());
Chris@164 53 m_resampleQuality = settings.value("resample-quality", 1).toInt();
Chris@156 54 settings.endGroup();
Chris@145 55 }
Chris@145 56
Chris@145 57 Preferences::~Preferences()
Chris@145 58 {
Chris@136 59 }
Chris@136 60
Chris@136 61 Preferences::PropertyList
Chris@136 62 Preferences::getProperties() const
Chris@136 63 {
Chris@136 64 PropertyList props;
Chris@246 65 props.push_back("Spectrogram Smoothing");
Chris@136 66 props.push_back("Tuning Frequency");
Chris@138 67 props.push_back("Property Box Layout");
Chris@140 68 props.push_back("Window Type");
Chris@164 69 props.push_back("Resample Quality");
Chris@136 70 return props;
Chris@136 71 }
Chris@136 72
Chris@136 73 QString
Chris@136 74 Preferences::getPropertyLabel(const PropertyName &name) const
Chris@136 75 {
Chris@246 76 if (name == "Spectrogram Smoothing") {
Chris@246 77 return tr("Spectrogram y-axis smoothing:");
Chris@136 78 }
Chris@136 79 if (name == "Tuning Frequency") {
Chris@141 80 return tr("Frequency of concert A");
Chris@136 81 }
Chris@138 82 if (name == "Property Box Layout") {
Chris@141 83 return tr("Property box layout");
Chris@138 84 }
Chris@140 85 if (name == "Window Type") {
Chris@141 86 return tr("Spectral analysis window shape");
Chris@140 87 }
Chris@164 88 if (name == "Resample Quality") {
Chris@165 89 return tr("Playback resampler type");
Chris@164 90 }
Chris@136 91 return name;
Chris@136 92 }
Chris@136 93
Chris@136 94 Preferences::PropertyType
Chris@136 95 Preferences::getPropertyType(const PropertyName &name) const
Chris@136 96 {
Chris@246 97 if (name == "Spectrogram Smoothing") {
Chris@246 98 return ValueProperty;
Chris@136 99 }
Chris@136 100 if (name == "Tuning Frequency") {
Chris@136 101 return RangeProperty;
Chris@136 102 }
Chris@138 103 if (name == "Property Box Layout") {
Chris@138 104 return ValueProperty;
Chris@138 105 }
Chris@140 106 if (name == "Window Type") {
Chris@140 107 return ValueProperty;
Chris@140 108 }
Chris@164 109 if (name == "Resample Quality") {
Chris@164 110 return ValueProperty;
Chris@164 111 }
Chris@136 112 return InvalidProperty;
Chris@136 113 }
Chris@136 114
Chris@136 115 int
Chris@136 116 Preferences::getPropertyRangeAndValue(const PropertyName &name,
Chris@245 117 int *min, int *max, int *deflt) const
Chris@136 118 {
Chris@246 119 if (name == "Spectrogram Smoothing") {
Chris@136 120 if (min) *min = 0;
Chris@246 121 if (max) *max = 2;
Chris@246 122 if (deflt) *deflt = int(SpectrogramZeroPadded);
Chris@246 123 return int(m_spectrogramSmoothing);
Chris@136 124 }
Chris@136 125
Chris@136 126 //!!! freq mapping
Chris@136 127
Chris@138 128 if (name == "Property Box Layout") {
Chris@138 129 if (min) *min = 0;
Chris@138 130 if (max) *max = 1;
Chris@245 131 if (deflt) *deflt = 0;
Chris@138 132 return m_propertyBoxLayout == Layered ? 1 : 0;
Chris@138 133 }
Chris@138 134
Chris@140 135 if (name == "Window Type") {
Chris@140 136 if (min) *min = int(RectangularWindow);
Chris@142 137 if (max) *max = int(BlackmanHarrisWindow);
Chris@245 138 if (deflt) *deflt = int(HanningWindow);
Chris@140 139 return int(m_windowType);
Chris@140 140 }
Chris@140 141
Chris@164 142 if (name == "Resample Quality") {
Chris@164 143 if (min) *min = 0;
Chris@164 144 if (max) *max = 2;
Chris@245 145 if (deflt) *deflt = 1;
Chris@164 146 return m_resampleQuality;
Chris@164 147 }
Chris@164 148
Chris@136 149 return 0;
Chris@136 150 }
Chris@136 151
Chris@136 152 QString
Chris@136 153 Preferences::getPropertyValueLabel(const PropertyName &name,
Chris@136 154 int value) const
Chris@136 155 {
Chris@138 156 if (name == "Property Box Layout") {
Chris@141 157 if (value == 0) return tr("Show boxes for all panes");
Chris@141 158 else return tr("Show box for current pane only");
Chris@138 159 }
Chris@140 160 if (name == "Window Type") {
Chris@140 161 switch (WindowType(value)) {
Chris@140 162 case RectangularWindow: return tr("Rectangular");
Chris@141 163 case BartlettWindow: return tr("Triangular");
Chris@140 164 case HammingWindow: return tr("Hamming");
Chris@140 165 case HanningWindow: return tr("Hanning");
Chris@140 166 case BlackmanWindow: return tr("Blackman");
Chris@140 167 case GaussianWindow: return tr("Gaussian");
Chris@140 168 case ParzenWindow: return tr("Parzen");
Chris@142 169 case NuttallWindow: return tr("Nuttall");
Chris@142 170 case BlackmanHarrisWindow: return tr("Blackman-Harris");
Chris@140 171 }
Chris@140 172 }
Chris@164 173 if (name == "Resample Quality") {
Chris@164 174 switch (value) {
Chris@164 175 case 0: return tr("Fastest");
Chris@165 176 case 1: return tr("Standard");
Chris@164 177 case 2: return tr("Highest quality");
Chris@164 178 }
Chris@164 179 }
Chris@246 180 if (name == "Spectrogram Smoothing") {
Chris@246 181 switch (value) {
Chris@246 182 case NoSpectrogramSmoothing: return tr("None - blocky but accurate");
Chris@246 183 case SpectrogramInterpolated: return tr("Interpolate - fast but fuzzy");
Chris@246 184 case SpectrogramZeroPadded: return tr("Zero pad FFT - slow but clear");
Chris@246 185 }
Chris@246 186 }
Chris@246 187
Chris@136 188 return "";
Chris@136 189 }
Chris@136 190
Chris@136 191 QString
Chris@136 192 Preferences::getPropertyContainerName() const
Chris@136 193 {
Chris@136 194 return tr("Preferences");
Chris@136 195 }
Chris@136 196
Chris@136 197 QString
Chris@136 198 Preferences::getPropertyContainerIconName() const
Chris@136 199 {
Chris@136 200 return "preferences";
Chris@136 201 }
Chris@136 202
Chris@136 203 void
Chris@136 204 Preferences::setProperty(const PropertyName &name, int value)
Chris@136 205 {
Chris@246 206 if (name == "Spectrogram Smoothing") {
Chris@246 207 setSpectrogramSmoothing(SpectrogramSmoothing(value));
Chris@136 208 } else if (name == "Tuning Frequency") {
Chris@136 209 //!!!
Chris@138 210 } else if (name == "Property Box Layout") {
Chris@138 211 setPropertyBoxLayout(value == 0 ? VerticallyStacked : Layered);
Chris@140 212 } else if (name == "Window Type") {
Chris@140 213 setWindowType(WindowType(value));
Chris@164 214 } else if (name == "Resample Quality") {
Chris@164 215 setResampleQuality(value);
Chris@136 216 }
Chris@136 217 }
Chris@136 218
Chris@136 219 void
Chris@246 220 Preferences::setSpectrogramSmoothing(SpectrogramSmoothing smoothing)
Chris@136 221 {
Chris@246 222 if (m_spectrogramSmoothing != smoothing) {
Chris@246 223
Chris@246 224 // "smoothing" is one of those words that looks increasingly
Chris@246 225 // ridiculous the more you see it. Smoothing smoothing smoothing.
Chris@246 226 m_spectrogramSmoothing = smoothing;
Chris@246 227
Chris@156 228 QSettings settings;
Chris@156 229 settings.beginGroup("Preferences");
Chris@246 230 settings.setValue("spectrogram-smoothing", int(smoothing));
Chris@156 231 settings.endGroup();
Chris@246 232 emit propertyChanged("Spectrogram Smoothing");
Chris@138 233 }
Chris@136 234 }
Chris@136 235
Chris@136 236 void
Chris@136 237 Preferences::setTuningFrequency(float freq)
Chris@136 238 {
Chris@138 239 if (m_tuningFrequency != freq) {
Chris@138 240 m_tuningFrequency = freq;
Chris@156 241 QSettings settings;
Chris@156 242 settings.beginGroup("Preferences");
Chris@156 243 settings.setValue("tuning-frequency", freq);
Chris@156 244 settings.endGroup();
Chris@141 245 emit propertyChanged("Tuning Frequency");
Chris@138 246 }
Chris@136 247 }
Chris@136 248
Chris@138 249 void
Chris@138 250 Preferences::setPropertyBoxLayout(PropertyBoxLayout layout)
Chris@138 251 {
Chris@138 252 if (m_propertyBoxLayout != layout) {
Chris@138 253 m_propertyBoxLayout = layout;
Chris@156 254 QSettings settings;
Chris@156 255 settings.beginGroup("Preferences");
Chris@156 256 settings.setValue("property-box-layout", int(layout));
Chris@156 257 settings.endGroup();
Chris@141 258 emit propertyChanged("Property Box Layout");
Chris@138 259 }
Chris@138 260 }
Chris@138 261
Chris@140 262 void
Chris@140 263 Preferences::setWindowType(WindowType type)
Chris@140 264 {
Chris@140 265 if (m_windowType != type) {
Chris@140 266 m_windowType = type;
Chris@156 267 QSettings settings;
Chris@156 268 settings.beginGroup("Preferences");
Chris@156 269 settings.setValue("window-type", int(type));
Chris@156 270 settings.endGroup();
Chris@141 271 emit propertyChanged("Window Type");
Chris@140 272 }
Chris@140 273 }
Chris@140 274
Chris@164 275 void
Chris@164 276 Preferences::setResampleQuality(int q)
Chris@164 277 {
Chris@164 278 if (m_resampleQuality != q) {
Chris@164 279 m_resampleQuality = q;
Chris@164 280 QSettings settings;
Chris@164 281 settings.beginGroup("Preferences");
Chris@164 282 settings.setValue("resample-quality", q);
Chris@164 283 settings.endGroup();
Chris@164 284 emit propertyChanged("Resample Quality");
Chris@164 285 }
Chris@164 286 }