teaching machines

CS 145 Lecture 38 – Sequencer

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



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.



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);


package lecture1203;

public class Main {
  public static void main(String[] args) {


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;


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) {
      panel.add(new JLabel(instruments.get(r).getName()));
      for (int c = 0; c < nBeats; ++c) {
        checkboxes[r][c] = new JCheckBox();
    add(panel, BorderLayout.CENTER);
    JButton button = new JButton("Compose");
    add(button, BorderLayout.SOUTH);
    button.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        Write.midi(compose(), "/Users/johnch/Desktop/foo.midi");
  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()) {
          phrase.add(new Note(Pitches.A4, Durations.SIXTEENTH_NOTE));
        } else {
          phrase.add(new Rest(Durations.SIXTEENTH_NOTE));
      Mod.repeat(phrase, 10);
      Part part = new Part(instruments.get(r).getId(), r);
    return score;


package lecture1203;

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

public class SequencerMain {
  public static void main(String[] args) {
    ArrayList<Instrument> instruments = new ArrayList<>();
    instruments.add(new Instrument("Cowbell", Instruments.BELL));
    instruments.add(new Instrument("Timpani", Instruments.TIMPANI));
    instruments.add(new Instrument("Bird", Instruments.BIRD));
    new Sequencer(instruments, 8);


on composition:
I’m a bunch of stuff
Liver, feet, lungs, clavicle
I feel like more though