Cockos Incorporated Forums a simple question about building a step sequencer with JSFX
 Register Search Today's Posts Mark Forums Read

 05-21-2023, 06:33 PM #1 BryanChi Human being with feelings   Join Date: Jan 2019 Location: Taiwan Posts: 314 a simple question about building a step sequencer with JSFX I'm having difficulty with letting the JSFX know the current position within the sequencer's length. I've figured out how to know the current playhead position in a measure with this simple equation: MeasureNum= floor(beat_position/ts_denom); BeatPos= beat_position - ts_denom* (MeasureNum); but what happens when you want to make the sequencer longer than a measure? Thank you!
 05-22-2023, 02:04 AM #2 IXix Human being with feelings   Join Date: Jan 2007 Location: mcr:uk Posts: 3,830 You'd use something along the lines of... Code: `current_pos = beat_position % sequence_length;` ... then go from there.
 05-22-2023, 02:27 AM #3 TonE Human being with feelings   Join Date: Feb 2009 Location: Reaper HAS send control via midi !!! Posts: 3,885 Wo ai Taiwan, greetings to Taiwan.
05-22-2023, 03:15 AM   #4
souk21
Human being with feelings

Join Date: Mar 2021
Posts: 301

Quote:
 Originally Posted by IXix Code: `current_pos = beat_position % sequence_length;`
This, but keep in mind % returns an integer. If you want a fractional position you need to use fmod

Code:
```function fmod (n, k) (
n - k * floor(n/k);
);
current_pos = fmod(beat_position, sequence_length);```
If you want the sequencer to go along but not be tied to the arrangement specific position you can use something along the lines of

Code:
```@block
beat_per_spl = tempo / (srate * 60);
beat_per_block = beat_per_spl * samplesblock;
//This replaces beat_position
bp += beat_per_block;
//Fractional position
current_pos = fmod(bp, sequence_length);
//Integer position
current_beat = floor(current_pos);```
This will play even if transport is stopped, so if it's not desirable you've got to check play_state.

Then you can
Code:
```@block
beat_per_spl = tempo / (srate * 60);
beat_per_block = beat_per_spl * samplesblock;
bp += beat_per_block;
current_pos = fmod(bp, sequence_length);
next_block_pos = fmod(bp + beat_per_block, sequence_length);

//Next block is going to start during next beat
floor(current_pos) != floor(next_block_pos) ? (
//How far is next beat
beat_offset = ceil(cur_position) - cur_position;
spl_offset = beat_offset / beat_per_block * samplesblock;
midisend(spl_offset, [...]);
);```
The advantage being that you can do stuff like
Code:
```beat_per_block = beat_per_spl * samplesblock;
beat_per_block *= speed;```
And if you need it to be sync with transport you can do
Code:
```@init
is_init = 0;

@block
//beat_position is not available in @init so you need to set it here
!is_init ? (
is_init = 1;
bp = beat_position;
);```

Last edited by souk21; 05-22-2023 at 05:55 AM.

 05-22-2023, 05:07 AM #5 BryanChi Human being with feelings   Join Date: Jan 2019 Location: Taiwan Posts: 314 @souk21 oh wow that is so comprehensive, thank you very much, you're a saint! @IXix Thank you, I will try a bit and see how it goes! @TonE hahaha Taiwan loves you too
 05-22-2023, 05:45 AM #6 souk21 Human being with feelings     Join Date: Mar 2021 Posts: 301 You're welcome Just noticed this part should be: Code: ``` //How far is next beat beat_offset = next_block_pos - floor(next_block_pos); spl_offset = (1 - beat_offset / beat_per_block) * samplesblock; midisend(spl_offset, [...]);``` I edited my previous post to correct this
 05-22-2023, 05:55 AM #7 souk21 Human being with feelings     Join Date: Mar 2021 Posts: 301 Or even clearer Code: ```//How far is next beat beat_offset = ceil(cur_position) - cur_position; spl_offset = beat_offset / beat_per_block * samplesblock;```
05-25-2023, 10:49 PM   #8
BryanChi
Human being with feelings

Join Date: Jan 2019
Location: Taiwan
Posts: 314

Thank you souk21!
I used just the first bit of your code and have already achieved most of what I need. I'll look deeper into it when I need more advanced functionalities.

Can you please explain to me what this means?

Quote:
 Originally Posted by souk21 The advantage being that you can do stuff like Code: ```beat_per_block = beat_per_spl * samplesblock; beat_per_block *= speed;```

 Yesterday, 06:03 AM #9 souk21 Human being with feelings     Join Date: Mar 2021 Posts: 301 The advantage is that if you use the "simple" version Code: `current_pos = fmod(beat_position, sequence_length);` If you want to change the speed, you can use the following code: Code: `current_pos = fmod(beat_position * speed, sequence_length);` That works but current_pos will jump all over the place if you change speed while playing. Code: ```//e.g beat_position is 2 and speed is 1 current_pos = fmod(2 * 1, sequence_length); //you change speed to 2 current_pos = fmod(2 * 2, sequence_length); //current_pos has jumped from 2 to 4``` Whereas with Code: ```beat_per_block = beat_per_spl * samplesblock; beat_per_block *= speed; next_block_pos = fmod(bp + beat_per_block, sequence_length);``` You won't have this problem Code: ```//e.g bp is 2 and speed is 1 next_block_pos = fmod(2 + beat_per_block * 1, sequence_length); //you change speed to 2 next_block_pos = fmod(2 + beat_per_block * 2, sequence_length); //next_block_pos has only gone up beat_per_block*2 which is what we want```
 Yesterday, 06:12 AM #10 souk21 Human being with feelings     Join Date: Mar 2021 Posts: 301 And this part Code: ```//How far is next beat beat_offset = ceil(cur_position) - cur_position; spl_offset = beat_offset / beat_per_block * samplesblock;``` Is useful if you want to trigger your sound/midi on the beat with sample accuracy. A block will never start at the beginning of a beat, so you need to know when in the buffer the beat is. If you want to trigger audio you can do it like this: Code: ```@buffer [...] //Next block is going to start during next beat floor(current_pos) != floor(next_block_pos) ? ( //How far is next beat beat_offset = ceil(cur_position) - cur_position; spl_offset = floor(beat_offset / beat_per_block * samplesblock); ); @sample spl_offset == 0 ? ( //Beat starts at this sample, e.g start playing buffer ); spl_offset -= 1;``` and if you want to trigger midi Code: ```//Next block is going to start during next beat floor(current_pos) != floor(next_block_pos) ? ( //How far is next beat beat_offset = ceil(cur_position) - cur_position; spl_offset = beat_offset / beat_per_block * samplesblock; midisend(spl_offset, [...]); );```

 Thread Tools Display Modes Linear Mode

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is Off Forum Rules
 Forum Jump User Control Panel Private Messages Subscriptions Who's Online Search Forums Forums Home REAPER Forums     REAPER General Discussion Forum     newbieland     REAPER Q&A, Tips, Tricks and Howto     Recording Technologies and Techniques     REAPER Compatibility     REAPER Color Themes and Icon Sets     MIDI Hardware, Control Surfaces, and OSC     REAPER Non-English Speaking User Forums         Forum de REAPER en français         Foro de REAPER en Español         Fórum do REAPER em português         Forum di REAPER in italiano         Deutschsprachiges REAPER Userforum         Pyccкоязычный фopyм REAPER     REAPER Bug Reports     REAPER Feature Requests     Dstruct's Casa De Nitpicks     REAPER for Live Use     REAPER for Video Editing/Mangling     REAPER for Spatial Audio     ReaScript, JSFX, REAPER Plug-in Extensions, Developer Forum     REAPER for macOS     REAPER for Linux     REAPER Pre-Release Discussion     REAPER Music/Collaboration Discussion NINJAM Discussion     NINJAM User Discussion     NINJAM Developer Discussion Other Software Discussion     WDL users forum     LICEcap Discussion     OSCII-bot forum     Old Cockos Products Forum

All times are GMT -7. The time now is 08:49 PM.

 -- Cockos ---- REAPER 5 ---- Reaper 3 ---- Reaper 2 ---- Reaper 1 Contact Us - Çockos Incorporated - Archive - Top