annotate base/PropertyContainer.cpp @ 1290:fa574c909c3d 3.0-integration

Add MAD_BUFFER_GUARD padding at end of mp3 buffer, in order to ensure last frame is decoded successfully (otherwise the decoded audio is truncated). Another thing learned from madplay.
author Chris Cannam
date Thu, 24 Nov 2016 17:06:31 +0000
parents a54016762f77
children 576be7933ec7
rev   line source
Chris@49 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@52 4 Sonic Visualiser
Chris@52 5 An audio file viewer and annotation editor.
Chris@52 6 Centre for Digital Music, Queen Mary, University of London.
Chris@202 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@0 8
Chris@52 9 This program is free software; you can redistribute it and/or
Chris@52 10 modify it under the terms of the GNU General Public License as
Chris@52 11 published by the Free Software Foundation; either version 2 of the
Chris@52 12 License, or (at your option) any later version. See the file
Chris@52 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@0 16 #include "PropertyContainer.h"
Chris@199 17 #include "RangeMapper.h"
Chris@199 18 #include "UnitDatabase.h"
Chris@46 19
Chris@46 20 #include <iostream>
Chris@0 21
Chris@0 22 PropertyContainer::PropertyList
Chris@0 23 PropertyContainer::getProperties() const
Chris@0 24 {
Chris@0 25 return PropertyList();
Chris@0 26 }
Chris@0 27
Chris@0 28 PropertyContainer::PropertyType
Chris@0 29 PropertyContainer::getPropertyType(const PropertyName &) const
Chris@0 30 {
Chris@0 31 return InvalidProperty;
Chris@0 32 }
Chris@0 33
Chris@0 34 QString
Chris@340 35 PropertyContainer::getPropertyIconName(const PropertyName &) const
Chris@340 36 {
Chris@340 37 return QString();
Chris@340 38 }
Chris@340 39
Chris@340 40 QString
Chris@0 41 PropertyContainer::getPropertyGroupName(const PropertyName &) const
Chris@0 42 {
Chris@0 43 return QString();
Chris@0 44 }
Chris@0 45
Chris@0 46 int
Chris@245 47 PropertyContainer::getPropertyRangeAndValue(const PropertyName &,
Chris@245 48 int *min, int *max, int *deflt) const
Chris@0 49 {
Chris@0 50 if (min) *min = 0;
Chris@0 51 if (max) *max = 0;
Chris@245 52 if (deflt) *deflt = 0;
Chris@0 53 return 0;
Chris@0 54 }
Chris@0 55
Chris@0 56 QString
Chris@928 57 PropertyContainer::getPropertyValueLabel(const PropertyName &, int) const
Chris@0 58 {
Chris@0 59 return QString();
Chris@0 60 }
Chris@0 61
Chris@984 62 QString
Chris@984 63 PropertyContainer::getPropertyValueIconName(const PropertyName &, int) const
Chris@984 64 {
Chris@984 65 return QString();
Chris@984 66 }
Chris@984 67
Chris@190 68 RangeMapper *
Chris@190 69 PropertyContainer::getNewPropertyRangeMapper(const PropertyName &) const
Chris@190 70 {
Chris@190 71 return 0;
Chris@190 72 }
Chris@190 73
Chris@0 74 void
Chris@46 75 PropertyContainer::setProperty(const PropertyName &name, int)
Chris@46 76 {
Chris@843 77 cerr << "WARNING: PropertyContainer[" << getPropertyContainerName() << "]::setProperty(" << name << "): no implementation in subclass!" << endl;
Chris@46 78 }
Chris@46 79
Chris@387 80 Command *
Chris@387 81 PropertyContainer::getSetPropertyCommand(const PropertyName &name, int value)
Chris@46 82 {
Chris@245 83 int currentValue = getPropertyRangeAndValue(name, 0, 0, 0);
Chris@387 84 if (value == currentValue) return 0;
Chris@387 85 return new SetPropertyCommand(this, name, value);
Chris@46 86 }
Chris@199 87
Chris@199 88 void
Chris@528 89 PropertyContainer::setPropertyFuzzy(QString nameString, QString valueString)
Chris@199 90 {
Chris@199 91 PropertyName name;
Chris@199 92 int value;
Chris@199 93 if (!convertPropertyStrings(nameString, valueString, name, value)) {
Chris@843 94 cerr << "WARNING: PropertyContainer::setProperty(\""
Chris@686 95 << nameString << "\", \""
Chris@844 96 << valueString
Chris@843 97 << "\"): Name and value conversion failed" << endl;
Chris@199 98 return;
Chris@199 99 }
Chris@199 100 setProperty(name, value);
Chris@199 101 }
Chris@199 102
Chris@387 103 Command *
Chris@387 104 PropertyContainer::getSetPropertyCommand(QString nameString, QString valueString)
Chris@199 105 {
Chris@199 106 PropertyName name;
Chris@199 107 int value;
Chris@199 108 if (!convertPropertyStrings(nameString, valueString, name, value)) {
Chris@843 109 cerr << "WARNING: PropertyContainer::getSetPropertyCommand(\""
Chris@686 110 << nameString << "\", \""
Chris@844 111 << valueString
Chris@843 112 << "\"): Name and value conversion failed" << endl;
Chris@387 113 return 0;
Chris@199 114 }
Chris@387 115 return getSetPropertyCommand(name, value);
Chris@199 116 }
Chris@199 117
Chris@199 118 bool
Chris@199 119 PropertyContainer::convertPropertyStrings(QString nameString, QString valueString,
Chris@199 120 PropertyName &name, int &value)
Chris@199 121 {
Chris@199 122 PropertyList pl = getProperties();
Chris@199 123
Chris@199 124 QString adjusted = nameString.trimmed();
Chris@199 125 adjusted.replace('_', ' ');
Chris@199 126 adjusted.replace('-', ' ');
Chris@199 127
Chris@199 128 name = "";
Chris@199 129
Chris@199 130 for (PropertyList::iterator pli = pl.begin(); pli != pl.end(); ++pli) {
Chris@199 131
Chris@199 132 QString label = getPropertyLabel(*pli);
Chris@199 133
Chris@199 134 if (label != "" && (nameString == label || adjusted == label)) {
Chris@199 135 name = *pli;
Chris@199 136 break;
Chris@199 137 } else if (nameString == *pli) {
Chris@199 138 name = *pli;
Chris@199 139 break;
Chris@199 140 }
Chris@199 141 }
Chris@199 142
Chris@199 143 if (name == "") {
Chris@843 144 cerr << "PropertyContainer::convertPropertyStrings: Unable to match name string \"" << nameString << "\"" << endl;
Chris@199 145 return false;
Chris@199 146 }
Chris@199 147
Chris@199 148 value = 0;
Chris@199 149 bool success = false;
Chris@199 150
Chris@199 151 bool isDouble = false;
Chris@199 152 double dval = valueString.toDouble(&isDouble);
Chris@199 153
Chris@199 154 switch (getPropertyType(name)) {
Chris@199 155
Chris@199 156 case ToggleProperty:
Chris@199 157 if (valueString == tr("yes") ||
Chris@199 158 valueString == tr("on") ||
Chris@199 159 valueString == tr("true")) {
Chris@199 160 value = 1; success = true;
Chris@199 161 } else if (valueString == tr("no") ||
Chris@199 162 valueString == tr("off") ||
Chris@199 163 valueString == tr("false")) {
Chris@199 164 value = 0; success = true;
Chris@199 165 }
Chris@199 166 break;
Chris@199 167
Chris@199 168 case RangeProperty:
Chris@199 169 if (isDouble) {
Chris@199 170 RangeMapper *mapper = getNewPropertyRangeMapper(name);
Chris@199 171 if (mapper) {
Chris@199 172 value = mapper->getPositionForValue(dval);
Chris@199 173 delete mapper;
Chris@199 174 success = true;
Chris@199 175 }
Chris@199 176 }
Chris@199 177 break;
Chris@199 178
Chris@199 179 case ValueProperty:
Chris@387 180 case ColourProperty:
Chris@199 181 {
Chris@199 182 int min, max;
Chris@245 183 getPropertyRangeAndValue(name, &min, &max, 0);
Chris@199 184 for (int i = min; i <= max; ++i) {
Chris@199 185 if (valueString == getPropertyValueLabel(name, i)) {
Chris@199 186 value = i;
Chris@199 187 success = true;
Chris@199 188 break;
Chris@199 189 }
Chris@199 190 }
Chris@199 191 break;
Chris@199 192 }
Chris@199 193
Chris@199 194 case UnitsProperty:
Chris@199 195 value = UnitDatabase::getInstance()->getUnitId(valueString, false);
Chris@199 196 if (value >= 0) success = true;
Chris@199 197 else value = 0;
Chris@199 198 break;
Chris@199 199
Chris@199 200 case InvalidProperty:
Chris@690 201 SVDEBUG << "PropertyContainer::convertPropertyStrings: Invalid property name \"" << name << "\"" << endl;
Chris@199 202 return false;
Chris@199 203 }
Chris@199 204
Chris@199 205 if (success) return true;
Chris@199 206
Chris@199 207 int min, max;
Chris@245 208 getPropertyRangeAndValue(name, &min, &max, 0);
Chris@199 209
Chris@199 210 bool ok = false;
Chris@199 211 int i = valueString.toInt(&ok);
Chris@199 212 if (!ok) {
Chris@843 213 cerr << "PropertyContainer::convertPropertyStrings: Unable to parse value string \"" << valueString << "\"" << endl;
Chris@199 214 return false;
Chris@199 215 } else if (i < min || i > max) {
Chris@690 216 SVDEBUG << "PropertyContainer::convertPropertyStrings: Property value \"" << i << "\" outside valid range " << min << " to " << max << endl;
Chris@199 217 return false;
Chris@199 218 }
Chris@199 219
Chris@199 220 value = i;
Chris@199 221 return true;
Chris@199 222 }
Chris@46 223
Chris@46 224 PropertyContainer::SetPropertyCommand::SetPropertyCommand(PropertyContainer *pc,
Chris@46 225 const PropertyName &pn,
Chris@46 226 int value) :
Chris@46 227 m_pc(pc),
Chris@46 228 m_pn(pn),
Chris@46 229 m_value(value),
Chris@46 230 m_oldValue(0)
Chris@0 231 {
Chris@0 232 }
Chris@0 233
Chris@46 234 void
Chris@46 235 PropertyContainer::SetPropertyCommand::execute()
Chris@46 236 {
Chris@245 237 m_oldValue = m_pc->getPropertyRangeAndValue(m_pn, 0, 0, 0);
Chris@46 238 m_pc->setProperty(m_pn, m_value);
Chris@46 239 }
Chris@46 240
Chris@46 241 void
Chris@46 242 PropertyContainer::SetPropertyCommand::unexecute()
Chris@46 243 {
Chris@46 244 m_pc->setProperty(m_pn, m_oldValue);
Chris@46 245 }
Chris@46 246
Chris@46 247 QString
Chris@46 248 PropertyContainer::SetPropertyCommand::getName() const
Chris@46 249 {
Chris@247 250 return tr("Set %1 Property").arg(m_pn);
Chris@46 251 }
Chris@46 252