MUMT 307 Term Project
The Project
The goal of this project was to create a highly-functional drum sequencer, capable of producing unusual time signatures, fully customizable to the user's specification. The resulting program is a set of Max/MSP patches with embedded Javascript.

Functions
First, one loads their desired samples into the Sample Editor frames. The user can pitch-shift each sample by the desired number of semitones, select a portion of the sample to be played (if they do not want the whole sample), play the sample in reverse, and preview the sample. The program automatically extracts the sample name from the file name, and displays it beside the sample. See below for an example.
Sample Editor

Then, the user goes to Sequencer mode by selecting the tab at the bottom. Here, they can select boxes for the given sample they would like in the loop, where time progresses from left to right. One can zoom in and out with the black bar at the bottom of the grid, which is a sort of scroll bar. See below for an example.
Sequencer

The user can customize the timing of samples in the following manner: Shift-clicking on a square subdivides its column. The resulting two columns individually occupy half the time that the original one did. One can append a new column by cmd-clicking on a column, or prepend by ctrl-clicking, both having the effect of adding a new column to the layer of the column clicked on, and skewing the time values for that layer. Option-clicking deletes a column.
Bars can also be created and deleted by the same types of clicks on the rectangles above the grid. Shift-clicking on a given half of one of these rectangles prepends or appends a new column to the very beginning or end of that bar. Here is an example of bars deleted, columns subdivided, and then expanded.
Time Skewing

The amount of time per bar is fixed, but the width of each column is proportional to the amount of time within the bar that the sample occupies.

Looking down, one sees the Volume Sliders frame. Here the user can select the sample whose volume they would like to modify, with the bottommost sample as the default. By dragging the white bars, one scales the volume of the sample for playback. The layout of the sliders reflects the structure of the sequencer frame. See the picture below:
Volume Sliders

Looking even farther down, one sees the Flanger frame. Here, for each sample, if desired, the user can flange the signal. 5 parameters are given for each flanger, so the effect can be tuned to the user's desires. An example is shown below.
Flanger Frame

Finally, one can playback the loop, with looping enabled or disabled, with the little box on the right. They can set tempo, and "Optimize for CPU", which disables the highlighting of columns in the sequencer during playback, significantly unburdening the CPU during playback, especially for higher tempos.
And that's how it's used!
Challenges Faced
I could write a lengthy report on the innumerable difficulties faced in developing this software, but I'll spare you the boring details. Here are the major challenges that I faced. Firstly, Max/MSP, as a program, has inconsistencies. For example, "detonate" objects mysteriously intercommunicate, undesirably, if they reside in the same patch, so they must be separately encapsulated. A detonate can not simply re-trigger itself, as it simply ignores the message to do so, so backdoors had to be found.
Also, with too many send~ and receive~ objects, Max simply crashes when audio is enabled, without explanation. I had to pore over the crash dump to figure out the source.
Other expected behaviours tend to misbehave, like the bang sent out by a buffer~ when it has finished loading a sample. This bang actually occurs before the read is done, so one must delay by a few hundred milliseconds before using the data.
Being limited to "jsui" objects for dynamic GUI development was a bit painful, as Javascript is an extremely slow language. It was originally my intention to code almost the whole project in Javascript, but Max was necessary for time-sensitive processes and, of course, DSP. It was done out of necessity, since dynamically creating and arranging Max objects is dreadfully difficult.

In the end, the biggest challenge faced was the fact that Max/MSP is simply not intended for building software of this magnitude. I should have realised this from the get-go...there's a reason they call it a "patch" and not an application. This problem manifests itself through the difficulty had in modularizing objects through dynamically assigned arguments, and the fact that every send or send~ makes its data global. Variable scope for sends would be fantastic, but the developers decided against this. One could say that I should just connect everything with wires, but then the screen would be full of wires, and the program would become unreadable. Contorting my development process to work with these limitations ended up occupying a large part of the work put into this project. I apologize in advance for the illegibility of my Javascript code. It was written in moments of inspiration, and as a consequence, good form went by the wayside.
Improvements for the Future
The first thing I would do is reprogram everything in a different language. Ideally I would do it in C++/Objective-C, backed by STK, with an interface package like QT. I could then apply real software development principles. Secondly, in my reprogramming, I would do it top-down, instead of bottom-up. When I wrote Seq, I would think something up, and then graft it onto the existing framework. Much refactoring was required as a result of this, but with a better plan for the whole program and a programming environment that makes modularity simpler, the program could be cleanly written.
On a functional level, I would add more DSP options, such as filters, reverb, echo, vocoding, etc. to the signal chain. It was my original intention to have some of these, and make the order in which they are processed user-configurable within the SignalMatrix patch (hence the name). Packaging this software as a VST would be nice, since then it could run within other sequencers, and the drum loops could be applied to music production. A way of saving loops would be nice to have, and not terribly difficult to program.
These are the changes I will make if I choose to continue development of this software.
The Result
That's it! Enjoy the program. It's attached below.
Download

--Brian Stern