-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathAlignment.cs
More file actions
135 lines (104 loc) Β· 4.05 KB
/
Alignment.cs
File metadata and controls
135 lines (104 loc) Β· 4.05 KB
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
ο»Ώusing System;
using System.Collections.Generic;
using ABC;
using UnityEngine;
namespace ABCUnity
{
public class Alignment
{
public class Beat
{
public List<ABC.Item> items = new List<ABC.Item>();
public int beatStart { get; }
public Beat(int beatStart)
{
this.beatStart = beatStart;
}
}
public class Measure
{
public List<Beat> beats { get; } = new List<Beat>();
public ABC.Item bar;
public int lineNumber { get; set; }
public Measure(int lineNumber)
{
this.lineNumber = lineNumber;
}
public bool isRest
{
get { return IsMeasureRest(); }
}
private bool IsMeasureRest()
{
if (beats.Count != 1)
return false;
if (beats[0].items.Count != 1)
return false;
return beats[0].items[0].type == ABC.Item.Type.MultiMeasureRest;
}
}
public List<Measure> measures { get; private set; }
TimeSignature timeSignature;
public Voice voice {get; private set;}
public void Create(ABC.Voice voice)
{
this.voice = voice;
measures = new List<Measure>();
if (voice.items.Count == 0) return;
var initialTimeSignature = voice.initialTimeSignature;
if (initialTimeSignature == string.Empty)
throw new BeatAlignmentException("Voice does not initially declare a time signature.");
timeSignature = TimeSignature.Parse(initialTimeSignature);
float t = 0;
int currentBeat = 1;
int lineNumber = 0;
Measure measure = new Measure(lineNumber);
Beat beat = new Beat(currentBeat);
for (int i = 0; i < voice.items.Count; i++)
{
switch (voice.items[i].type)
{
case ABC.Item.Type.Chord:
case ABC.Item.Type.Rest:
case ABC.Item.Type.Note:
var noteItem = voice.items[i] as ABC.Duration;
beat.items.Add(noteItem);
t += noteItem.duration;
if (t >= timeSignature.noteValue) // current beat is filled
{
measure.beats.Add(beat);
float beatCount = Mathf.Floor(t / timeSignature.noteValue);
currentBeat += (int)beatCount;
beat = new Beat(currentBeat);
t -= beatCount * timeSignature.noteValue;
}
break;
case ABC.Item.Type.MultiMeasureRest:
var measureRest = voice.items[i] as ABC.MultiMeasureRest;
if (measureRest.count > 1)
throw new LayoutException("Measure Rests of length greater than 1 are not currently supported.");
beat.items.Add(measureRest);
break;
case ABC.Item.Type.Bar:
measure.bar = voice.items[i];
if (beat.items.Count > 0)
measure.beats.Add(beat);
measures.Add(measure);
measure = new Measure(lineNumber);
currentBeat = 1;
beat = new Beat(currentBeat);
t = 0.0f;
break;
case ABC.Item.Type.LineBreak:
lineNumber += 1;
measure.lineNumber = lineNumber;
break;
}
}
if (beat.items.Count > 0)
measure.beats.Add(beat);
if (measure.beats.Count > 0)
measures.Add(measure);
}
}
}