-
Notifications
You must be signed in to change notification settings - Fork 0
/
HalfNote.java
174 lines (142 loc) · 4.64 KB
/
HalfNote.java
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
* Name: Rynel Luo, Vidula Kopli
* PennKey: rynelluo, vkopli
* Recitation: 215, 216
*
* Description: A half note that has already been read from the line
*/
public class HalfNote implements Note{
private static String[] string = {"G", "F", "E", "D", "C", "B",
"A", "G", "F", "E", "D"};
private static int[] pitch = {10, 8, 7, 5, 3, 2, 0, -2, -4, -5, -7};
private static final int SPS = 44100; //samples per second
private static final double DURATION = 1;
private static final int SAMPLE_LENGTH = (int) (SPS * DURATION);
private static final double[] blankArray = new double[(int) (SPS * 0.05)];
private int x;
private int[] y = new int[100];
private int[] staffIdx = new int[100];
private int N = 0; //number of notes in chord
private double[] sampleArray;
/**
* make given note to that note plus a sharp (e.g. F --> F sharp)
* @param note to be set to sharp version of note
*/
public static void setSharp(String s) {
boolean foundNote = false;
for (int i = 0; i < string.length; i++) {
if (string[i].equals(s)) {
pitch[i] += 1;
foundNote = true;
}
}
if (!foundNote) {
throw new IllegalArgumentException("not a valid note string");
}
}
/**
* make given note to that note plus a sharp (e.g. F --> F flat)
* @param note to be set to flat version of note
*/
public static void setFlat(String f) {
boolean foundNote = false;
for (int i = 0; i < string.length; i++) {
if (string[i].equals(f)) {
pitch[i] -= 1;
foundNote = true;
}
}
if (!foundNote) {
throw new IllegalArgumentException("not a valid note string");
}
}
/**
* Constructor: make QuarterNote
* @param x position, y position, index of note in staff
*/
public HalfNote(int xPos, int yPos, int Idx) {
x = xPos;
y[N] = yPos;
staffIdx[N++] = Idx;
sampleArray = makeSampleArray();
}
/**
* get string representation of note
*/
public String getNoteString() {
String s = string[staffIdx[0]];
for (int i = 1; i < N; i++) {
s += "/" + string[staffIdx[i]];
}
return s;
}
/**
* play note
*/
public void play() {
StdAudio.play(sampleArray);
StdAudio.play(blankArray);
}
/**
* draw note
*/
public void draw() {
PennDraw.setPenColor(PennDraw.RED);
for (int i = 0; i < N; i++) {
PennDraw.circle(x, y[i], 3);
}
}
/**
* get sample array for note
*/
public double[] getSampleArray() {
return sampleArray;
}
/**
* Returns staff index of the first note in the chord
* (if the note is part of a chord)
* @return staff index of the first note of the chord
*/
public int getStaffIdx() {
return staffIdx[0];
}
/**
* Returns x position of note (of first note if it is part of a chord)
* @return x position of note
*/
public int getX() {
return x;
}
/**
* Returns y position of note (of first note if it is part of a chord)
* @return y position of note
*/
public int getY() {
return y[0];
}
/**
* add another note over this note by combining sample arrays
* @param note to be overlayed over this note
*/
public void overlayNote(Note newNote) {
//WARNING: assumes inputted note has shorter or same duration as this note
double[] sampleArray2 = newNote.getSampleArray();
y[N] = newNote.getY();
staffIdx[N++] = newNote.getStaffIdx();
for (int i = 0; i < sampleArray2.length; i++) {
sampleArray[i] += sampleArray2[i];
}
}
/**
* make sample array for note (used by StdAudio to play note)
*/
private double[] makeSampleArray() {
int p = pitch[staffIdx[0]];
double hz = 440 * Math.pow(2, p / 12.0);
double[] sampleArray = new double[SAMPLE_LENGTH + 1];
for (int i = 0; i <= SAMPLE_LENGTH; i++) {
sampleArray[i] = Math.sin(2 * Math.PI * i * hz / SPS);
}
return sampleArray;
}
}