summaryrefslogtreecommitdiffstats
path: root/src/track/beatmap.h
blob: d3f05c259110c1257337dbedc112af7227ec7396 (plain)
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
/*
 * beatmap.h
 *
 *  Created on: 08/dic/2011
 *      Author: vittorio
 */

#pragma once

#include <QMutex>

#include "proto/beats.pb.h"
#include "track/beats.h"

#define BEAT_MAP_VERSION "BeatMap-1.0"

class Track;

typedef QList<mixxx::track::io::Beat> BeatList;

namespace mixxx {

class BeatMap final : public Beats {
  public:
    // Construct a BeatMap. iSampleRate may be provided if a more accurate
    // sample rate is known than the one associated with the Track.
    BeatMap(const Track& track, SINT iSampleRate);
    // Construct a BeatMap. iSampleRate may be provided if a more accurate
    // sample rate is known than the one associated with the Track. If it is
    // zero then the track's sample rate will be used. The BeatMap will be
    // deserialized from the byte array.
    BeatMap(const Track& track, SINT iSampleRate,
            const QByteArray& byteArray);
    // Construct a BeatMap. iSampleRate may be provided if a more accurate
    // sample rate is known than the one associated with the Track. If it is
    // zero then the track's sample rate will be used. A list of beat locations
    // in audio frames may be provided.
    BeatMap(const Track& track, SINT iSampleRate,
            const QVector<double>& beats);

    ~BeatMap() override = default;

    // See method comments in beats.h

    Beats::CapabilitiesFlags getCapabilities() const override {
        return BEATSCAP_TRANSLATE | BEATSCAP_SCALE | BEATSCAP_ADDREMOVE |
                BEATSCAP_MOVEBEAT;
    }

    QByteArray toByteArray() const override;
    BeatsPointer clone() const override;
    QString getVersion() const override;
    QString getSubVersion() const override;
    virtual void setSubVersion(const QString& subVersion);

    ////////////////////////////////////////////////////////////////////////////
    // Beat calculations
    ////////////////////////////////////////////////////////////////////////////

    double findNextBeat(double dSamples) const override;
    double findPrevBeat(double dSamples) const override;
    bool findPrevNextBeats(double dSamples,
                           double* dpPrevBeatSamples,
                           double* dpNextBeatSamples) const override;
    double findClosestBeat(double dSamples) const override;
    double findNthBeat(double dSamples, int n) const override;
    std::unique_ptr<BeatIterator> findBeats(double startSample, double stopSample) const override;
    bool hasBeatInRange(double startSample, double stopSample) const override;

    double getBpm() const override;
    double getBpmRange(double startSample, double stopSample) const override;
    double getBpmAroundPosition(double curSample, int n) const override;

    ////////////////////////////////////////////////////////////////////////////
    // Beat mutations
    ////////////////////////////////////////////////////////////////////////////

    void addBeat(double dBeatSample) override;
    void removeBeat(double dBeatSample) override;
    void translate(double dNumSamples) override;
    void scale(enum BPMScale scale) override;
    void setBpm(double dBpm) override;

    SINT getSampleRate() const override {
        return m_iSampleRate;
    }

  private:
    BeatMap(const BeatMap& other);
    bool readByteArray(const QByteArray& byteArray);
    void createFromBeatVector(const QVector<double>& beats);
    void onBeatlistChanged();

    double calculateBpm(const mixxx::track::io::Beat& startBeat,
                        const mixxx::track::io::Beat& stopBeat) const;
    // For internal use only.
    bool isValid() const;

    void scaleDouble();
    void scaleTriple();
    void scaleQuadruple();
    void scaleHalve();
    void scaleThird();
    void scaleFourth();

    mutable QMutex m_mutex;
    QString m_subVersion;
    SINT m_iSampleRate;
    double m_dCachedBpm;
    double m_dLastFrame;
    BeatList m_beats;
};

} // namespace mixxx