File: notes.hh

package info (click to toggle)
performous 1.1%2Bgit20181118-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 11,712 kB
  • sloc: cpp: 30,008; ansic: 2,751; sh: 801; xml: 464; python: 374; makefile: 22
file content (136 lines) | stat: -rw-r--r-- 4,760 bytes parent folder | download | duplicates (3)
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
#pragma once

#include <map>
#include <string>
#include <vector>

#include "color.hh"
#include "musicalscale.hh"

/// stores duration of a note
struct Duration {
	double begin; ///< beginning timestamp in seconds
	double end;   ///< ending timestamp in seconds
	Duration();
	/// create a new Duration object and initialize begin and end
	Duration(double b, double e): begin(b), end(e) {}
	/// compares begin timestamps of two Duration structs
	static bool ltBegin(Duration const& a, Duration const& b) { return a.begin < b.begin; }
	/// compares end timestamps of two Duration structs
	static bool ltEnd(Duration const& a, Duration const& b) { return a.end < b.end; }
};

typedef std::vector<Duration> Durations;
typedef std::map<int, Durations> NoteMap;

/// Sort by instrument track name
struct CompInstrumentTrack {
	bool operator()(std::string const& l, std::string const& r) const {
		// TODO: Sort other guitar tracks (coop / rhythm) properly
		return l > r;
	}
};

struct InstrumentTrack {
	// TODO: name should not be needed here (contained into the map)
	InstrumentTrack(std::string n): name(n) {}
	std::string name;
	NoteMap nm;
};

// keep these ones
typedef std::map<std::string, InstrumentTrack, CompInstrumentTrack> InstrumentTracks;
typedef std::map<std::string, InstrumentTrack const*, CompInstrumentTrack> InstrumentTracksConstPtr; // this one really needed ? can't we save only the map key for comparison ?

static inline bool isTrackInside(InstrumentTracks const& track_map, std::string const& name) {
	return track_map.find(name) != track_map.end();
}

// TODO: Make Note use Duration

/// note read from songfile
struct Note {
	Note();
	double begin; ///< begin time
	double end; ///< end time
	double phase; /// Position within a measure, [0, 1)
	// FIXME: Remove gameplay variables from here (Note should be immutable).
	/// power of note (how well it is being hit right now)
	mutable double power;
	/// which players sung well
	mutable std::vector<Color> stars;
	/// note type
	enum Type { FREESTYLE = 'F', NORMAL = ':', GOLDEN = '*', SLIDE = '+', SLEEP = '-',
	  TAP = '1', HOLDBEGIN = '2', HOLDEND = '3', ROLL = '4', MINE = 'M', LIFT = 'L'} type;
	int note; ///< MIDI pitch of the note (at the end for slide notes)
	int notePrev; ///< MIDI pitch of the previous note (should be same as note for everything but SLIDE)
	/// lyrics syllable for that note
	std::string syllable;
	/// Difference of n from note
	double diff(double n) const { return diff(note, n); }
	/// Difference of n from note, so that note + diff(note, n) is n (mod 12)
	static double diff(double note, double n);
	/// Maximum score
	double maxScore() const;
	/// The length of the time period [a,b] that falls within the note in seconds
	double clampDuration(double b, double e) const;
	/// Score when singing over time period (a, b), which needs not to be entirely within the note
	double score(double freq, double b, double e) const;
	/// How precisely the note is hit (always 1.0 for freestyle, 0..1 for others)
	double powerFactor(double note) const;
	/// Compares begin of two notes
	static bool ltBegin(Note const& a, Note const& b) {
		if (a.begin == b.begin) {
			if (a.type == Note::SLEEP) return true;
			if (b.type == Note::SLEEP) return false;			
		}
		return a.begin < b.begin; 
	}
	/// Compares end of two notes
	static bool ltEnd(Note const& a, Note const& b) { return a.end < b.end; }
	/// Compare equality of two notes, used for deleting duplicates when programatically creating the duet track.
	static bool equal(Note const& a, Note const& b) { 
		if (a.type == Note::SLEEP) return (a.type == b.type);
		return (a.begin == b.begin && a.end == b.end && a.note == b.note && a.type == b.type);
	}
	/// Check if two notes overlap
	static bool overlapping(Note const& a, Note const& b) { return (a.end > b.begin && a.type != Note::SLEEP && b.type != Note::SLEEP); }
  private:
	double scoreMultiplier() const;
};

typedef std::vector<Note> Notes;

class VocalTrack {
public:
	VocalTrack(std::string name);
	void reload();
	std::string name;
	Notes notes;
	int noteMin, noteMax; ///< lowest and highest note
	double beginTime, endTime; ///< the period where there are notes
	double m_scoreFactor; ///< normalization factor for the scoring system
	MusicalScale scale; ///< scale in which song is sung
};

typedef std::map<std::string, VocalTrack> VocalTracks;

struct DanceTrack {
	DanceTrack(std::string& description, Notes& notes);
	//track description
	std::string description;
	//container for the actual note data
	Notes notes;
};

enum DanceDifficulty {
	BEGINNER,
	EASY,
	MEDIUM,
	HARD,
	CHALLENGE,
	DIFFICULTYCOUNT
};

typedef std::map<DanceDifficulty, DanceTrack> DanceDifficultyMap;
typedef std::map<std::string, DanceDifficultyMap> DanceTracks;