Skip to content

Latest commit

 

History

History
98 lines (79 loc) · 4.46 KB

README.md

File metadata and controls

98 lines (79 loc) · 4.46 KB

Electric Boogaloo

A string based language for representing musical notation using only ASCII characters. Created as a group project for Bjarne Stroustrup's "Design Using C++" course (COMS 4995) by Brennan McManus, Dean Deng, and Conder Shou. Implemented as an expansion of the C++11 MIDI-format parsing library midifile. A presentation summarizing the content below can be found here.

Representing Music

Electric Boogaloo represents real musical concepts programmatically: program with Notes and Keys, not unsigned integers. It also provides a flexible, string-based input language for the representation of music. The following is an comparison of how to write hot cross buns, with examples written using each of Electric Boogaloo, the original Midifile, and MidiWriterJS.

Electric Boogaloo:

#include "MidiOutput.hpp"

using namespace smf;

int main() {

    Track melody{"E D C . E D C . C C D D E D C ."};
    MidiOutput out{ melody };
    out.write("hot_cross_buns.mid");

    return 0;
}

Midifile:

idiFile midifile;
   int track   = 0;
   int channel = 0;

   int tpq     = midifile.getTPQ();
   int count   = options.getInteger("note-count");
   for (int i=0; i<count; i++) {
      int starttick = int(starttime(i) / 4.0 * tpq);
      int key       = pitch(i); // Get the next key [64, 62, 60, 64, 62, 60 …] 
      int endtick   = starttick + int(duration(mt) / 4.0 * tpq);
      midifile.addNoteOn (track, starttick, channel, key, velocity(mt));
      midifile.addNoteOff(track, endtick,   channel, key);
   }
   midifile.sortTracks();  // Need to sort tracks since added events are
                           // appended to track in random tick order.
   string filename = options.getString("output-file");
   midifile.write(filename);

MidiWriterJS:

var MidiWriter = require('midi-writer-js');

var track = new MidiWriter.Track();

track.addEvent([
			new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4'}),
			new MidiWriter.NoteEvent({pitch: ['C4'], duration: '2'}),
			new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4'}),
			new MidiWriter.NoteEvent({pitch: ['C4'], duration: '2'}),
			new MidiWriter.NoteEvent({pitch: ['C4', 'C4', 'C4', 'C4', 'D4', 'D4', 'D4', 'D4'], duration: '8'}),
			new MidiWriter.NoteEvent({pitch: ['E4','D4'], duration: '4'}),
			new MidiWriter.NoteEvent({pitch: ['C4'], duration: '2'})
	], function(event, index) {
    return {sequential:true};
  }
);
var write = new MidiWriter.Writer(track);
console.log(write.dataUri());

Central Constructs

Pitch

A Pitch is our elemental unit of music, closely tied to the lower-level MIDI format. A Pitch consists of:

  • a base pitch (the pitch’s place in an octave) - one of "C", "D", "E", "F", "G", "A", "B"
  • an accidental (an optional addition of sharpness or flatness) - "#" or "b"
  • and an octave (how high or low the octave of this pitch is) - "^x" or "_x", where x is the number of octaves above or below

When this comes together, we can use this system to represent pitches like “C^4” and “Eb_3”

Note

A Note is any single musical moment, and consists of one or more Pitches, and a length. This represents the Pitch or Pitches, if any, that occur in the given moment, and how long the given moment lasts. A Note can be:

  • a note in the traditional sense, like A or E♭ ("A" and "Eb", respectively)
  • a rest (represented with ".")
  • or a chord, such as an A minor chord (written as "A/C/E" or "ACE").

Notes are implemented as a vector of Pitches and an integer length.

Track

A Track is a single musical line, consisting of any number of Notes. Tracks can be layered on top of each other, and are implemented as a vector of Notes.

Writing MIDI-format files

MidiOutput handles the logic for converting a Track or multiple Tracks to MIDI-format files. MidiOutputs are where Electric Boogaloo interfaces with Midifile's existing MIDI writing utilities.

Added Content

cs4995-library

Contains class structure and logic for representing musical notes, and conversions between these structures and their string representation.

cs4995-include

Contains headers and type definitions for the library.

cs4995-programs

Contains example programs that demonstrate the use of the string-based input language to represent musical ideas.

Makefile.cs4995

Builds the programs in ./cs4995-programs.