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@466
|
21 // PlaySpeedRangeMapper maps a position in the range [0,120] on to a
|
Chris@466
|
22 // play speed factor on a logarithmic scale in the range 0.125 ->
|
Chris@466
|
23 // 8. This ensures that the desirable speed factors 0.25, 0.5, 1, 2,
|
Chris@466
|
24 // and 4 are all mapped to exact positions (respectively 20, 40, 60,
|
Chris@466
|
25 // 80, 100).
|
Chris@466
|
26
|
Chris@466
|
27 // Note that the "factor" referred to below is a play speed factor
|
Chris@466
|
28 // (higher = faster, 1.0 = normal speed), the "value" is a percentage
|
Chris@466
|
29 // (higher = faster, 100 = normal speed), and the "position" is an
|
Chris@466
|
30 // integer step on the dial's scale (0-120, 60 = centre).
|
Chris@466
|
31
|
Chris@466
|
32 PlaySpeedRangeMapper::PlaySpeedRangeMapper() :
|
Chris@466
|
33 m_minpos(0),
|
Chris@466
|
34 m_maxpos(120)
|
Chris@43
|
35 {
|
Chris@43
|
36 }
|
Chris@43
|
37
|
Chris@43
|
38 int
|
Chris@434
|
39 PlaySpeedRangeMapper::getPositionForValue(double value) const
|
Chris@43
|
40 {
|
Chris@43
|
41 // value is percent
|
Chris@434
|
42 double factor = getFactorForValue(value);
|
Chris@43
|
43 int position = getPositionForFactor(factor);
|
Chris@43
|
44 return position;
|
Chris@43
|
45 }
|
Chris@43
|
46
|
Chris@43
|
47 int
|
Chris@434
|
48 PlaySpeedRangeMapper::getPositionForValueUnclamped(double value) const
|
Chris@330
|
49 {
|
Chris@330
|
50 // We don't really provide this
|
Chris@330
|
51 return getPositionForValue(value);
|
Chris@330
|
52 }
|
Chris@330
|
53
|
Chris@434
|
54 double
|
Chris@43
|
55 PlaySpeedRangeMapper::getValueForPosition(int position) const
|
Chris@43
|
56 {
|
Chris@434
|
57 double factor = getFactorForPosition(position);
|
Chris@434
|
58 double pc = getValueForFactor(factor);
|
Chris@43
|
59 return pc;
|
Chris@43
|
60 }
|
Chris@43
|
61
|
Chris@434
|
62 double
|
Chris@330
|
63 PlaySpeedRangeMapper::getValueForPositionUnclamped(int position) const
|
Chris@330
|
64 {
|
Chris@330
|
65 // We don't really provide this
|
Chris@330
|
66 return getValueForPosition(position);
|
Chris@330
|
67 }
|
Chris@330
|
68
|
Chris@434
|
69 double
|
Chris@434
|
70 PlaySpeedRangeMapper::getValueForFactor(double factor) const
|
Chris@43
|
71 {
|
Chris@466
|
72 return factor * 100.0;
|
Chris@43
|
73 }
|
Chris@43
|
74
|
Chris@434
|
75 double
|
Chris@434
|
76 PlaySpeedRangeMapper::getFactorForValue(double value) const
|
Chris@43
|
77 {
|
Chris@466
|
78 return value / 100.0;
|
Chris@466
|
79 }
|
Chris@43
|
80
|
Chris@466
|
81 int
|
Chris@466
|
82 PlaySpeedRangeMapper::getPositionForFactor(double factor) const
|
Chris@466
|
83 {
|
Chris@466
|
84 if (factor == 0) return m_minpos;
|
Chris@466
|
85 int pos = int(lrint((log2(factor) + 3.0) * 20.0));
|
Chris@466
|
86 if (pos < m_minpos) pos = m_minpos;
|
Chris@466
|
87 if (pos > m_maxpos) pos = m_maxpos;
|
Chris@466
|
88 return pos;
|
Chris@43
|
89 }
|
Chris@43
|
90
|
Chris@434
|
91 double
|
Chris@43
|
92 PlaySpeedRangeMapper::getFactorForPosition(int position) const
|
Chris@43
|
93 {
|
Chris@466
|
94 return pow(2.0, double(position) * 0.05 - 3.0);
|
Chris@43
|
95 }
|
Chris@43
|
96
|
Chris@43
|
97 QString
|
Chris@43
|
98 PlaySpeedRangeMapper::getUnit() const
|
Chris@43
|
99 {
|
Chris@43
|
100 return "%";
|
Chris@43
|
101 }
|