Sequencer: Use double for ticks_t

This helps dealing with fractional errors resulting in dropped notes when running with
very small buffer sizes.
This commit is contained in:
Jonathan Moore Liles 2012-04-27 18:31:06 -07:00
parent 2c6b6b1a75
commit d23307ca53
7 changed files with 27 additions and 25 deletions

View File

@ -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;

View File

@ -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 beats = (unsigned long)(_rw->length / PPQN);
tick_t rem = _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;
} }

View File

@ -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 ( ph != onph ) */
{ /* { */
if ( onph > ph ) /* if ( onph > ph ) */
DWARNING( "duplicated %lu ticks (out of %d)", onph - ph, (int)(not_dropped * transport.ticks_per_period) ); /* DWARNING( "duplicated %lu ticks (out of %d)", onph - ph, (int)(not_dropped * transport.ticks_per_period) ); */
else /* else */
DWARNING( "dropped %lu ticks (out of %d)", ph - onph, (int)(not_dropped * transport.ticks_per_period) ); /* 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 );
} }

View File

@ -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();
} }

View File

@ -23,8 +23,7 @@
#include "canvas.H" #include "canvas.H"
#include "mapping.H" #include "mapping.H"
// #include "event.H" // #include "event.H"
#include "common.h"
typedef unsigned long tick_t;
#include <vector> #include <vector>
using std::vector; using std::vector;

View File

@ -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 );

View File

@ -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;