This helps dealing with fractional errors resulting in dropped notes when running with very small buffer sizes.tags/non-daw-v1.2.0
| @@ -21,7 +21,7 @@ | |||||
| // #pragma once | // #pragma once | ||||
| typedef unsigned char byte_t; | typedef unsigned char byte_t; | ||||
| typedef unsigned long tick_t; | |||||
| typedef double tick_t; | |||||
| typedef unsigned int uint; | typedef unsigned int uint; | ||||
| @@ -260,8 +260,8 @@ Grid::prev_note_x ( int x ) const | |||||
| void | void | ||||
| Grid::_fix_length ( 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; | _rw->length = (rem ? (beats + 1) : beats) * PPQN; | ||||
| } | } | ||||
| @@ -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! */ | /* 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 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 ) | if ( ! transport.valid ) | ||||
| goto schedule; | goto schedule; | ||||
| @@ -320,15 +320,15 @@ process ( jack_nframes_t nframes, void *arg ) | |||||
| if ( ( ! transport.rolling ) || ph == oph ) | if ( ( ! transport.rolling ) || ph == oph ) | ||||
| goto schedule; | 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; | ++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() ); | DMESSAGE( "Triggering pattern %i ph=%lu, ts=%lu", e.msb(), ph, e.timestamp() ); | ||||
| p->trigger( e.timestamp(), -1 ); | |||||
| p->trigger( e.timestamp(), INFINITY ); | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| @@ -433,7 +433,7 @@ process ( jack_nframes_t nframes, void *arg ) | |||||
| { | { | ||||
| pattern *p = pattern::pattern_by_number( i + 1 ); | pattern *p = pattern::pattern_by_number( i + 1 ); | ||||
| p->trigger( 0, -1 ); | |||||
| p->trigger( 0, INFINITY ); | |||||
| p->play( ph, nph ); | p->play( ph, nph ); | ||||
| } | } | ||||
| @@ -24,6 +24,7 @@ | |||||
| #include "jack.H" | #include "jack.H" | ||||
| #include "transport.H" | #include "transport.H" | ||||
| #include <math.h> | |||||
| int pattern::note_shape = SQUARE; | int pattern::note_shape = SQUARE; | ||||
| @@ -217,7 +218,8 @@ pattern::record_event ( const midievent *me ) | |||||
| tick_t duration = off->timestamp() - on->timestamp(); | tick_t duration = off->timestamp() - on->timestamp(); | ||||
| /* place within loop */ | /* 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->link( off ); | ||||
| on->note_duration( duration ); | on->note_duration( duration ); | ||||
| @@ -234,7 +236,7 @@ pattern::record_event ( const midievent *me ) | |||||
| // if ( ! filter ) | // if ( ! filter ) | ||||
| e->timestamp( e->timestamp() % p->_rw->length ); | |||||
| e->timestamp( fmod( e->timestamp(), p->_rw->length ) ); | |||||
| el->unlink( e ); | el->unlink( e ); | ||||
| p->_rw->events.insert( e ); | p->_rw->events.insert( e ); | ||||
| @@ -314,7 +316,7 @@ pattern::draw_row_names ( Canvas *c ) const | |||||
| void | void | ||||
| pattern::trigger ( tick_t start, tick_t end ) | 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; | _start = start; | ||||
| _end = end; | _end = end; | ||||
| @@ -325,7 +327,7 @@ pattern::trigger ( tick_t start, tick_t end ) | |||||
| void | void | ||||
| pattern::trigger ( void ) | pattern::trigger ( void ) | ||||
| { | { | ||||
| trigger( transport.frame / transport.frames_per_tick, -1 ); | |||||
| trigger( transport.frame / transport.frames_per_tick, INFINITY ); | |||||
| } | } | ||||
| void | void | ||||
| @@ -423,14 +425,14 @@ pattern::play ( tick_t start, tick_t end ) const | |||||
| const event *e; | const event *e; | ||||
| _index = tick % d->length; | |||||
| _index = fmod( tick, d->length ); | |||||
| bool reset_queued = false; | bool reset_queued = false; | ||||
| if ( _index < end - start ) | if ( _index < end - start ) | ||||
| { | { | ||||
| /* period covers the beginning of the loop */ | /* 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; | _cleared = false; | ||||
| @@ -535,7 +537,7 @@ done: | |||||
| if ( _end == end ) | if ( _end == end ) | ||||
| { | { | ||||
| /* we're done playing this trigger */ | /* 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(); | stop(); | ||||
| } | } | ||||
| @@ -23,8 +23,7 @@ | |||||
| #include "canvas.H" | #include "canvas.H" | ||||
| #include "mapping.H" | #include "mapping.H" | ||||
| // #include "event.H" | // #include "event.H" | ||||
| typedef unsigned long tick_t; | |||||
| #include "common.h" | |||||
| #include <vector> | #include <vector> | ||||
| using std::vector; | using std::vector; | ||||
| @@ -22,6 +22,7 @@ | |||||
| #include "pattern.H" | #include "pattern.H" | ||||
| #include "smf.H" | #include "smf.H" | ||||
| #include "common.h" | #include "common.h" | ||||
| #include <math.h> | |||||
| vector <phrase*> phrase::_phrases; | vector <phrase*> phrase::_phrases; | ||||
| signal <void> phrase::signal_create_destroy; | signal <void> phrase::signal_create_destroy; | ||||
| @@ -197,7 +198,7 @@ phrase::play ( tick_t start, tick_t end ) | |||||
| int num_played = tick / d->length; | int num_played = tick / d->length; | ||||
| tick_t offset = _start + (d->length * num_played); | tick_t offset = _start + (d->length * num_played); | ||||
| _index = tick % d->length; | |||||
| _index = fmod( tick, d->length ); | |||||
| if ( _index < end - start ) | if ( _index < end - start ) | ||||
| DMESSAGE( "Triggered phrase %d at tick %lu (ls: %lu, le: %lu, o: %lu)", number(), start, _start, _end, offset ); | DMESSAGE( "Triggered phrase %d at tick %lu (ls: %lu, le: %lu, o: %lu)", number(), start, _start, _end, offset ); | ||||
| @@ -24,7 +24,7 @@ | |||||
| #include <sigc++/sigc++.h> | #include <sigc++/sigc++.h> | ||||
| typedef unsigned long tick_t; | |||||
| #include "common.h" | |||||
| using std::vector; | using std::vector; | ||||
| using std::list; | using std::list; | ||||