# teaching machines

## CS 145 Lecture 38 – Sequencer

December 3, 2014 by . Filed under cs145, fall 2014, lectures.

### Agenda

• what ?s
• instance vs. local vs. static
• compose this
• sequencer

### TODO

• An extra credit Weekly Outside Problem will be emailed to you later today. This last one is a little survey about your reaction to and interest in computer science, and I’d really appreciate your feedback even if you don’t need the extra credit.

### Compose This

A musician friend asks you to write a sequencer application so that he can walk across campus. Without a steady beat in his ear, his legs don’t move. He’d like to have a graphical user interface that shows a bunch of percussive instruments and lets him choose on which beats a particular instrument plays. Once a measure or two is composed, he’d like to generate an audio file that repeats the sequence many times.

What actors/objects might you call upon to compose this application? What state do they manage? What behaviors are needed for other actors to interact with them? Think of at least 4.

### Code

#### Vector2D.java

package lecture1203;

public class Vector2D {
private double x;
private double y;

public static final Vector2D X = new Vector2D(1, 0);
public static final Vector2D Y = new Vector2D(0, 1);

public Vector2D() {
x = y = 0.0;
}

public Vector2D(double x, double y) {
this.x = x;
this.y = y;
}

public double getLength() {
return Math.hypot(x, y);
}

public void normalize() {
double length = getLength();
x /= length;
y /= length;
}

public String toString() {
return String.format("%f %f -> %f", x, y, getLength());
}

public static void main(String[] args) {
Vector2D v = new Vector2D(10, 10);
v.normalize();
System.out.println(v);
}
}

#### Main.java

package lecture1203;

public class Main {
public static void main(String[] args) {
System.out.println(Vector2D.X);
}
}

#### Instrument.java

package lecture1203;

public class Instrument {
private String name;
private int id;

public Instrument(String name,
int id) {
this.name = name;
this.id = id;
}

public String getName() {
return name;
}

public int getId() {
return id;
}
}

#### Sequencer.java

package lecture1203;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import jm.constants.Durations;
import jm.constants.Pitches;
import jm.music.data.Note;
import jm.music.data.Part;
import jm.music.data.Phrase;
import jm.music.data.Rest;
import jm.music.data.Score;
import jm.music.tools.Mod;
import jm.util.Write;

public class Sequencer extends JFrame {
private JCheckBox[][] checkboxes;
private ArrayList<Instrument> instruments;

public Sequencer(ArrayList<Instrument> instruments,
int nBeats) {
this.instruments = instruments;
checkboxes = new JCheckBox[instruments.size()][nBeats];

// Layout
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(instruments.size(), nBeats + 1));

for (int r = 0; r < instruments.size(); ++r) {
for (int c = 0; c < nBeats; ++c) {
checkboxes[r][c] = new JCheckBox();
}
}

JButton button = new JButton("Compose");
@Override
public void actionPerformed(ActionEvent e) {
Write.midi(compose(), "/Users/johnch/Desktop/foo.midi");
}
});

pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}

private Score compose() {
Score score = new Score("Walking Beat");

for (int r = 0; r < instruments.size(); ++r) {
Phrase phrase = new Phrase();

// Create phrase.
for (int c = 0; c < checkboxes[r].length; ++c) {
if (checkboxes[r][c].isSelected()) {
} else {
}
}

Mod.repeat(phrase, 10);

Part part = new Part(instruments.get(r).getId(), r);

}

return score;
}
}

#### SequencerMain.java

package lecture1203;

import java.util.ArrayList;
import jm.constants.Instruments;

public class SequencerMain {
public static void main(String[] args) {
ArrayList<Instrument> instruments = new ArrayList<>();

}