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 146 147 148 149 150 151 152 153 154 155 156
|
#ifndef IMPORTMIDI_INNER_H
#define IMPORTMIDI_INNER_H
#include "importmidi_fraction.h"
#include "importmidi_tuplet.h"
#include "importmidi_operation.h"
#include <vector>
#include <cstddef>
#include <utility>
// ---------------------------------------------------------------------------------------
// These inner classes definitions are used in cpp files only
// Include this header to link tests
// ---------------------------------------------------------------------------------------
namespace Ms {
enum class Key;
struct MidiTimeSig;
namespace Meter {
// max level for tuplets: duration cannot go over the tuplet boundary
// this level should be greater than any other level
const int TUPLET_BOUNDARY_LEVEL = 10;
struct MaxLevel
{
int level = 0; // 0 - the biggest, whole bar level; other: -1, -2, ...
int levelCount = 0; // number of positions with 'level' value
ReducedFraction pos = {-1, 1}; // first position with value 'level'; -1 - undefined pos
};
struct DivLengthInfo
{
ReducedFraction len;
int level;
};
struct DivisionInfo
{
ReducedFraction onTime; // division start tick (tick is counted from the beginning of bar)
ReducedFraction len; // length of this whole division
bool isTuplet = false;
std::vector<DivLengthInfo> divLengths; // lengths of 'len' subdivisions
};
enum class DurationType : char;
ReducedFraction userTimeSigToFraction(
MidiOperations::TimeSigNumerator timeSigNumerator,
MidiOperations::TimeSigDenominator timeSigDenominator);
MidiOperations::TimeSigNumerator fractionNumeratorToUserValue(int n);
MidiOperations::TimeSigDenominator fractionDenominatorToUserValue(int z);
} // namespace Meter
class Staff;
class Score;
class MidiTrack;
class DurationElement;
class MidiChord;
class MidiEvent;
class TDuration;
class Measure;
class KeyList;
class MTrack {
public: // chords store tuplet iterators, so we need to copy class explicitly
MTrack();
MTrack(const MTrack &other);
MTrack& operator=(MTrack other);
int program;
Staff* staff;
const MidiTrack* mtrack;
QString name;
bool hasKey;
int indexOfOperation;
int division;
bool isDivisionInTps; // ticks per second
bool hadInitialNotes;
std::multimap<ReducedFraction, int> volumes;
std::multimap<ReducedFraction, MidiChord> chords;
std::multimap<ReducedFraction, MidiTuplet::TupletData> tuplets; // <tupletOnTime, ...>
void createNotes(const ReducedFraction &lastTick);
void processPendingNotes(QList<MidiChord>& midiChords,
int voice,
const ReducedFraction &startChordTickFrac,
const ReducedFraction &nextChordTick);
void processMeta(int tick, const MidiEvent& mm);
void fillGapWithRests(Score *score, int voice, const ReducedFraction &startChordTickFrac,
const ReducedFraction &restLength, int track);
QList<std::pair<ReducedFraction, TDuration> >
toDurationList(const Measure *measure, int voice, const ReducedFraction &startTick,
const ReducedFraction &len, Meter::DurationType durationType);
void createKeys(Key defaultKey, const Ms::KeyList &allKeyList);
void updateTupletsFromChords();
private:
void updateTuplet(std::multimap<ReducedFraction, MidiTuplet::TupletData>::iterator &);
};
namespace MidiTuplet {
struct TupletInfo
{
int id;
ReducedFraction onTime = {-1, 1}; // invalid
ReducedFraction len = {-1, 1};
int tupletNumber = -1;
// <chord onTime, chord iterator>
std::map<ReducedFraction, std::multimap<ReducedFraction, MidiChord>::iterator> chords;
ReducedFraction tupletSumError;
ReducedFraction regularSumError;
ReducedFraction sumLengthOfRests;
int firstChordIndex = -1;
std::map<ReducedFraction, int> staccatoChords; // <onTime, note index>
};
bool haveIntersection(const std::pair<ReducedFraction, ReducedFraction> &interval1,
const std::pair<ReducedFraction, ReducedFraction> &interval2,
bool strictComparison = true);
bool haveIntersection(const std::pair<ReducedFraction, ReducedFraction> &interval,
const std::vector<std::pair<ReducedFraction, ReducedFraction>> &intervals,
bool strictComparison = true);
} // namespace MidiTuplet
namespace MidiCharset {
QString convertToCharset(const std::string &text);
QString defaultCharset();
std::string fromUchar(const uchar *text);
} // namespace MidiCharset
namespace MidiBar {
ReducedFraction findBarStart(const ReducedFraction &time, const TimeSigMap *sigmap);
} // namespace MidiBar
namespace MidiDuration {
double durationCount(const QList<std::pair<ReducedFraction, TDuration> > &durations);
} // namespace MidiDuration
} // namespace Ms
#endif // IMPORTMIDI_INNER_H
|