Rack: DISCUSSION: Sequencers missing first step on reset or Rack launch

Created on 2 May 2018  Â·  65Comments  Â·  Source: VCVRack/Rack

This is not a Rack issue, but rather a trigger for a discussion on sequencers in Rack that are affected by this artifact.

The problem: In sum, the problem occurs when we do a global reset of our patch or when we launch Rack in which a sequencer was last running. What happens is that the module gets reset as soon as the reset button is pressed (or reset by Rack on launch); however, the clock generator (LFO, or other) used in the patch sees the reset at the same time as the sequencer, but there are a few samples that go by before the new synched clock is emitted. The sequencer thus sees this as two distinct events: a reset, followed by a clock a few samples later. Hence the step is advanced, and the first step's duration was way too short.

The fix: On module power up and reset, ignore the clock during the first millisecond. This is in fact justified and logical, as having a clock within 1 millisecond of a reset makes no sense and is not what the user is likely trying to do (unless someone is clocking their sequencer at 1 kHz!). It works wonderfully in my modules so far (upcoming 0.6.4 of Impromptu Modular), and when a patch is saved with a running sequencer, it is quite neat to see it play properly on launch of VCV Rack.

This is related to issue #698, and since PulseMatrix is closed source, it was probably not apparent to many as to how the fix was performed (and I'm not sure which technique was used). So just trying to give some visibility to this minor point, and to see if anyone has implemented it differently and to chime in on advantages and disadvantages of different methods.

P.S. A somewhat stretched analogy would be the power-on mute present in many amplifiers and powered speakers. When the amp is turned on, the sound is muted for a second or two, to let the capacitors charge up, and if no mute was performed, turning on the amp would result in a pop in the speakers, which is obviously not a good thing.

Most helpful comment

Hi Marc, I think you are into something here definitely!

Just tried the changes you made to phrase 16 seq, indeed it goes smoothly most of the time, but you can end up with an offset sequence depending on the time a reset is sent to the module. Now, this gave me an idea to try on the master clock side...

I still think this issue could have a better fix via a master start/stop/reset/etc clock provided by rack itself (in a way that all the modules obey and follow that timing or mult/divs of it) but hey, if we can come up with a solid solution I'm in ;)

All 65 comments

Trigger a PulseGenerator on clocks/resets & only accept new clocks/resets when the pulse generator is low.

I had a similar problem in my shift register when clocking from a sequencer: If the path from the sequencer's clock is shorter than the path from the sequencer's CV (if you're passing it through a voltage adder / octave switch, etc.), and you sample the input on rising edge, you will get the previous step's CV value.

Hi Marc, I think you are into something here definitely!

Just tried the changes you made to phrase 16 seq, indeed it goes smoothly most of the time, but you can end up with an offset sequence depending on the time a reset is sent to the module. Now, this gave me an idea to try on the master clock side...

I still think this issue could have a better fix via a master start/stop/reset/etc clock provided by rack itself (in a way that all the modules obey and follow that timing or mult/divs of it) but hey, if we can come up with a solid solution I'm in ;)

Thanks for the feedback Alfredo and Jon. Instead of using PulseGenerator, I instead count the number of steps necessary for 1ms (adjusting for samplerate), which ends up being equivalent. The description of path lengths is on point, as when I was researching a solution and I had only added .reset() to the clock trigger(s) used in my module (when reset is detected), I noticed it helped, but routing the clock through one more module (fundamental mutes is just an example) made the problem re-appear, because of the added sample delay, hence my 1ms idea.

Alfredo, I'd be curious to know more details about this part you mentionned: _but you can end up with an offset sequence depending on the time a reset is sent to the module_. You mean if a reset is sent slightly more than 1ms before a given clock edge?

The master clock idea is interesting, but not sure if it adheres to the design principles behind Rack (which I don't formally know, but I'm taking the liberty of interpreting!), which are probably to be as hands-off as possible and let the modules do the most of the things themselves. If Andrew decides to go with this solution, no problem with me; however it has the drawback of loosing a bit of the intrinsically modular paradigm, but that is just my view.

This idea from Alfredo raises an interesting corolary though: how is this issue handled in the physical modular world? Thanks for the discussion guys!

Marc: I went BPM clock(16ths out) + P16S+stuff to hear the seq, and clicked away the reset button on the clock at random times, more than once P16S ended up playing one step, behind what I had programmed.
I noticed seq-3 sets the step index to be the last when a reset is detected(or something like that), the effect being that the skipped step is the last one, so for the user is like no step was skipped...still a workaround and not a real fix I think.

Btw. the idea I got (on the clock side) was to force the reset switch to trigger in sync with a clock tick and not right when you press it.

I see now why you are getting this behavior: BMP clock does not restart (resync) its clock outputs on a reset. For my tests, I was using Fundamental LFO as a clock source, and when you send a reset to it, it restarts (resyncs) it clock output pulse. Not saying anything should be changed with BMP clock though, but at least it seems to explain the behavior. Thanks for the details!
EDIT: sorry, comment applies only to 16ths output, the others seem to get reset.

Your idea of a synchonous reset is also a cool idea for a solution!

This is good! actually the reset on BPM clock was in sync all fine, but the lfo providing the clock was not being reset too... not sure how or if that affected anything, but one thing less to fix now hehe

I patched up some things you are talking about here and I find that there are many places where this kind of thinking needs more. Thinking. I managed to trick all kindsa behaviours out of various modules depending on timing of resets and first clocks. So it may be a bigger problem, not one I can even ask the questions about let alone answer.

However I can use your help and this seems like it is on topic: how should a clock divider behave? If we assume there are CLK, RESET inputs and, say CLK/2 CLK/4 &c outputs?

One I am looking at:

sets all CLK/ outputs high on reset, irrespective of CLK level. Nothing happens until the first post-RESET rising CLK edge, when CLK/2 goes low. CLK/4 goes low on the 2nd risign CLK. Viewed as a binary number, CLK/16:CLK/8:CLK/4:CLK/2 counts backwards.

Just now I thought to try RESET as an input rather than a button. It appears not to function, so I can't say what happens if you hit both CLK and RESET at once.

I have no idea (haven't looked closely, that is) what my own DIVADA ridiculous clock divider does. TBH I am happy with any clock divider that, well, divided the clock in a macro sense. Details around precise interpretation of CLK and RESET were ignored. By me during development.

So, I have the open space to do "what is right", can you help with the details "real" synthesists would want/expect around CLK edges, RESET and, pursuant to this thread, simultaneous arrival of rising edges or levels on RESET and CLK?

TIA. Off to see what my DIVADA does… [EDIT] OK, it does the same thing, except my RESET input works. This is not surprising since I stole didn't invent the logic I employed. If I hit RESET and CLK, my DIVADA indeed catches that CLK rising edge and CLK/2 is LOW already "off to the races".

alto777

Not sure how to advise here, I'm no expert on clock dividers, but interesting to see that the preoccupation crosses over to those, and on shift registers as also mentioned. The important part I would say is to be aware of it and decide how to handle things in a consistent and documented manner. Perhaps checking AS's BPM clock to compare behaviors, as I believer Alfredo has fixed a slight bug there. Best regards @alto777 !

Thanks for the help. Deciding may be above my creativity level, but consistency and ability to document with precision are not.

Now another area of investigation. I note that RESETs are often caught as edge events (SchmittTrigger), but certain hardware ideas of RESET would more be a level-orientated repsonse - RESET holds down the activity of a module until it goes away. Often a hardware RESET is active low, that is a subtlety. But level or edge is not… I lean towards level, though atypical, just 'cause it seems like you'd want to get everything all settled, so to speak.

Having done some digital hardware design, I have also thought about having level sensitive resets in modular, but from what I can tell so far, I guess edge sensitive is part of the eurorack culture. Very interesting to see how both areas intersect! I also had a leaning toward level sensitive, but perhaps there is a reason for edge that we are not aware of. In any case, like in many areas of life where an established culture is embedded, best to go with the flow! :-)

Yes. It looks like if I ever do a "real" clock divider it will have a few switches on it for flexibility. :-)

I gave a thought about level sensing switches too (also made a module to convert from CV to Trigger, which is essentially a voltage level sensing switch).
Not 100% sure about it, but I think because of how 0v can be a working voltage and not mean absence of voltage as one may infer at first, that's not the standard way vcv rack handles switches.
I'd say, consider sticking to the vcv rack standard, if anything, maybe just to keep things from breaking in the future :)

Oh, I'll figure out a way to break things no matter what.

There are a few modules that use CVs for logic. It looks like SchmittTrigger for edge detection and 0 volts logic low and 5 volts logic high is kinda common. I guess you could go all technical and use, say, TTL or CMOS standard margins in your specified expectations. Nice thing about virtual - no noise! Well, except intentionally produced sound not music!

@MarcBoule - I guess with the level sensitive you are saying you could solve the race by holding the device in reset for "a long time" (several ms.) so that clocks that get slightly delayed are ignored? But what about the case where the clock comes in slightly early? How can one assure that the sequence "clock, delay, reset" is safe? What if that "extra" clock triggers and envelope that then triggers a loud sound? You would hear the extra clock. But at least this would be an improvement. The talk of "barred resets" on FB sounds like a full solution, but difficult to get to (would need a critical mass of modules to do that).

For clocks that come early, I don't think it's a problem since when the sequencer receives a clock pulse, there is no way for it to know that a reset will come in a short time. If someone sends a clock, then after a short delay a reset, what ever the clock just did to advance the sequencer will be moot anyways because of the reset that follows. Hope I understood your comment, these are interesting discussions indeed. I'll have to think more about the barred resets and if/how they relate. Cheers!

"If someone sends a clock, then after a short delay a reset, what ever the clock just did to advance the sequencer will be moot anyways because of the reset that follows" that is where I disagree. What if the clock causes a loud sample to trigger, then the reset does the same? You will get two things playing at once. Sure it will often be fine, but it's not ideal to have, in effect, two clocks in quick succession, leaving it to chance that it will sound like just one. That's why the barred idea is cool - it is "perfect".

From my point of view, in a typical patch, if someone sends their global reset pulse (from AS Triggers for example) simultaneously to their clock and their sequencers, then it is impossible for that reset to hit the sequencer after the newly emitted clock pulse that was just send by the also "resetted" clock. Furthermore, I don't know how one would implement the sequencer not playing a clock pulse when a reset comes shortly after, there seems to be a causality problem with this (unless everything gets delayed in the sequencer, which is probably not ideal). I guess it all depends on the use cases, but it's all good, the purpose of this issue was to get people talking about it :-)

@MarcBoule I think we are agreeing with each other, with a slightly different emphasis? I think we both agree that in theory current reset schemes are slightly ambiguous, and the meaning of a clock and a reset arriving very close to each other is ambiguous. As you note, any attempt to completely disambiguate this situation is doomed to (theoretical) failure (causality issue). I think the difference is that you are claiming (probably correctly) that this ambiguity doesn't cause a problem in the real world, whereas I'm worried about it anyway. Perhaps you are saying that the ambiguity can be reliably avoided if one uses one and only one master clock? I guess I should get out a pencil and paper and try to concoct a semi-realistic patch where this wouldn't work...

Echoing a comment in https://github.com/VCVRack/Fundamental/issues/53, as per AB's suggestion. This shows the issue when patching a global reset with SEQ-3.

With an external clock that has its reset input (aka sync for LFOs) wired to a global reset, and with SEQ-3's reset also wired to this global reset, as shown in the following setup, then there is a problem.
image
In this use case, when the seq is running and it is not on the first step, and pressing the Momentay switch on AS to perform a patch-wide reset, SEQ-3 will always restart on the second step. This is what prompted my whole discussion thread, since my sequencers were doing the same thing. When I figured that I should simply ignore any clock events during the 1st milisecond after receving a reset, which solved the problem in my case, I wanted to share this and was hoping that others would think about such issues. I found it unreasonable to accept a clock event so close to a reset, and I adopted the strategy of declaring this a parasitic clock event given routing delays though modules. Not saying I have the perfect solution and that other seqs should do the same, but just wanted to shine some light on this topic.

One could also argue that it is up to the user to be aware of routing delays through modules, and in my above use case, if we simply route the reset signal through a dummy module, then everything works perfectly:
image
I just think that since the fix I proposed is quite simple, and especially if it avoids users saying that our seqs are not working properly, then in my case implementing the 1ms-clock-ignore-after-reset approach is a no-brainer! :-)

That sounds like a good heuristic. And does it then matter if the reset is level sensitive or edge sensitive? Obviously it does, so would you also recommend that the reset always be level sensitive?

Well from what I have seen (very informally, I didn't do a detailed survey), resets tend to mostly be edge sensitive in Rack. From the way I see it, in the module itself it wouldn't matter really regarding the 1ms clock ignore, since with a level sensitive reset, the device is continually held in reset while the level is high, and upon releasing the reset we would ignore clocks for 1ms afterwards.

In a scenario where some devices are level sensitive and others are edge sensitive though, these differences would introduce timing offsets and it might get at bit messy.

I've been thinking of making a sequencer with a high speed "MIDI style" clock. As you probably know those clocks tend to run at at least 96 X BMP. But at those high rates none of these solutions really work. Perhaps I'll keep the external clock slow and multiply it up like in "Chopper" (our tremolo with clock in).

nord g2 sync
In a discussion on the FB Group about this, I posted info on how Nord Modular handles this. Their sequencers have a special Reset input that prepares the sequencer to reset to the beginning but doesn't actually commit the Reset until the next Clock input signal. This technique, in combination with the Main Clock module's "Sync" output, which sends a Pulse every 'X' number of beats, makes it easy to synchronize sequencers (and other sync-relevant modules), either internally or in response to incoming MIDI Clock (Song Position Pointer).

Interesting method!

Yes, the original post about nord modular got me going down this rabbit hole in the first place. If we wanted to implement this (reset on next clock), I guess it would need to be a separate "mode"? We could really use a VCV spec for how reset should work!

The Nord distinguishes between the two Reset modes graphically.
screen shot 2018-07-27 at 6 12 40 pm

Hi All! This is my first post. Please go gentle on me. First, I want to thank EVERYONE that is bringing VCV Rack to life by contributing their own work into the VCV Rack system and for VCV Rack in the first place. I will be thanking with money as I can.
I've been noticing what seems like an implementation issue occurring and searched for 'reset" and got this thread. I read through to the bottom and didn't see a resolution. I see this when I do a global reset with different sequencers, LFOs, etc., that everything doesn't start in sync. It does seem that there is variation in how different modules handle a reset. That is, what triggers a reset and then what's the first thing that happens right after it. I was using RJ Modules Button for a global reset. I've now been using AS Triggers Mk III to see if that would help and it didn't. I then tried adding Alikins Gate Length after the trigger to see if it was pulse-length related. From all of this I came to the conclusion that different developers are handling resets differently and it seems like there needs to be an agreement on how modules first detect a reset and then what's the first thing they do right afterwards.
For the life of me, I can't get all sequencers to be in sync.
Am I doing something wrong? I don't believe I am, but I sure can be overlooking something fundamental.

Hi Mike, welcome to the group! For a solution, since this is an open platform and everyone is free to code their modules as they wish, it may not be easy to get a standard going, but in my case I did propose a solution (see top-most post) and I did implement it in all my Impromptu Modular sequencers, and it seems to do the trick. Cheers!

Thank you! I will check out what you're referring to. I've not done
software development in an open sourced environment. Interface standards
are hard enough with a large team, I would think it would be almost
critical in open source. I'm not here to complain, just a little
surprised, that's all.

Thank you again for the work you do on your modules!

Mike

On Tue, Oct 23, 2018 at 5:44 AM Marc Boulé notifications@github.com wrote:

Hi Mike, welcome to the group! For a solution, since this is an open
platform and everyone is free to code their modules as they wish, it may
not be easy to get a standard going, but in my case I did propose a
solution (see top-most post) and I did implement it in all my Impromptu
Modular sequencers, and it seems to do the trick. Cheers!

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/VCVRack/Rack/issues/938#issuecomment-432230912, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AORDNPD0PTmk8mN-ogKk25H05wM0rLC8ks5unw8cgaJpZM4Tvj9Z
.

@MarcBoule Do you know if anyone has implemented the Nord protocol (mentioned above) in a VCV module? I'm seriously considering implementing yours (to be pragmatic) as well as an option for Nord Delayed RST (since it is to me the "best" proposal).

Not sure anyone has done the Nord method, and although it is a good idea, one very minor drawback I see would be that when the clocks are turned off, sending a reset pulse would indeed have no visible effect, which would look weird. Imagine you stop your master clock, then hit reset to reposition everything, and nothing moves since it only happens on the next clock, which may be in a few minutes when we're ready to start up our master clock again. Not a major point though, and since my solution does the trick for me and the use cases I see most, I did not bother to do the Nord option as well (it could eventually be added in the right-click menu as an option though, if that became more widespread in VCV Rack). Cheers!

There is a related discussion in the VCV Rack forum; referencing here for those interested:
https://community.vcvrack.com/t/impromptu-clocked-coming-changes-and-call-for-discussion/1229

Thanks! Great discussion and I'm happy to hear a standard is developing.
This will certainly help with my sequencer issues :)
Mike

On Sun, Jan 13, 2019 at 6:00 PM Marc Boulé notifications@github.com wrote:

There is a related discussion in the VCV Rack forum; referencing here for
those interested:

https://community.vcvrack.com/t/impromptu-clocked-coming-changes-and-call-for-discussion/1229

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/VCVRack/Rack/issues/938#issuecomment-453886792, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AORDNIMh71a2upazdhYbhVTuSMqlX5s6ks5vC-S4gaJpZM4Tvj9Z
.

Okay, I declare the following to be the standard for all modules with a CLOCK and RESET input (sequencers, sequential switches, clock dividers/multipliers, and other clock utilities).

  • When the CLOCK is triggered, do not advance the state of the module if RESET has been triggered less than 1ms ago.

Thanks Andrew.
In order for this standard to be more visible to devs, would it be possible to also add it to the manual at
https://vcvrack.com/manual/VoltageStandards.html
and perhaps rename the page to simply "Standards" or something more general?

Not sure I follow your points Jim. This standard does not address run inputs that we have on our sequencers, nor general clock behaviors, just one behavior in particular where a clock arrives too soon after the reset which leads to a missed step in most sequencers. For those that have implemented the "reset moves to last step" approach , then a change may be required, but in my humble opinion, it would be for the best since resetting to the last step in the last pattern is really not ideal.

EDIT: actually, in thinking through this again, perhaps nothing needs to actually be changed in "reset moves to last step" sequencers, since if they worked properly before, they will work properly now since nothing fundamentally has changed in Rack's core, it concerns only the modules themselves.

@MarcBoule Updated at https://vcvrack.com/manual/VoltageStandards.html#timing

@Rcomian It directly addresses and solves the issue in the original post. If you have a similar issue, start a new thread with a clear problem description. I don't understand the problem in your post.

@Rcomian If you're talking about https://community.vcvrack.com/t/impromptu-clocked-coming-changes-and-call-for-discussion/1229/20?u=vortico, this is normal behavior for modular sequencers, in the Buchla, Serge, Eurorack, Moog, etc standards. If you reset a sequencer with a pulse or button on the panel, the first LED will shine, indicating that the sequencer is in position 1. Send another clock and the sequencer will be in position 2. This is how most users, including ones entirely new to modular, will assume they work.

This "problem" is solved by changing your mindset about how modular sequencers work. I think the point of confusion is that in modular, nothing stops, so you shouldn't attempt to "stop and prepare" your patch to be started when the clock starts coming in. Clocks and sequencers should always be running, just like how oscillators never stop internally generating sound.

If you have more than one sequencer in your patch, it's useful to reset everything to be in sync once in a while, which is why a big push-button module that generates a gate is useful, as it effectively presses the RESET button of all sequencers at once.

@Rcomian In my minimal 3 module example in the forum post, and in my initial post above, we are not addressing run signals nor specific clock modules and their run switches. That is a problem also, and I currently solve it by also ignoring clocks that happen within 1ms of run being turned on, but this has a weakness that we can explore in another place and time if you want (my pleasure to discuss this, since it is important). For now though, ignoring clocks 1ms after a reset solves one important issue, which actually happens with sequential switches too. They don't have run inputs, but clearly something needed to be done. Witness another example of related discussions : https://github.com/VCVRack/Fundamental/issues/53

I don't follow you on this part:

this implies that the run output of a clock must be attached to the reset input of a sequencer. This means it becomes impossible to simply stop a sequence and then continue where we left off.

Since the last changed to Clocked that came after a very welcome issue you made on my github, we can now do precisely what you mention above (stop a seq and continue it where it left off), and I do implement the _1ms-clock-ignore-after-reset_ standard. But in order for the stop/start behavior described above to work, I also have to implement a _1ms-clock-ignore-after-run_ approach (which has no internal connections to reset, and may in fact be the source of the confusion).

So to summarize, Andrew has decided on the _1ms-clock-ignore-after-reset_, but nothing has been decided for the _1ms-clock-ignore-after-run_. I do implement the run version also, and the start stop of any Impromptu sequencer that has a run input and switch does work.

@AndrewBelt Very interesting comment and it shows why some sequencers like the ER101 don't have a run input. It's so very interesting to compare both paradigms: in hardware everything is running by default as you say, but the start/stop is inherently part of DAWs. In Rack, we have a mixing of worlds, so to speak, and the issue above with the RUN connections is precisely in that intersection, thus perhaps why it is not obvious.

Since perhaps RUN states will be unavoidable in Rack, we will need a discussion there also, which will intrinsically be related to clocks also (since clocks are often the source of the run trigger), but that can be for another github issue.

Incidentally, I personally don't like the idea of periodic resets mid patch (as we saw in the 9 minute Eurorack video I posted in the forum), because with a very long multi-pattern sequence, it will just reset back to the beginning of the song and the song will never play to the end. For short songs, that is fine, but with Foundry and PianoRoll, we can have complete 5 minute songs in there that don't repeat :-)

1ms-clock-ignore-after-run doesn't work because if the CLOCK trigger is received a few samples before the RUN trigger, the result will be a sequencer at step 2. In other words, this solution is not slight delta delay between pulses due to the way you set up your signal chain-invariant.
The reason 1ms-clock-ignore-after-reset works, is because the result is the same regardless of whether CLOCK is received shortly before, during, or after RESET.

I'm only an observer here, with minimal knowledge about the implications of this problem. I mentioned the Nord system a while ago, and I just wanted to mention this now, in case it triggers any new ideas. In addition to the way the Nord handles resets, it also features a "Sync" function when using its primary clock module. The Sync output, programmable to send a Reset every 4, 8, 16, or 32 beats, patched into all relevant Reset inputs ensures that when the whole system is put into play mode, the various clocked modules will not be OUT of sync for any longer than the count of one cycle of the Sync setting.

Ok, looks like RUN as we have it now is problematic then. Thinking out loud, perhaps the master clock should be the only one to have a RUN button, and sequencers should simply always be in a running state and there should be no RUN cables going through the patch.

In order for this no-run-cables approach to work, when resetting a stopped clock, it would have to rail its clock outputs high, so that if we start the clock more than 1ms after the reset (thus too late for the reset-ignore), then no spurious clock pulse would be seen by the (always running) sequencer.

Such an approach, if feasible, would actually simplify things immensely. I have seen both very experienced Rackheads (which will remain nameless!) and beginners struggle with the RUN (i.e. forget to connect it), and if it can be removed from all my sequencers, I will be tremendously happy to do it.

@cmountvpr I have a comment not too far up above about the periodic reset approach, and I believe it is incompatible with larger pattern sequencers such as the PhraseSequencers and PianoRoll, since if we set up a long 5 minute song, it will trash our song.

The NORD delayed reset method is also problematic in my view, since when a patch has different sequencers running at different clock rates, a delayed reset will happen much sooner on those sequencers with a fast clock than those with a slow clock, thus throwing the patch out of sync @nysthi

Thanks Marc, I've read the whole thread more carefully now. :)

perhaps the master clock should be the only one to have a RUN button

That's fine. RUN on a sequencer really just means "mute the CLOCK trigger input". I personally don't use that feature (I always have my sequencers running), but others like the option, so we included it in Pulse Matrix and SEQ-3.

Indeed, in thinking more, I would probably remove the jack, but leave the RUN button (or invert its behavior and call it Freeze, like on the ER101), since it can be useful musically (stop and hold a bassline or whatever, while other stuff continues to play).
EDIT: Hmm, but then users would want a CV input for freeze :-) Ok, perhps simplest to have button and jack, and like in PulseMatrix, have it running by default.

@AndrewBelt How do you feel about Clock generators railing their ouputs high on reset (when they are not running)?

@cmountvpr I have a comment not too far up above about the periodic reset approach, and I believe it is incompatible with larger pattern sequencers such as the PhraseSequencers and PianoRoll, since if we set up a long 5 minute song, it will trash our song.

The NORD delayed reset method is also problematic in my view, since when a patch has different sequencers running at different clock rates, a delayed reset will happen much sooner on those sequencers with a fast clock than those with a slow clock, thus throwing the patch out of sync @nysthi

I expect a reset to be sent to all the clock sources: a reset for me is start as it was the first time (given the current pattern, or song)

All good Antonio, still trying to fully understand the NORD method for completeness. So if reset is sent to all clock sources also, we are counting on the fact that reset will get to the sequencer first, and then when the newly resetted clock edge hits the sequencer a sample or so later, then it will go back to the first step for everyone. What I don't understand though, is if we hit reset when the running clock is high, wouldn't the following case be problematic?

  • hit reset when a clock is high
  • the seq and clock see the reset simultaneously
  • the seq sees this as a request for a delayed reset
  • the clock sees this and resets its output; but since the output was already high, and it now gets reset high since it's starting its new reseted pulse, the seq will have to wait for the next clock to do its reset, but this may come much later if it is a /64 clock.

I guess the delayed reset is still bit weird for me.

Oh wait, we should deprecate the old standard already and do it this way.

When the CLOCK is triggered, do not advance the state of the module if RESET is HIGH.

Thoughts?

At first thought I like the new proposed standard because it's a very clean and simple statement, and it alleviates the modules from having to count the 1ms delay in the current standard (not that this is hard to do, but still, it would be one less thing to implement).

But perhaps there would be an undesirable side effect in the new proposal in cases where a reset button does not emit a 1ms pulse but instead keeps its output high for as long as the button is kept pressed. I assume this would be a valid way to implement a reset button also, and if we hold this type of button long enough and release it right when a clock edge is about to happen, then perhaps with signal delays in cables and modules, some sequencers will see the reset go back down after the clock edge and others will see it go down before the clock edge, thus the clock will have been counted for some modules but not others, thereby desynchronizing the patch. In my example I assume that a clock generator is reset/restarted on the rising edge of the reset, and that the clock is not held in a reset state while reset is kept high (whether it's a reset that is given to it, or its own reset button if it has one).

The advantage of the 1ms-clock-ignore is that we use a short enough time such that we guarantee no modules are missing any proper clocks within this timeframe, since they are inherently declared as being too fast given our 1kHz limit.

Since resets can come from a bunch of places (slow LFO, a midi level from an external device, etc.), we probably can't declare that reset pulses should be 1ms in duration either. Just trying to see any limitations in the new proposal. If the new method is deemed robust enough, I'd go for the new version no problem.

if we hold this type of button long enough and release it right when a clock edge is about to happen...

When using a manual button module for the reset gate, this would happen equally as often with the 1ms-after-reset rule, so this is an invalid point.

What is a valid point is that reset "signals" can be as artibrary as possible. If using a Eurorack module through Core AUDIO to reset a sequencer, it might look like a bandlimited delta function. On the other hand, if this is as crazy as they get, those things last a few samples so it would still work...

When using a manual button module for the reset gate, this would happen equally as often with the 1ms-after-reset rule, so this is an invalid point.

Not sure I follow you here, but perhaps it's because of the way I chose to implement the 1ms-clock-ignore-after-reset. I don't know how others implement reset, but in my case (Clocked and Sequencers) I detect only the rising edge of the reset signal and on that precise event (SchmittTrigger), I do a reset in my modules and also start the 1ms counters in the case of sequencers. So if the user keeps reset high for 10 minutes after that edge, it changes nothing the way I see it at least, and the point I raised might still be a concern in my view.

I agree that if there is a free running clock in Rack that does not get reset while this other manual (or external) reset happens, then yes, after 1ms there could very well be a clock edge nearby for which routing delays would mess up the sync of the patch, and so there would be a problem also in the 1ms approach (which is impossible to solve actually). But in cases where the clock gets reset on the rising edge of reset (and provided it's not continually held in a reset state while the reset it high), then the 1ms would still be more robust the way I see it.

Just for the recored, I actually would prefer the new standard you are proposing, I'm just trying to push arguments further so that we get a better picture of any possible side effects we may be overlooking.

Here's the issue

some sequencers will see the reset go back down after the [falling] clock edge and others will see it go down before the [falling] clock edge

So there's an event at t that marks the beginning of when clocks are allowed to advance your sequencer. It doesn't matter when the event is t_rising + 1ms or t_falling, the above quoted text will still apply.

the above quoted text will still apply.

I'll have to disagree, sorry :-), because in the 1ms version of the standard, if the clock was reset also, and this clock rate is lower than 1kHz, then it's impossible for there to be a new clock edge that some seqs will see and others will not see.

Here is my summary of the discussion and why I still see a problem:

  • The user presses the reset button and holds it for 1000ms
  • A 300 BPM clock (5 Hz) sees the reset at _t_rising_ and restarts itself on that edge
  • New clock edges are emitted starting at _t_rising_ and continue to occur periodically every 200ms after that
  • With the 1ms standard, another clock edge at _t_rising + 1ms_ is impossible (or deemed inavlid)
  • With the revised standard, another clock edge at _t_rising + 1000ms_ is possible, and thus problematic

Apologies if I am not understanding something central to the discussion, and thanks for your patience Andrew.

Oh I see. You've patched the button signal into the clock RESET input as well.

But if your clock generator module has a RESET input, it must follow the standard too.

So upon t_rising, the clock generator should emit a 1ms pulse but should not be allowed to phase-accumulate after that. So when RESET goes LOW (which could be 7 hours later), the next clock will be emitted 200ms later.

So the language of the standard could be something like

All modules with a RESET input must reset their state upon receiving the trigger and not advance their state (by not phase-accumulating, by ignoring incoming clock triggers, etc) until RESET is LOW.

However, the 1ms rule is still fine, but I believe this one could work too.

EDIT: this comment is a reply to the one that is two up from this one.

But if your clock generator module has a RESET input, it must follow the standard too.

I would say that the standard does not generally apply to clock generators since only a minority actually have a clock input. So I would think that a clock gen would restart as soon as possible when seeing the reset edge.

Now for clock generators that have a clock sync input, or even a clock divider/multiplier, we would have to see if/how it would make sense to apply the standard to those.

So upon t_rising, the clock generator should emit a 1ms pulse but should not be allowed to phase-accumulate after that.

I guess that would be one way of doing it, but it now seems to be much messier than the original standard, namely, a clock generator will emit various type of pulses. Imagine it's setup in 50% pw mode, there would be a weird 1ms pulse and when reset is released, and then a normal LFO like clock signal afterwards.

All modules with a RESET input must reset their state upon receiving the trigger and not advance their state (by not phase-accumulating, by ignoring incoming clock triggers, etc) until RESET is LOW.

However, the 1ms rule is still fine, but I believe this one could work too.

Agreed. It does now make it behave more like a _level_-sensitive reset though, as opposed to an _edge_-sensitive reset, but I can buy that.

So in light of this new proposal two comments up from this one, I should then modify Clocked so that after setting up its outputs as a result of the edge part of the reset, it will hold them like that as long as reset is high (as opposed to start running immediately).

Ok, I will try implementing your latest proposal in Clocked and in all my sequencers, and in the process of doing this, if I come across a corner case we overlooked, I will mention it here in a followup, but at first sight it looks very good to me.

I'll assume we're going with the last proposal though, and for reasons of coherence and simplicity, I would even suggest that the 1ms version be retired, in order for behaviors to be consistent across modules. If both versions of the standard were to be deemed acceptable, then we will have precisely the problems we are trying to avoid in the first place! :-)

Still haven't decided. Currently the 1ms rule is the only standard.

Ok, all good, I won't make any changes until a decision is made.

Oh, another part of the discussion that we need to remember is what happens on Rack launch. I don't know if I made this clear in the latter portion of this thread, but for me the 1ms-clock-ignore-on-reset also applies to power-up, which I treat as an implicit reset. This is needed so that when things load up in Rack and the engine starts, if a sequencer's clock input interprets the initial high state of an LFO's output as a clock edge (because output[].value are initially 0.f), then when powering up Rack the sequencer will unfortunately start at step 2. (An LFO was used as the clock generator in this example.)

Since there is not necessarily a reset pulse coming into the module's reset port on power-up, the new proposal above might not work as there is no high reset signal to instruct the module to ignore clock edges.

EDIT: unrelated to comment above, but I don't want to spam this thread, so I'll append some interesting refecences here. They are not meant to try to steer the discussion in any direction in particular, as personally the 1ms rule above suits me perfectly.

VPME - Euclidean Circles (video referenced by Steve Baker). Starting at 6:40, we see that the developper of this module also seems to ignore all clocks it receives a very short time after reset.

https://www.youtube.com/watch?v=v-UzD3jvM80

Doepfer - A160 Clock divider (from modulargrid):

The A-160 also has a reset input. Whenever a reset signal is sensed, all outputs are set to zero, until the reset voltage disappears.

Shakmat - Clock O' Pawn (video referenced by Steve Baker). Starting at 6:45, the author seems to implement the Nord delayed reset approach, with a slight delay on the clock outputs such that after a reset, a clock happens quickly to reset everything to the first step.

https://www.youtube.com/watch?v=5ShDpU_88xY

It seems like we resolved this issue with the 1ms rule. Reopen if issue is still present.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Coirt picture Coirt  Â·  7Comments

jonheal picture jonheal  Â·  4Comments

gogobanziibaby picture gogobanziibaby  Â·  4Comments

ryan-allen picture ryan-allen  Â·  5Comments

vogelscheiss picture vogelscheiss  Â·  5Comments