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
typedef unsigned char byte_t;
typedef unsigned long tick_t;
typedef double tick_t;
typedef unsigned int uint;

View File

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

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! */
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 );
}

View File

@ -24,6 +24,7 @@
#include "jack.H"
#include "transport.H"
#include <math.h>
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();
}

View File

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

View File

@ -22,6 +22,7 @@
#include "pattern.H"
#include "smf.H"
#include "common.h"
#include <math.h>
vector <phrase*> phrase::_phrases;
signal <void> 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 );

View File

@ -24,7 +24,7 @@
#include <sigc++/sigc++.h>
typedef unsigned long tick_t;
#include "common.h"
using std::vector;
using std::list;