midibox_sequencer_vx
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
midibox_sequencer_vx [2006/04/06 14:17] – MBSEQv2 CS Prototype Stage stryd_one | midibox_sequencer_vx [2008/09/02 04:08] (current) – removed stryd_one | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== MIDIBox Sequencer vX ====== | ||
- | aka ' | ||
- | |||
- | Some of you will already know about my work on developing a somewhat unusual sequencer... Well, a few recent events have made major changes to the way I can do this, and so I thought that after such a long time, and the recent advances, it might be time to let you guys know what I'm up to - both for your interest, and for the purpose of any feedback that you might give in the form of suggestions or corrections etc... | ||
- | |||
- | Well the latest bit of good news is the PIC18F4620. Now, you may already know that it has a problem with the UART, or EUSART to be precise, and as such has problems with MIDI. This is about the end of the downsides to this chip, and so for the purpose of conversation, | ||
- | |||
- | So anyway, enough background, lets get into the concept. This has changed a bit from the previous incarnations and may change again in the future... But this is how it works for now ;) Forgive me, this will probably be a very, very long post, as I feel I should give some insight into what I've been doing all this time, and I fear that with so many details, that it may be hard to explain well. I will do my best to explain it as clearly as I am able. The project has the working name of MIDIBox Sequencer vX - as in version X I've taken to calling it " | ||
- | |||
- | All that said, there are three major differences between the vX and the current MBSEQ: | ||
- | |||
- | ===== First, the Clock Modules: ===== | ||
- | |||
- | The vX will have a master clock, exactly as the current MBSEQ, nothing new there. TK's clock interpolation algorithm for 24ppqn-> | ||
- | |||
- | One Master Loop, run either by incoming MIDI Clock or internal clocks run by the PIC's timer, has a length measured in MIDI Clock Ticks. The Master Loop Length is the number of MIDI Clock Ticks in one bar at the master time signature, and will be in a table which is looked up for the correct value when the song time signature is set. For eg, the MLL at 4/4 time signature is 384, at 3/4 it is 288, at 7/8 it is 336, at 5/4 it is 480. | ||
- | |||
- | Each clock has a pair (for simplicity of use) of multipliers and dividers. These are represented as N Steps per O Loops and P Steps per Q Loops of the Master Loop. Internally, they will be multiplied and converted to a single numerator and denominator of a master loop. | ||
- | |||
- | O * Q * MLL | ||
- | T = ---------------- | ||
- | N * P | ||
- | |||
- | Where MLL is the Master Loop Length\\ | ||
- | T is the amount of MIDI ticks between this slave clocks ticks.\\ | ||
- | (N*P)/(O*Q) is the steps/loops of the first slave clock\\ | ||
- | |||
- | This will be presented as two fractions, which, for musical clarity, are inverted from the equation above. Some examples: | ||
- | For a common 4 step per bar clock, you setup a clock like this: | ||
- | |||
- | | ||
- | --- --- Per | ||
- | | ||
- | |||
- | The second fraction is ignored as it has the same numerator and denominator, | ||
- | To play a polymeter, you would assign a pattern with more or less steps than this, to this same clock. For example, if you had a pattern with 5 steps (between the start and end point) assigned to this same clock along with a pattern with 4 steps, then every 20 Master Loops, they would sync up. | ||
- | |||
- | To have a 5:4 polyrhythm (five notes play in the same time as 4 notes), you would assign a clock such as the above to a 4 step pattern, and setup the clock assigned to a 5 step pattern clock like so: | ||
- | |||
- | | ||
- | --- --- Per | ||
- | | ||
- | |||
- | Now the two patterns will loop in sync, despite having different lengths, because they are clocked by slaves to the one master loop. | ||
- | |||
- | If you wanted to play 4/4 triplets, you would set the clock parameters like so: | ||
- | |||
- | | ||
- | --- --- Per | ||
- | | ||
- | |||
- | This is the same as 12/1 or 24/2 etc …you can decide which is a more clear representation for your needs, the core takes care of the math. | ||
- | |||
- | Or for 4/4 with a ' | ||
- | |||
- | | ||
- | --- --- Per | ||
- | | ||
- | |||
- | (This is the same as 4 steps per 8 loops or 1 steps/2 loops) | ||
- | |||
- | And so on… you could do weird nonexistent (until now) things like synchronized 7< | ||
- | |||
- | Normally, doing this would mean either clocking externally and wasting IO pins, which can also be slow to drive, or doing a big nasty multiply/ | ||
- | |||
- | This is done by calculating the integer number of ticks required between steps, which is essentially three multiplies (the pair of numerators and the clock resolution, and the pair of denominators) followed by a divide operation which returns the quotient and modulus. The quotient is used as the default number of ticks to count between steps. Where there is a remainder/ | ||
- | |||
- | So… each clock has a set of parameters which it will use to calculate the number of midi clock ticks until the next step. With each 96ppqn tick of the master/MIDI clock, this 'Next Tick Countdown' | ||
- | |||
- | ===== Next, Pattern Modules: ===== | ||
- | |||
- | With the MBSEQ, each track is scanned and the next step is played, if the clock has ticked. The same thing happens with my design, only the tracks check different clocks which are assigned in their parameters. The existing MBSEQ code is so modular, I could easily believe that the concept of multiple clocks was already intended in the current design :) | ||
- | |||
- | Each pattern is a single track of 16 steps, is independent of the other patterns, and can use an independent clock, or share a clock with other tracks. They have independent Loop Start and End Points, can be independently set to Play/ Stop/ Pause/ Record, individually set to loop in different modes, independently set to a different current step, etc. | ||
- | |||
- | Pattern parameters include Pattern Play Sync, which works like this: You make a pattern and you have it triggered to play and step by clock #7. Now, you set the pattern to enter Play Mode after the next tick of clock #3. When you press Play for this pattern, it sits idle, until after clock #3 ticks, when the pattern is triggered to enter play mode. But it will not process and play the first step yet… until clock #7 ticks, because that is the clock which is set to trigger the steps to play. | ||
- | |||
- | Other pattern parameters: | ||
- | Direction: | ||
- | * Forward - Plays from start point to end point | ||
- | * Reverse - Plays from end point to start point\\ | ||
- | |||
- | |||
- | Loop Mode: | ||
- | * Looped - Normal looped play in the above direction | ||
- | * PingPong - Plays forward, reverse, then loops. Can be reversed as above | ||
- | * OneShot - Plays once only in direction above. Stops at end point in forward mode, or at Start point in Reverse mode\\ | ||
- | |||
- | Clock Patch Mode: | ||
- | * Step, | ||
- | * !Trigger, | ||
- | * Trigger, | ||
- | * !Trigger, | ||
- | |||
- | While any pattern can be stepped or triggered regardless of these parameters, patterns set to these modes will need to be stepped/ | ||
- | |||
- | This gives a brief overview of the modular patterns, but so far I have left out one major detail – I hinted that the above parameters, as well as all the other Pattern parameters including parameters for each step, and also all of the Clock parameters, accept input from remote control, but all the parameters can also be from other patterns. How does one pattern modify or trigger a clock or another pattern, I hear you ask?.... | ||
- | |||
- | |||
- | ===== Finally, Step Functions: ===== | ||
- | |||
- | In the vX, a step is no longer just for a MIDI message. Each step contains a parameter which selects a Function to use, and a set of parameters which are passed to the function when it is ' | ||
- | |||
- | This " | ||
- | |||
- | Then, you can do tricky things like having another pattern, which changes step 4's parameters, so that it plays drum fill#1, then next time, it plays drum fill #2, then fill #3, etc etc. It opens up various algorithmic composition possibilities... I hope you can all see where I'm going with this. | ||
- | |||
- | Also, patterns of extended lengths are easily implemented. If you want a pattern 32 steps long, you create two, 16-step patterns, and link them, using a single 2-step pattern… Or 4,8-step patterns, linked by a single 4-step pattern, etc | ||
- | |||
- | All of these examples would require functions which can manipulate tracks in ways such as the examples in the ' | ||
- | |||
- | The functions can also be called externally, so for example, a slider on your midibox could select a pattern by setting the parameter for a given function, and the C4 key could be used to trigger the pattern selected by the slider… Another example is that you could setup keys on your controller keyboard, or trigger pads, that will have a pattern jump to a certain step in the sequence. DJ's reading this who can beat juggle will immediately see the use of a function like this, and those who are familiar with modular sequencers with a step# input will see a similarity also. | ||
- | |||
- | These mappings of external input to internal functions and their parameters could be hardcoded like the functions, or could possibly be included as a set of parameters which would be part of each song… I have not worked on the remote control very much at all just yet. | ||
- | |||
- | |||
- | ===== General Info ===== | ||
- | |||
- | Those of you who have used an analog modular sequencer will probably see a great deal of resemblance between them, and the vX... Only in our case, multiple synced clocks are possible, enabling multipliers and dividers limited only to the resolution of MIDI clock; and the steps can trigger far more complex features than just sending CV out, they can dynamically repatch the entire rack :) | ||
- | |||
- | Similar to the Notron, the vX can pass values generated by functions as a relative number. In these functions, values of 0 to 127 are interpreted as -63 to +64, so 63 is interpreted as a 0. For example, a pattern has a parameter for a " | ||
- | |||
- | For " | ||
- | |||
- | * If the step has a value of 63, it is interpreted as 0. 0 + 63 = 63 = D#4\\ | ||
- | * If the step has a value of 64, it is interpreted as +1. +1 + 63 = 64 = E4\\ | ||
- | * If the step has a value of 62, it is interpreted as -1. -1 + 63 = 62 = D4\\ | ||
- | |||
- | …All " | ||
- | |||
- | * If the step has a value of 63, it is interpreted as 0. 0 + 45 = 45 = A2\\ | ||
- | * If the step has a value of 64, it is interpreted as +1. +1 + 45 = 46 = A# | ||
- | * If the step has a value of 62, it is interpreted as -1. -1 + 45 = 44 = G#2\\ | ||
- | |||
- | I hope to include another feature from the Notron (and about 1000 other algorithmic sequencers) where notes will be locked to a scale. This function would use a table lookup to map note numbers to the scale set in the pattern parameters. | ||
- | |||
- | Similarly, a function could modify a parameter' | ||
- | |||
- | |||
- | ===== Order of Execution ===== | ||
- | |||
- | The order of execution goes like so: | ||
- | |||
- | * Clocks - Have to be a priority for timing to be accurate | ||
- | |||
- | * Patterns: - | ||
- | * Start Sync - So that tracks are started for these other procedures… | ||
- | * Control Functions - So that parameters are modified in time to be read for MIDI Functions | ||
- | * MIDI Functions - Then the notes get sent | ||
- | |||
- | All data is buffered with code based on that within the existing MBSEQ, so all this seems to happen at the same time :) | ||
- | |||
- | * UI - Not so time-sensitive | ||
- | |||
- | |||
- | ===== EUSART ===== | ||
- | |||
- | Previously, I mentioned the PIC18F4620, and it's additional memory allowing for these features to be implemented practically. I also mentioned that there is a EUSART fault (for those who haven' | ||
- | |||
- | |||
- | ===== A Touch of Normalcy ;) ===== | ||
- | |||
- | Despite all of the differences, | ||
- | |||
- | |||
- | ===== User Interface ===== | ||
- | |||
- | The user interface will be reminiscent of the Doepfer Schaltwerk, with buttons for each of the steps arranged in a row for each pattern, and a single large character LCD, jog wheel and slider for fast data entry, buttons, and set of rotary controllers to edit parameters of the selected object. | ||
- | |||
- | There will be a set of buttons which will be used for selecting one of the clocks for configuration using the same LCD. Each button has an LED which flashes when that clock ticks. When a clock is selected for editing, the LED is set on, and flashes off for each tick (The LED is inverted). | ||
- | |||
- | I hope that eventually the grid of buttons for the steps will be arranged in an 8 row x 12 column grid. This will allow for two modes of operation. The first would be one that we are already familiar with, where each row is a pattern and each button within that row representing a step in the sequence. In this mode, there would be left/right buttons which would control which 8 of the 16 steps are displayed, and each row can be freely assigned to any pattern. Pressing a button selects that step, and then you set the parameters for the step | ||
- | |||
- | The second mode would be Grid Edit, where all of the buttons are used to set parameter values for a single pattern. In this mode, each column of buttons represents a single step, and each button in that vertical column represents a separate value for the selected parameter, so the 12 rows become, for example, an octave worth of notes. This is basically like a piano roll, but of course you can only edit one pattern at a time in this manner. When you press a button, it sets the selected parameter (eg Parameter 1, which is used for MIDI Note Number in the 'Send MIDI Note' Function) according to the row. In this mode, there would be left/right buttons which would control which 8 of the (up to) 16 steps are displayed, and pitch up/down buttons to ' | ||
- | |||
- | In the meantime, the User Interface will be driven by PC software… This is just until the core features are all done. I strongly suspect that a UI such as this may require a second core module, which would pass data to the second core, to drive the LCD and DOUTs. This has been discussed previously on the forum, and I am keen to implement it, as moving the control surface onto a second core will relieve the primary core of extra load driving IO. | ||
- | |||
- | |||
- | |||
- | ===== Prototype Implementation ===== | ||
- | |||
- | Implementation will be via a series of prototype stages: | ||
- | |||
- | * Flowcharts and pseudocode (Nothing real, but lots of planning time) | ||
- | * Seq with multiple single-track patterns, one clock (very boring, will mostly be a stripped-down MBSeq v2) | ||
- | * Add multiple clocks (way more interesting) | ||
- | * Add functions (yee hah!) | ||
- | * Remote control | ||
- | * Hardware UI | ||
- | * MBSEQv2 Control Surface Compatibility (So you can run vX app from your MBSEQ CS - although as I said, this is a companion to the MBSEQ, not a replacement) | ||
- | |||
- | |||
- | |||
- | |||
- | I'm sure there' | ||
- | |||
- | **Please share any thoughts or ideas or concerns or criticism or whatever!! :)** | ||