File: CoordinateScale.h

package info (click to toggle)
sonic-visualiser 5.2.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 24,744 kB
  • sloc: cpp: 158,888; ansic: 11,920; sh: 1,785; makefile: 517; xml: 64; perl: 31
file content (145 lines) | stat: -rw-r--r-- 4,734 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */

/*
    Sonic Visualiser
    An audio file viewer and annotation editor.
    Centre for Digital Music, Queen Mary, University of London.
    
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version.  See the file
    COPYING included with this distribution for more information.
*/

#ifndef COORDINATE_SCALE_H
#define COORDINATE_SCALE_H

#include <QString>

namespace sv {

class LayerGeometryProvider;

/**
 * A facility to map between coordinate and value in a given axis.
 * Queries a LayerGeometryProvider to find the proper dimensions for
 * its axis direction. A CoordinateScale object is self-contained and
 * can be passed around by value.
 *
 * These are generally only used where a scale is monotonic through
 * the visible area of the layer. Currently layers which may have more
 * than one scale region (e.g. waveforms, whose y axis may be divided
 * into multi-channel regions) or layers whose scale occupies only a
 * part of their visible area (e.g. the x axis of spectra) are not
 * able to make use of this.
 */
class CoordinateScale
{
public:
    enum class FrequencyMap {
        Linear,
        Mel,
        Log
    };

    enum class Direction {
        Horizontal,
        Vertical
    };

    /**
     * Construct a continuous linear or logarithmic scale with an
     * arbitrary unit and given extents. In the case of a log scale,
     * the extents are actual values, not log-values. The display
     * extents will be initialised to the same as the value extents.
     */
    CoordinateScale(Direction direction, QString unit, bool logarithmic,
                    double minValue, double maxValue);
        
    /**
     * Construct a frequency scale with a given map and extents. The
     * extents should be in Hz and the unit of the scale will be
     * "Hz". The display extents will be initialised to the same as
     * the value extents.
     */
    CoordinateScale(Direction direction, FrequencyMap map,
                    double minValue, double maxValue);

    /**
     * Construct an integer-valued bin scale with the given
     * extents. The extents should be in bin number (zero-based) and
     * the unit of the scale will be "bins". The display extents will
     * be initialised to the same as the value extents.
     */
    CoordinateScale(Direction direction, bool logarithmic,
                    int minBin, int maxBin);

    double getCoordForValue(const LayerGeometryProvider *, double value) const;
    int getCoordForValueRounded(const LayerGeometryProvider *, double value) const;

    double getValueForCoord(const LayerGeometryProvider *, double coordinate) const;
    int getValueForCoordRounded(const LayerGeometryProvider *, double coordinate) const;

    Direction getDirection() const { return m_direction; }
    
    QString getUnit() const { return m_unit; }

    double getValueMinimum() const { return m_valueMin; }
    double getValueMaximum() const { return m_valueMax; }

    double getDisplayMinimum() const { return m_displayMin; }
    double getDisplayMaximum() const { return m_displayMax; }

    CoordinateScale withValueExtents(double min, double max) const;
    CoordinateScale withDisplayExtents(double min, double max) const;

    CoordinateScale unionWith(const CoordinateScale &other) const;
    
    /**
     * Return true if the scale is logarithmic. Note that a scale
     * could have any kind of mapping - false does not imply linear.
     */
    bool isLogarithmic() const {
        if (m_isFrequencyScale) {
            return m_frequencyMap == FrequencyMap::Log;
        } else {
            return m_logarithmic;
        }
    }

    /**
     * Return true if the scale is linear. Note that a scale could
     * have any kind of mapping - false does not imply logarithmic.
     */
    bool isLinear() const {
        if (m_isFrequencyScale) {
            return m_frequencyMap == FrequencyMap::Linear;
        } else {
            return !m_logarithmic;
        }
    }

    bool visualRangeMatches(const CoordinateScale &other) const;
    
private:
    Direction m_direction;
    bool m_isFrequencyScale;
    bool m_isBinScale;
    QString m_unit;
    bool m_logarithmic;
    FrequencyMap m_frequencyMap;
    double m_valueMin;
    double m_valueMax;
    double m_displayMin;
    double m_displayMax;
    
    double map(double value) const;
    double unmap(double point) const;
    void mapExtents(double &min, double &max) const;
};

} // end namespace sv

#endif