annotate audioio/PlaySpeedRangeMapper.cpp @ 451:dc1a360f2b69

Allow layers to be loaded without models if their layer class explicitly says it's OK (otherwise default template won't load, as it has an empty waveform layer)
author Chris Cannam
date Mon, 20 Apr 2015 10:10:26 +0100
parents 72c662fe7ea3
children 45054b36ddbf
rev   line source
Chris@43 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@43 2
Chris@43 3 /*
Chris@43 4 Sonic Visualiser
Chris@43 5 An audio file viewer and annotation editor.
Chris@43 6 Centre for Digital Music, Queen Mary, University of London.
Chris@43 7 This file copyright 2006 QMUL.
Chris@43 8
Chris@43 9 This program is free software; you can redistribute it and/or
Chris@43 10 modify it under the terms of the GNU General Public License as
Chris@43 11 published by the Free Software Foundation; either version 2 of the
Chris@43 12 License, or (at your option) any later version. See the file
Chris@43 13 COPYING included with this distribution for more information.
Chris@43 14 */
Chris@43 15
Chris@43 16 #include "PlaySpeedRangeMapper.h"
Chris@43 17
Chris@43 18 #include <iostream>
Chris@43 19 #include <cmath>
Chris@43 20
Chris@43 21 PlaySpeedRangeMapper::PlaySpeedRangeMapper(int minpos, int maxpos) :
Chris@43 22 m_minpos(minpos),
Chris@43 23 m_maxpos(maxpos)
Chris@43 24 {
Chris@43 25 }
Chris@43 26
Chris@43 27 int
Chris@434 28 PlaySpeedRangeMapper::getPositionForValue(double value) const
Chris@43 29 {
Chris@43 30 // value is percent
Chris@434 31 double factor = getFactorForValue(value);
Chris@43 32 int position = getPositionForFactor(factor);
Chris@43 33 return position;
Chris@43 34 }
Chris@43 35
Chris@43 36 int
Chris@434 37 PlaySpeedRangeMapper::getPositionForValueUnclamped(double value) const
Chris@330 38 {
Chris@330 39 // We don't really provide this
Chris@330 40 return getPositionForValue(value);
Chris@330 41 }
Chris@330 42
Chris@330 43 int
Chris@434 44 PlaySpeedRangeMapper::getPositionForFactor(double factor) const
Chris@43 45 {
Chris@43 46 bool slow = (factor > 1.0);
Chris@43 47
Chris@43 48 if (!slow) factor = 1.0 / factor;
Chris@43 49
Chris@43 50 int half = (m_maxpos + m_minpos) / 2;
Chris@43 51
Chris@436 52 factor = sqrt((factor - 1.0) * 1000.0);
Chris@436 53 int position = int(lrint(((factor * (half - m_minpos)) / 100.0) + m_minpos));
Chris@43 54
Chris@43 55 if (slow) {
Chris@43 56 position = half - position;
Chris@43 57 } else {
Chris@43 58 position = position + half;
Chris@43 59 }
Chris@43 60
Chris@293 61 // cerr << "value = " << value << " slow = " << slow << " factor = " << factor << " position = " << position << endl;
Chris@43 62
Chris@43 63 return position;
Chris@43 64 }
Chris@43 65
Chris@434 66 double
Chris@43 67 PlaySpeedRangeMapper::getValueForPosition(int position) const
Chris@43 68 {
Chris@434 69 double factor = getFactorForPosition(position);
Chris@434 70 double pc = getValueForFactor(factor);
Chris@43 71 return pc;
Chris@43 72 }
Chris@43 73
Chris@434 74 double
Chris@330 75 PlaySpeedRangeMapper::getValueForPositionUnclamped(int position) const
Chris@330 76 {
Chris@330 77 // We don't really provide this
Chris@330 78 return getValueForPosition(position);
Chris@330 79 }
Chris@330 80
Chris@434 81 double
Chris@434 82 PlaySpeedRangeMapper::getValueForFactor(double factor) const
Chris@43 83 {
Chris@434 84 double pc;
Chris@43 85 if (factor < 1.0) pc = ((1.0 / factor) - 1.0) * 100.0;
Chris@43 86 else pc = (1.0 - factor) * 100.0;
Chris@293 87 // cerr << "position = " << position << " percent = " << pc << endl;
Chris@43 88 return pc;
Chris@43 89 }
Chris@43 90
Chris@434 91 double
Chris@434 92 PlaySpeedRangeMapper::getFactorForValue(double value) const
Chris@43 93 {
Chris@43 94 // value is percent
Chris@43 95
Chris@434 96 double factor;
Chris@43 97
Chris@43 98 if (value <= 0) {
Chris@43 99 factor = 1.0 - (value / 100.0);
Chris@43 100 } else {
Chris@43 101 factor = 1.0 / (1.0 + (value / 100.0));
Chris@43 102 }
Chris@43 103
Chris@293 104 // cerr << "value = " << value << " factor = " << factor << endl;
Chris@43 105 return factor;
Chris@43 106 }
Chris@43 107
Chris@434 108 double
Chris@43 109 PlaySpeedRangeMapper::getFactorForPosition(int position) const
Chris@43 110 {
Chris@43 111 bool slow = false;
Chris@43 112
Chris@43 113 if (position < m_minpos) position = m_minpos;
Chris@43 114 if (position > m_maxpos) position = m_maxpos;
Chris@43 115
Chris@43 116 int half = (m_maxpos + m_minpos) / 2;
Chris@43 117
Chris@43 118 if (position < half) {
Chris@43 119 slow = true;
Chris@43 120 position = half - position;
Chris@43 121 } else {
Chris@43 122 position = position - half;
Chris@43 123 }
Chris@43 124
Chris@43 125 // position is between min and half (inclusive)
Chris@43 126
Chris@434 127 double factor;
Chris@43 128
Chris@43 129 if (position == m_minpos) {
Chris@43 130 factor = 1.0;
Chris@43 131 } else {
Chris@43 132 factor = ((position - m_minpos) * 100.0) / (half - m_minpos);
Chris@43 133 factor = 1.0 + (factor * factor) / 1000.f;
Chris@43 134 }
Chris@43 135
Chris@43 136 if (!slow) factor = 1.0 / factor;
Chris@43 137
Chris@293 138 // cerr << "position = " << position << " slow = " << slow << " factor = " << factor << endl;
Chris@43 139
Chris@43 140 return factor;
Chris@43 141 }
Chris@43 142
Chris@43 143 QString
Chris@43 144 PlaySpeedRangeMapper::getUnit() const
Chris@43 145 {
Chris@43 146 return "%";
Chris@43 147 }