Change tempo to be in beats per minute#1
Conversation
If you are changing the divisions you could get into a situation where the current step is out of bounds.
| function setSequence(division, sequence) { | ||
| if (typeof division !== 'number') throw new TypeError('Division must be a number'); | ||
| if (!(sequence instanceof Array)) throw new TypeError('Sequence must be an array'); | ||
| if (sequence && !(sequence instanceof Array)) throw new TypeError('Sequence must be an array'); |
There was a problem hiding this comment.
While you're here, let's change sequence instanceof Array to Array.isArray(sequence).
| } | ||
|
|
||
| function advance() { | ||
| if (this.step >= this.division) this.step = 0; |
There was a problem hiding this comment.
Good catch, I think this makes more sense as well.
Though, I think this should be:
if (this.step >= this.sequence.length) this.step = 0;There was a problem hiding this comment.
Well, I am working under the assumption that the sequence can be empty because that's the way I have been using this. If we init it the way you describe below then it's different.
| function calcTimeout(tempo, division) { | ||
| return Math.floor((60 / tempo * division) * 10e8) + 'n'; | ||
| function calcTimeout(tempo) { | ||
| return Math.floor((60 / tempo) * 10e8) + 'n'; |
There was a problem hiding this comment.
The way I had it initially, you could have multiple subdivisions per beat, i.e. you could say the tempo is 120, and the division is 4, and you would get 4 emits per beat. This is useful if you want eighth, sixteenth, half notes, etc.
This new way only emits once per beat. I guess you could change the tempo to get the effect of having subdivisions, but I would prefer to have subdivisions.
Thoughts?
index.js
Outdated
| this.division = division; | ||
| this.sequence = sequence; | ||
| this.timeout = calcTimeout(this.tempo, this.division) | ||
| this.timeout = calcTimeout(this.tempo) |
index.js
Outdated
| this.step = 0; | ||
| this.timer = new NanoTimer(); | ||
| this.timeout = calcTimeout(this.tempo, this.division) | ||
| this.timeout = calcTimeout(this.tempo) |
|
|
||
| this.division = division; | ||
| this.sequence = sequence; | ||
| this.sequence = sequence || []; |
There was a problem hiding this comment.
Sure, we could make the sequence optional. But maybe we should default to an Array that is the same length as the number of subdivisions (or maybe 16, typical step-sequencer length)
this.sequence = sequence || Array(divisions);
// or
this.sequence = sequence || Array(16);There was a problem hiding this comment.
I think I copied the initialization from the constructor.
|
Thanks for reviewing! There are two features mixed together on this branch now because I have been using my fork in my project and needed all these changes. I should have sent separate PRs from feature branches. Sorry about that. This could be split into the following, maybe you could comment on both.
To quote what you said about 1. already.
In my step sequencer I have 3 arguments: stepSequencer = new StepSequencer(tempo * stepsPerBeat, numberOfSteps)If I change one of those variables I do: stepSequencer.setTempo(tempo * stepsPerBeat)
stepSequencer.setSequence(numberOfSteps)
stepSequencer.removeAllListeners()
registerAllListeners() //loops through range numberOfSteps to register all the event handlersI found this way easier to reason about and I am still not sure I could do it if tempo was tied to divisions. |
|
Would you be happy to change the constructor to? StepSequencer(tempo, stepsPerBeat, numberOfSteps [, sequence])Though I am not quite sure what to do about checking the size of the sequence array if we allow people to |
|
I fixed the semi-colons. Any thoughts on this? If I can't get this merged in some way I'll have to release a fork as I'd like to put my Launchpad step sequencer up on NPM. |
|
Hey @kasbah, I'll take a look at this when I get home from work. Hopefully we can get this merged in the next day or two. |
|
Looking at the constructor you posted earlier: StepSequencer(tempo, stepsPerBeat, numberOfSteps [, sequence])I like this. I wrote this project while trying to create a little step sequencer for a Raspberry Pi/Teenage Engineering Pocket Operator thing. In the var sequence = [
true, false, false, false,
true, false, false, false,
true, false, false, false,
true, false, false, false
];
var sequencer = new StepSequencer(120, 4, 16, sequence);
// On you launchpad:
// [X] [ ] [ ] [ ] [X] [ ] [ ] [ ]
// [X] [ ] [ ] [ ] [X] [ ] [ ] [ ]Of course, you could keep the sequence outside of the Anyways, you can change the constructor as you suggested. There would need to be an |
|
Yes, that does make sense. In my application I prefer to keep the sequence We could make use of dynamic typing and make the last argument either On 30 September 2016 at 15:43, Brandon Freitag notifications@github.com
|
|
Ok, so if the last argument is a number, treat it as numberOfSteps, but if it is an array, treat it as sequence, deriving the number of steps from the length of the array. Sounds good to me! |
I am using this to make a nice step sequencer out of my old Novation Launchpad. Thanks very much!
To me it makes more sense to have the tempo be beats per minute and independant of the number of divisions, so I adapted it. What do you think?