Shipping will be unavailable from Dec 21 to Jan 3. Orders placed during that time will be shipped the week of Jan 3.

Sequences

The source for this demo on Ardcore can be downloaded [here](https://github.com/nw2s/b/blob/master/sketches/nw2s/ArdcoreDemoSequence/ArdcoreDemoSequence.ino). The 'b version [is available as well](https://github.com/nw2s/b/blob/master/sketches/nw2s/bDemoSequence/bDemoSequence.ino). Please note that the 'b version includes both the pitch and envelope CV signals and therefore won't run on the Ardcore. When you want to play a sequence of notes... you use a sequence. A NoteSequencer to be exact. I apologize ahead of time, but this will be the first tutorial where a bit of C++ knowledge will help keep you from getting completely confused. Otherwise, just focus on the bigger picture and don't worry about the syntax details. ### Notation First, let's talk a little bit about notation. We are specifying the notes of a sequence as a tuple of octave and scale degree. Even though 'degree' may not be the proper musical terminology, that's what we'll use to specify the index of the note within the scale. For major and minor scales, it will make perfect sense. Here are some examples - though we'll show a better way of describing them in the next step. SequenceNote root = { 0, 1 }; SequenceNote fifth = { 0, 5 }; SequenceNote octave = { 1, 1 }; SequenceNote highest = { 5, 1 }; A modular synth operates on control voltages of 0-5V representing a total of 4 complete octaves and one last note on top. basically C0 through C5. Let's build an array of notes that will represent our sequence for the tutorial: SequenceNote notelist[34] = { {1,1}, {1,3}, {1,5}, {1,1}, {1,3}, {1,5}, {1,1}, {1,5}, {2,1}, {2,3}, {2,5}, {2,1}, {2,3}, {2,5}, {2,1}, {2,5}, {3,1}, {3,3}, {3,5}, {3,1}, {3,3}, {3,5}, {3,1}, {3,5}, {4,1}, {4,3}, {4,5}, {4,1}, {4,3}, {4,5}, {4,1}, {5,1} }; As you can see, you can represent an arbitrarily long sequence of notes as an array. This one is 34 notes long and wanders around, slowly arpeggiating upwards from {0,1} to {5,1} - Which, coincidentally, just happens to be the 5 octave range that we can represent with our available 0V - 5V CV range. ### Sequencing Assuming that makes sense, let's do something a little more useful with it. /* Add the raw array to a vector for easier transport */ NoteSequenceData* notes = new NoteSequenceData(notelist, notelist + 34); /* Build our note-based seuqnce */ NoteSequencer* sequencer = NoteSequencer::create(notes, C, MAJOR, DIV_QUARTER, ARDCORE_DAC); And here's the first side effect of working in C++. Arrays in and of themselves are simply pointers to an address in memory, so to pass them around to other methods requires passing other metadata. The NoteSequenceData class is an abstraction of the C++ STL vector which encapsulates logic to manage lists of data such as a sequence of notes. With the vector, we can now create our actual sequencer device. The sequencer is created by specifying the sequence of notes, the key, the scale type, the clock division, and the analog out. Don't forget to attach this beat device to a clock. fixedclock->registerdevice(sequencer); When you upload this, the sequencer will immediately begin looping, generating voltages on the output specified. If you look at the complete source file, you'll notice that the fixedclock is a 16 note per phrase clock and the sequence is a 34 note sequence. What does this mean? This means that the clock itself will reset to beat 0 after 16 ticks, but the sequence will continue and not reset until it reaches the end of 34 ticks. This out-of-phase phrasing may be desired or not. If not, simply limit your sequences to 2, 4, 8, or 16 notes. ### Bonus There's an optional boolean parameter on the sequence factory method. NoteSequencer* sequencer = NoteSequencer::create(notes, C, MAJOR, DIV_QUARTER, ARDCORE_DAC, true); It specifies whether or not the sequence should be randomized. When set to true, the notes of the sequence will be played in a random order. The value defaults to false (it will play them in the correct order). ### Additional Parameters A sequentially changing list of CV pitch values is of limited value by itself. There are a few properties that may also be set that will add additional data or modifications to the sequence. ### Slew sequencer->setslew(DecaySlew::create(0.90)); There are two slew controllers that will modify the pitch output. The DecaySlew uses an exponential decay similar to an RC network to slew the value from one pitch to the next. The input parameter is the time constant. The time constant values can be from 0.99 to 0.10 where the larger values are longer and smaller values are shorter. sequencer->setslew(LinearSlew::create(25)); There is also a linear slew which is a simple linear path from one value to the next. The speed parameter is valid from 1 to 99 where smaller values are slower and larger values are faster. ### Gate sequencer->setgate(Gate::create(ARDCORE_OUT_D0, 75)); The gate parameter adds another output to your sequence. It uses a digital output to trigger and ADSR, run a VCA directly, or any other use you may have. The first parameter is the digital output and the second value is the time in milliseconds that the gate should remain open. ### Envelope sequencer->seteg(ADSR::create(20, 40, 254, 1250, 1200, false, ARDCORE_DAC)); This bit o code sets up yet another output for your sequence. This will generate CV corresponding to an ADSR envelope on the output ARDCORE_DAC. What's that? You say you're already using ARDCORE_DAC for the pitch CV? Ah. Yeah, well, there's only one DAC output on the Ardcore. That's one reason I'm working on a prototype box that has more outs. Until then, you'll need to decide whether you want pitch or ADSR. Can't do both. ### Continuing Obviously, with the Ardcore, you can only have a single DAC output. This can be a little bit limiting, but with the nw2s::b, you'll be able to have quite a few more sequences all running at the same time. They can be running on the same clock with different clock divisions or even on different clocks running on different tempos. Spend some time. Play, make sounds. Then [continue to the next tutorial](https://github.com/nw2s/b/wiki/05-Tutorial:-More-Sequencers) where we'll cover some of the other sequencer types. If you would like to learn more about the constants used in this tutorial, what they mean, and what some other choices are, then [you can find out more in the appendix](https://github.com/nw2s/b/wiki/99-Reference:-Constants).

Leave a comment

Please note, comments must be approved before they are published