Development has been demonstrated in Zynthian Club. . . . .
Someone keeps posting while we talk
Someone has to handle the PR ! we should put the step sequencer screens up here for review!
I gave a sneak preview in Zynthian Club to something I have been working on for the past few days.
This is a (partially) functional wire-frame for a step sequencer. It provides a grid of notes / steps. You can change the grid size to have more or fewer steps in the pattern. Each step may have any quantity of notes, each at its own velocity. Velocity is indicated by the opacity of the cell, darker cells being louder. The SELECT rotary encoder moves the selector left / right through steps and the SNAPSHOT encoder moves the selector up / down through notes. The SELECT button push will add or remove a note. The grid scrolls if you move up or down beyond the display. All steps are always shown horizontally, i.e. there may be 32 narrow columns for a 32 step pattern or 4 wide columns for a 4 step pattern. Touch / mouse also works. Touching or clicking on a cell will add or remove a note and dragging the piano-roll will scroll vertically. The top right shows a kind of menu. Rotation of LAYER encoder will select the menu. Short press of LAYER button will allow entry of a value with LAYER encoder changing the value, e.g. the input velocity level or quantity of step in a pattern. Options are:
- Select pattern
- Set input velocity
- Change quantity of steps
- Copy pattern
- Clear pattern
- Set MIDI channel
- Change transport mode (start / continue).
A short press of the SNAPSHOT button will start or stop the playback looping. Playback is indicated by a cursor moving along the bottom aligned with the currently playing step. Playback tempo is driven by MIDI clock, currently relying on an external clock source. MIDI start, stop and continue are recognised.
- This is just a proof of concept to demonstrate what can be done within the Zynthian GUI / controls. It is currently written entirely in Python and is not performant. (Some x-runs and missed notes.) I may (probably will) need to write the sequencer part in a lower level language, e.g. C.
- Only the pattern editor is currently implemented. Song editor needs to be added.
- Note length is fixed to one step period. The plan is to allow variable duration notes by pressing the top left button to start the note and top right to end it.
- Auto routing not yet implemented. I hard coded the output to the Zynthian MIDI input and the clock input to a specific USB MIDI device.
- No internal clock source. Need to add the option to run from an internal or external clock source.
- Does not respond to MIDI note input, i.e. cannot add notes from external keyboard.
Cannot add or delete patterns. The code is there to save and load from file but not to create or delete patterns.Fixed in commits 0639d98…80fe30c
I quite like it. I have been considering this for a while but we kept looking at options then not implementing them so I decided to have a bash - how hard could it be? Let me know what you think.
Awesome to see a native Zynthian sequencer being worked on!
Just something to think about: have you considered going beyond a strict step-based sequencer?
What Pyramid roughly does, it stores the notes internally in free offsets (plain old MIDI type-0/1 files), and the step grid is merely an UI view into that data. A zooming level is then used to handle the currently viewed detail level. That allows much more flexibility across the board, including but not limited to preserving + editing of a live recordings etc.
FWIW, the Pyramid UI is also an interesting study into how little you can get by with: the Zynthian screen is huge compared to that (although much of the Pyramid UI is in the big backlit buttons)
I took a quick look at Pyramid today after @Simon said he had just bought one. It looks interesting and did give me some ideas. At this stage I am planning just an old school step sequencer with a few enhancements so note start quantized to step boundaries. I would quite like to get this working and see how it works from a user workflow view before considering more complex implementation. The underlying data storage would need to be different to what I am currently doing for a free offset implementation. Let’s see how it looks and feels with fixed quantization before considering such an enhancement. (I am keeping my project manager hat on and avoiding letting the inner geek go off on a foray into scope creep .)
Keep It Simple
As long as it’s accurate, the bells and whistles can come later.
Sure, wanting to keep it simple for starters perfectly understood. Just wanted to bring the point up for consideration early because fundamental design changes become much harder later on.
I’m a Pyramid user for some 2.5 years, if you want to know how something is done there, feel free to ask. There are some clever things in there but also some "oh please don’t"s
May have to pick your brains some time - I’m completely new to it
@riban, i just tested your step sequencer and have to say that … Woaoooo!! i really like the concept. It’s a great proof of concept … so we have to implement the real thing. Yesssss!
I used jack-midi-clock and Jack transport for generating an internal clock and it worked like a charm.
The demo works quite well. Pattern editing is quite easy, and pattern options also works OK: MIDI-channel, velocity, pattern, steps,… As you say, tempo is not totally stable and some events got lost. Nothing serious we can not solve
The more important part is the UI, that i find very easy to learn. Of course, i would change some “details” to be more coherent with the rest of Zynthian UI. This is my proposal for the current functionality:
- XY cursors in the 2 bottom encoders (back & select)
- add/remove note on short-select
- note options on bold-select (velocity, duration)
- pattern options on short-snapshot, similarly to what you have now:
- short-snapshot for play/stop
- bold-snapshot for menu select
- rotation for selecting menu option or value.
Regarding the “pattern menu”:
- A clean-all option
- I will love to have some kind of divisor/structure parameter for adding visual marks that ease pattern edition when you want to go beyond the 4/4. For instance, having 24 steps divided in 8 groups of 3 notes.
Of course, this could change when song editor is defined. And we also need a BPM control for the internal clock, etc.
Regarding the implementation, from my POW, C/C++ is the way to go for the sequencing engine … a funny task!!!
Congratulations and thanks a lot!!
can we test it too, please? maybe save me a bit of soldering
It’s available for everybody. You only have to change the branch for your zynthian-ui repository, from the webconf.
After that, the StepSquencer will be on your main menu, under Auto-EQ (I think you should move it one step up, @riban)
I followed these steps:
Install and run jack-midi-clock like that:
apt install jack-midi-clock jack-midi-clock &
jack_connect zynthstep:output ZynMidiRouter:seq_in jack_connect jack_midi_clock:mclk_out zynthstep:input
Finally, you can use jack_transport for start rolling and control the midi-clock tempo:
Type help fro having a list of commands …
Ahhh! Remember to have your zynthian in Multitimbric mode (i.e. single channel mode disabled!!) for using the StepSequencer’s MIDI-channel option …
Also, it is currently loading and saving patterns at /zynthian/zynthian-my-data/sequences/patterns.json and my not create the file / folder automatically. The reason I had not advertised more widely is because some issues need resolving before it is easy to install / enable. I will try to resolve those over next few days so that you can all enjoy and feedback.
Thanks for the kind words and useful feedback. I am aware that I cut some corners to get this working, including pretty much ignoring the Zynthian GUI style guide. (Is there one??? )
I too feel the top knobs don’t feel right but there is a workflow based reason for choosing them. I intend to allow variable length notes to be entered and the plan is to press one button to start the note and another button to end it. Why two buttons? This allows the second button to be used to create short notes / drum beats without having to press twice on each cell. Using the bottom two buttons for this interferes with the common use of BACK. I also want to keep the main workflow on two knobs, i.e. advancing steps and entering notes should use the same knob. I feel it more intuitive and ergonomic to use two buttons for this rather than:
- Short press to enter note
- Bold press to adjust note
- Twiddle to select adjustment, e.g. duration
- Some other twiddle (another knob?) to make that adjustment
- Short press to stop editing
I have seen a similar workflow elsewhere but I am not sure it is best workflow - however, I can see it might work with a bit of change, i.e. using different knobs for part of the workflow. I will play and come back with some options.
Clean all: Good idea, I will addimplemented in 0da9e2a…8ece73e
- Grid lines: I had considered horizontal grid lines to show white / black notes but consensus within my small focus group suggested this would add undue clutter. Vertical grid lines requires the concept of beats and bars which I was trying to avoid to allow freedom in mind for creativity. I have too often been constrained by the concept of beats and bars and wanted a more loose implementation. I will add a menu option to add vertical delimitation of columns at configurable separation… but maybe not today!
- Tempo: I plan to add a control of internal clock to give tempo adjustment. I need to use it a bit to figure out how prominent this control should be. It may get its own knob or be part of the menu.
Also on my list are:
- Play forward / back / random
- Playback rate /2, /4, /8…
- Scales / drum maps (remove rows, change pianoroll)
Copy patternsimplemented in 0da9e2a…8ece73e
- Inherit and implement Zynthian GUI style, including colours and title bar widgets
- Incorporate into Zynthian snapshots - I was considering whether each set of patterns be saved with snapshots and how songs tie in with that? Thoughts please.
The current implementation is very much fixed steps with each step having a list of notes to play or stop. When I migrate the play engine to a lower level language I may implement @pmatilai’s idea of giving each note a start and duration allowing more complex manipulation of patterns in the future - we will see.
My current goal is to implement a simple, old-school step sequencer with patterns and songs (which use those patterns) which is simple and intuitive to use but extensible to allow future enhancements.
Ramp up ramp down * octave range would give you a powerful arpegiator type functionality.
From keyboard is an obvious implementation but should have some screen space to demonstrate it’s on and how far you are transposed at the moment.
There are differing schools of thought to my mind, and they represent different organisational approaches.
1/ the person who treats a sequence as something entirely tied to a set of layers., and doesn’t want the possibility that they will change. Live stage sequencing where you need to know it will play exactly as you want, possibly without a preview of any kind.
2/ The person who would want a group of tracks to remain locked but would want the ability to easily change specific tracks to search for different interpretations. ( good for the Piano comparison pack …)
3/ Those who have a different orchestra like layers with some overall structure (Piano on One, strings on two etc) show would want the sequence to be easily moveable between different orchestra structures ( arrangers and such like)
4/ Completely free form anything to anywhere where the sequence has no locking to layers and would consider itself a component of the MIDI universe not the Layer world ( The DJ community ?).
Presumably, the first couple will need to check that the layers they expect to see are actually present so there could be an indication for both those states, perhaps that could be a default and the lack of the needed patches ( hashing) could drop it into one or two other less stringent modes.
The ability to transfer sequences around separately from layers would seem useful for the more free form implementations, and presumably, this would be exported as standard MIDI files, with the snapshot linking being another file that would be indicated in the sequence list. So that from a snapshot loading point of view you would load up any sequences that use those specific layers and indicate their presence, and from the purely MIDI point of view you show a list of sequences with states indicated for what is available. If this sequence list could be the same for both layer selection & MIDI selection that would, at least, te things together logically.
Looking to sell: Squarp Pyramid, only 5 days old
Just a couple of remarks/ideas on the topic:
On the Pyramid the note duration (and velocity) is pre-determined so all note lengths are equally fast to enter with a single click. Ie if you’re entering 1/16 notes you change the length to that and then add the notes, and when you need something else you just change the length. In this scenario the duration would be an encoder of its own, and single click to select adds/removes (or something like that)
Another way to set duration using just one button with one click could be defining length by rotating the encoder while pressed. I don’t actually know if Zynthian encoders support that, but that technicue is used for various tasks on Pyramid.
How easy would it be, at this stage, to offer the keyboard horizontally as well for piano roll like operation?
Many people use that particular form of presentation to learn.
Easy. Just one boolean variable.
I see the issue, that it’s not display only but the controls need to be differently assigned as well.
I wouldn’t do both.
Hi @pmatilai, I just came to a similar idea. Similar to how the velocity is currently set and used for new notes and existing notes can have velocity changed by selecting them - I can do same with duration, i.e. set the duration and all new notes have that duration then select an existing note and change duration. I will do this. I had envisaged a type of paint notes approach used by DAWs but actually the step sequencer approach works fine. This also allows @jofemodo’s suggestion of using bottom row of encoders. I will make it so!