Skip to content

Commit 641d7d7

Browse files
committed
10/19/2019 it is rainny today
1 parent d08b685 commit 641d7d7

File tree

138 files changed

+2777
-80
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

138 files changed

+2777
-80
lines changed

.gitignore

Lines changed: 0 additions & 50 deletions
This file was deleted.

.gitmodules

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/** A client that uses the synthesizer package to replicate a plucked guitar string sound */
2+
public class GuitarHeroLite {
3+
private static final double CONCERT_A = 440.0;
4+
private static final double CONCERT_C = CONCERT_A * Math.pow(2, 3.0 / 12.0);
5+
6+
public static void main(String[] args) {
7+
/* create two guitar strings, for concert A and C */
8+
synthesizer.GuitarString stringA = new synthesizer.GuitarString(CONCERT_A);
9+
synthesizer.GuitarString stringC = new synthesizer.GuitarString(CONCERT_C);
10+
11+
while (true) {
12+
13+
/* check if the user has typed a key; if so, process it */
14+
if (StdDraw.hasNextKeyTyped()) {
15+
char key = StdDraw.nextKeyTyped();
16+
if (key == 'a') {
17+
stringA.pluck();
18+
} else if (key == 'c') {
19+
stringC.pluck();
20+
}
21+
}
22+
23+
/* compute the superposition of samples */
24+
double sample = stringA.sample() + stringC.sample();
25+
26+
/* play the sample on standard audio */
27+
StdAudio.play(sample);
28+
29+
/* advance the simulation of each guitar string by one step */
30+
stringA.tic();
31+
stringC.tic();
32+
}
33+
}
34+
}
35+

hw/hw1/GuitarPlayer.java.skeleton

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import edu.princeton.cs.algs4.StdAudio;
2+
import synthesizer.GuitarString;
3+
4+
import javax.sound.midi.InvalidMidiDataException;
5+
import javax.sound.midi.MetaMessage;
6+
import javax.sound.midi.MidiEvent;
7+
import javax.sound.midi.MidiMessage;
8+
import javax.sound.midi.MidiSystem;
9+
import javax.sound.midi.Sequence;
10+
import javax.sound.midi.Track;
11+
import java.io.File;
12+
import java.io.IOException;
13+
import java.io.InputStream;
14+
15+
/**
16+
* Plays guitar from MIDI files.
17+
*
18+
* @author Eli Lipsitz
19+
*/
20+
public class GuitarPlayer {
21+
private Sequence sequence = null;
22+
private GuitarString[] strings;
23+
private double[] vol;
24+
25+
public GuitarPlayer(InputStream source) {
26+
try {
27+
sequence = MidiSystem.getSequence(source);
28+
} catch (IOException | InvalidMidiDataException e) {
29+
e.printStackTrace();
30+
}
31+
}
32+
33+
public GuitarPlayer(File source) {
34+
try {
35+
sequence = MidiSystem.getSequence(source);
36+
} catch (IOException | InvalidMidiDataException e) {
37+
e.printStackTrace();
38+
}
39+
}
40+
41+
private void initialize() {
42+
strings = new GuitarString[128];
43+
vol = new double[128];
44+
for (int i = 0; i < strings.length; i++) {
45+
strings[i] = new GuitarString(440.0 * Math.pow(2.0, (i - 69.0) / 12.0));
46+
vol[i] = 0.0;
47+
}
48+
}
49+
50+
private void tic() {
51+
for (int i = 0; i < strings.length; i++) {
52+
if (vol[i] > 0.0) {
53+
strings[i].tic();
54+
}
55+
}
56+
}
57+
58+
private double sample() {
59+
double sum = 0.0f;
60+
for (int i = 0; i < strings.length; i++) {
61+
sum += vol[i] * strings[i].sample();
62+
}
63+
return sum;
64+
}
65+
66+
public void play() {
67+
if (sequence == null) {
68+
return;
69+
}
70+
71+
System.out.println("starting performance...");
72+
initialize();
73+
double bpm = 120;
74+
double samplesPerTick = (StdAudio.SAMPLE_RATE * 60.0) / (sequence.getResolution() * bpm);
75+
76+
Track[] tracks = sequence.getTracks();
77+
Track track = sequence.createTrack();
78+
int maxSize = 0;
79+
int lead = 0;
80+
for (int i = 0; i < tracks.length; i++) {
81+
for (int j = 0; j < tracks[i].size(); j++) {
82+
track.add(tracks[i].get(j));
83+
}
84+
}
85+
86+
long tick = 0;
87+
for (int i = 0; i < track.size(); i++) {
88+
MidiEvent event = track.get(i);
89+
MidiMessage msg = event.getMessage();
90+
byte[] data = msg.getMessage();
91+
92+
if (msg instanceof MetaMessage) {
93+
MetaMessage mm = (MetaMessage) msg;
94+
if (mm.getType() == 0x51) {
95+
// set tempo
96+
data = mm.getData();
97+
int tempo = (data[0] & 0xff) << 16 | (data[1] & 0xff) << 8 | (data[2] & 0xff);
98+
bpm = 60000000.0 / tempo;
99+
samplesPerTick = (StdAudio.SAMPLE_RATE * 60.0);
100+
samplesPerTick /= (sequence.getResolution() * bpm);
101+
} else if (mm.getType() == 0x05) {
102+
// lyrics
103+
data = mm.getData();
104+
String lyrics = new String(data);
105+
lyrics = lyrics.replace("\r", "\r\n");
106+
System.out.print(lyrics);
107+
}
108+
continue;
109+
}
110+
111+
if (event.getTick() > tick) {
112+
int samplesToSkip = (int) ((event.getTick() - tick) * samplesPerTick);
113+
for (int j = 0; j < samplesToSkip; j++) {
114+
tic();
115+
StdAudio.play(sample());
116+
}
117+
tick = event.getTick();
118+
}
119+
120+
int j = 0;
121+
while (j < data.length - 2) {
122+
int s = data[j++] & 0xFF;
123+
124+
if (s >= 0x80 && s <= 0x8F) {
125+
// note off
126+
int note = data[j++] & 0xFF;
127+
int vel = data[j++] & 0xFF;
128+
vol[note] = 0.0;
129+
} else if (s >= 0x90 && s <= 0x9F) {
130+
// note on?
131+
int note = data[j++] & 0xFF;
132+
int vel = data[j++] & 0xFF;
133+
vol[note] = vel / 127.0;
134+
strings[note].pluck();
135+
} else {
136+
// status
137+
int d = data[j++] & 0xFF;
138+
int d2 = data[j++] & 0xFF;
139+
}
140+
}
141+
}
142+
143+
System.out.println("please clap");
144+
}
145+
}

0 commit comments

Comments
 (0)