From d23307ca53011fbffbca27933d6b99804b74291b Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Fri, 27 Apr 2012 18:31:06 -0700 Subject: [PATCH] Sequencer: Use double for ticks_t This helps dealing with fractional errors resulting in dropped notes when running with very small buffer sizes. --- sequencer/src/common.h | 2 +- sequencer/src/grid.C | 4 ++-- sequencer/src/jack.C | 22 +++++++++++----------- sequencer/src/pattern.C | 16 +++++++++------- sequencer/src/pattern.H | 3 +-- sequencer/src/phrase.C | 3 ++- sequencer/src/sequence.H | 2 +- 7 files changed, 27 insertions(+), 25 deletions(-) diff --git a/sequencer/src/common.h b/sequencer/src/common.h index e8740d1..7c179a8 100644 --- a/sequencer/src/common.h +++ b/sequencer/src/common.h @@ -21,7 +21,7 @@ // #pragma once typedef unsigned char byte_t; -typedef unsigned long tick_t; +typedef double tick_t; typedef unsigned int uint; diff --git a/sequencer/src/grid.C b/sequencer/src/grid.C index a8d21c1..3087c7f 100644 --- a/sequencer/src/grid.C +++ b/sequencer/src/grid.C @@ -260,8 +260,8 @@ Grid::prev_note_x ( int x ) const void Grid::_fix_length ( void ) { - tick_t beats = (_rw->length / PPQN); - tick_t rem = _rw->length % PPQN; + tick_t beats = (unsigned long)(_rw->length / PPQN); + tick_t rem = (unsigned long)_rw->length % PPQN; _rw->length = (rem ? (beats + 1) : beats) * PPQN; } diff --git a/sequencer/src/jack.C b/sequencer/src/jack.C index 98ca0dc..14e214a 100644 --- a/sequencer/src/jack.C +++ b/sequencer/src/jack.C @@ -312,7 +312,7 @@ process ( jack_nframes_t nframes, void *arg ) /* ph-nph is exclusive. It is important that in normal continuous playback each tick is covered exactly once! */ const tick_t ph = transport.ticks; - const tick_t nph = trunc( transport.ticks + transport.ticks_per_period ); + const tick_t nph = transport.ticks + transport.ticks_per_period; if ( ! transport.valid ) goto schedule; @@ -320,15 +320,15 @@ process ( jack_nframes_t nframes, void *arg ) if ( ( ! transport.rolling ) || ph == oph ) goto schedule; - if ( ph != onph ) - { - if ( onph > ph ) - DWARNING( "duplicated %lu ticks (out of %d)", onph - ph, (int)(not_dropped * transport.ticks_per_period) ); - else - DWARNING( "dropped %lu ticks (out of %d)", ph - onph, (int)(not_dropped * transport.ticks_per_period) ); + /* if ( ph != onph ) */ + /* { */ + /* if ( onph > ph ) */ + /* DWARNING( "duplicated %lu ticks (out of %d)", onph - ph, (int)(not_dropped * transport.ticks_per_period) ); */ + /* else */ + /* DWARNING( "dropped %lu ticks (out of %d), ticks per period = %f", ph - onph, (int)(not_dropped * transport.ticks_per_period) ); */ - not_dropped = 0; - } + /* not_dropped = 0; */ + /* } */ ++not_dropped; @@ -398,7 +398,7 @@ process ( jack_nframes_t nframes, void *arg ) { DMESSAGE( "Triggering pattern %i ph=%lu, ts=%lu", e.msb(), ph, e.timestamp() ); - p->trigger( e.timestamp(), -1 ); + p->trigger( e.timestamp(), INFINITY ); } } else @@ -433,7 +433,7 @@ process ( jack_nframes_t nframes, void *arg ) { pattern *p = pattern::pattern_by_number( i + 1 ); - p->trigger( 0, -1 ); + p->trigger( 0, INFINITY ); p->play( ph, nph ); } diff --git a/sequencer/src/pattern.C b/sequencer/src/pattern.C index d83e06a..4dba582 100644 --- a/sequencer/src/pattern.C +++ b/sequencer/src/pattern.C @@ -24,6 +24,7 @@ #include "jack.H" #include "transport.H" +#include int pattern::note_shape = SQUARE; @@ -217,7 +218,8 @@ pattern::record_event ( const midievent *me ) tick_t duration = off->timestamp() - on->timestamp(); /* place within loop */ - on->timestamp( ( on->timestamp() - p->_start ) % p->_rw->length ); + on->timestamp( + fmod( on->timestamp() - p->_start, p->_rw->length ) ); on->link( off ); on->note_duration( duration ); @@ -234,7 +236,7 @@ pattern::record_event ( const midievent *me ) // if ( ! filter ) - e->timestamp( e->timestamp() % p->_rw->length ); + e->timestamp( fmod( e->timestamp(), p->_rw->length ) ); el->unlink( e ); p->_rw->events.insert( e ); @@ -314,7 +316,7 @@ pattern::draw_row_names ( Canvas *c ) const void pattern::trigger ( tick_t start, tick_t end ) { - ASSERT( start <= end, "programming error: invalid loop trigger! (%lu-%lu)", start, end ); + /* ASSERT( end != -1 && start <= end, "programming error: invalid loop trigger! (%lu-%lu)", start, end ); */ _start = start; _end = end; @@ -325,7 +327,7 @@ pattern::trigger ( tick_t start, tick_t end ) void pattern::trigger ( void ) { - trigger( transport.frame / transport.frames_per_tick, -1 ); + trigger( transport.frame / transport.frames_per_tick, INFINITY ); } void @@ -423,14 +425,14 @@ pattern::play ( tick_t start, tick_t end ) const const event *e; - _index = tick % d->length; + _index = fmod( tick, d->length ); bool reset_queued = false; if ( _index < end - start ) { /* period covers the beginning of the loop */ - DMESSAGE( "%s pattern %d at tick %lu (ls: %lu, le: %lu, o: %lu)", _playing ? "Looped" : "Triggered", number(), start, _start, _end, offset ); + DMESSAGE( "%s pattern %d at tick %f (ls: %f, le: %f, o: %f)", _playing ? "Looped" : "Triggered", number(), start, _start, _end, offset ); _cleared = false; @@ -535,7 +537,7 @@ done: if ( _end == end ) { /* we're done playing this trigger */ - DMESSAGE( "Pattern %d ended at tick %lu (ls: %lu, le: %lu, o: %lu)", number(), end, _start, _end, offset ); + DMESSAGE( "Pattern %d ended at tick %f (ls: %f, le: %f, o: %f)", number(), end, _start, _end, offset ); stop(); } diff --git a/sequencer/src/pattern.H b/sequencer/src/pattern.H index 58f5f3a..3e4aaf5 100644 --- a/sequencer/src/pattern.H +++ b/sequencer/src/pattern.H @@ -23,8 +23,7 @@ #include "canvas.H" #include "mapping.H" // #include "event.H" - -typedef unsigned long tick_t; +#include "common.h" #include using std::vector; diff --git a/sequencer/src/phrase.C b/sequencer/src/phrase.C index 964828f..dd544d5 100644 --- a/sequencer/src/phrase.C +++ b/sequencer/src/phrase.C @@ -22,6 +22,7 @@ #include "pattern.H" #include "smf.H" #include "common.h" +#include vector phrase::_phrases; signal phrase::signal_create_destroy; @@ -197,7 +198,7 @@ phrase::play ( tick_t start, tick_t end ) int num_played = tick / d->length; tick_t offset = _start + (d->length * num_played); - _index = tick % d->length; + _index = fmod( tick, d->length ); if ( _index < end - start ) DMESSAGE( "Triggered phrase %d at tick %lu (ls: %lu, le: %lu, o: %lu)", number(), start, _start, _end, offset ); diff --git a/sequencer/src/sequence.H b/sequencer/src/sequence.H index 322535a..321abd4 100644 --- a/sequencer/src/sequence.H +++ b/sequencer/src/sequence.H @@ -24,7 +24,7 @@ #include -typedef unsigned long tick_t; +#include "common.h" using std::vector; using std::list;