diff options
author | Bad Diode <bd@badd10de.dev> | 2024-01-04 14:19:05 +0100 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-01-04 14:19:05 +0100 |
commit | 2d397003e2acbfd04019425bef00d0834191cd92 (patch) | |
tree | da37380fc954fa656686645d5bc1f58d1897a200 /src/sequencer.c | |
parent | e1680f8c586dfd111b794c0e6f7cc9ed81a76b0b (diff) | |
download | stepper-2d397003e2acbfd04019425bef00d0834191cd92.tar.gz stepper-2d397003e2acbfd04019425bef00d0834191cd92.zip |
Add new 96ppq sequencer tick timer
Diffstat (limited to 'src/sequencer.c')
-rw-r--r-- | src/sequencer.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/src/sequencer.c b/src/sequencer.c index 632a777..11c0f5a 100644 --- a/src/sequencer.c +++ b/src/sequencer.c | |||
@@ -346,21 +346,46 @@ play_step(void) { | |||
346 | step_counter = (step_counter + 1) % 16; | 346 | step_counter = (step_counter + 1) % 16; |
347 | } | 347 | } |
348 | 348 | ||
349 | static nseq_ticks = 0; | ||
350 | void | ||
351 | sequencer_tick(void) { | ||
352 | if (nseq_ticks++ < 24) { | ||
353 | return; | ||
354 | } | ||
355 | nseq_ticks = 0; | ||
356 | |||
357 | // NOTE: ACK interrupt before play_step??? | ||
358 | play_step(); | ||
359 | } | ||
360 | |||
349 | void | 361 | void |
350 | set_time(int bpm) { | 362 | set_time(int bpm) { |
351 | if (settings.sync == SYNC_IN_LINK) { | 363 | if (settings.sync == SYNC_IN_LINK) { |
352 | return; | 364 | return; |
353 | } | 365 | } |
354 | // The number of ticks of a 1024 cycle clock in a step based on the BPM can | 366 | // We use a high resolution 96 PPQ clock for sequencing. With the following |
355 | // be calculated as: | 367 | // formula we can calculate the time (in seconds) based on the PPQ and BPM: |
356 | // X bpm -> 60000 / 4 / bpm = Y ms = Ye-3 s | 368 | // |
357 | // Y ms -> Ye-3 / 59.99e-9 / 1024 = Z ticks | 369 | // t = 60 / (PPQ * BPM) |
358 | // We have to operate on integer values, so the numbers have been | 370 | // |
359 | // precalculated to `n_ticks = 244181 / bmp` | 371 | // To translate this timer to a GBA timer running at 64 CPU cycles per tick |
360 | int n_ticks = -244181 / bpm; | 372 | // we need to divide this by the constant Q = 3.97329943e-06. In theory, the |
361 | irs_set(IRQ_TIMER_2, play_step); | 373 | // period of this timer running a a frequency of 262.21kHz should be |
374 | // Q = 3.815us, but using this number resulted in a less accurate sequencer | ||
375 | // compared to the metronome of a DAW (Bitwig). Tuning Q using a japanese | ||
376 | // GBA-SP and an Analogue Pocket resulted in the previously mentioned value. | ||
377 | // | ||
378 | // If we factor out the BPM we can obtain a fixed constant: | ||
379 | // | ||
380 | // C = 60 / (96 * 3.97329943e-06) = 157300 | ||
381 | // | ||
382 | // Allowing us to calculate the clock timer as -C/BPM. Note that this is | ||
383 | // integer division and we will be losing the fractional part, resulting in | ||
384 | // some minor precision differences, but it seems to work well in practice. | ||
385 | int n_ticks = -157300 / bpm; | ||
386 | irs_set(IRQ_TIMER_2, sequencer_tick); | ||
362 | TIMER_DATA_2 = n_ticks; | 387 | TIMER_DATA_2 = n_ticks; |
363 | TIMER_CTRL_2 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3; | 388 | TIMER_CTRL_2 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_1; |
364 | } | 389 | } |
365 | 390 | ||
366 | TriggerNote * | 391 | TriggerNote * |