cwPreset.h/cpp : Added track_timestamp().
This commit is contained in:
parent
071cdb26dc
commit
61cd918a08
162
cwPresetSel.cpp
162
cwPresetSel.cpp
@ -4,6 +4,7 @@
|
|||||||
#include "cwMem.h"
|
#include "cwMem.h"
|
||||||
#include "cwText.h"
|
#include "cwText.h"
|
||||||
#include "cwObject.h"
|
#include "cwObject.h"
|
||||||
|
#include "cwTime.h"
|
||||||
#include "cwPresetSel.h"
|
#include "cwPresetSel.h"
|
||||||
|
|
||||||
namespace cw
|
namespace cw
|
||||||
@ -25,6 +26,10 @@ namespace cw
|
|||||||
double defaultFadeOutMs;
|
double defaultFadeOutMs;
|
||||||
|
|
||||||
struct frag_str* fragL;
|
struct frag_str* fragL;
|
||||||
|
|
||||||
|
|
||||||
|
frag_t* last_ts_frag;
|
||||||
|
|
||||||
} preset_sel_t;
|
} preset_sel_t;
|
||||||
|
|
||||||
preset_sel_t* _handleToPtr( handle_t h )
|
preset_sel_t* _handleToPtr( handle_t h )
|
||||||
@ -113,6 +118,50 @@ namespace cw
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _ts_is_in_frag( const frag_t* f, const time::spec_t& ts )
|
||||||
|
{
|
||||||
|
// if f is the earliest fragment
|
||||||
|
if( f->prev == nullptr )
|
||||||
|
return time::isLTE(ts,f->endTimestamp);
|
||||||
|
|
||||||
|
// else f->prev->end_ts < ts && ts <= f->end_ts
|
||||||
|
return time::isLT(f->prev->endTimestamp,ts) && time::isLTE(ts,f->endTimestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _ts_is_before_frag( const frag_t* f, const time::spec_t& ts )
|
||||||
|
{
|
||||||
|
// if ts is past f
|
||||||
|
if( time::isGT(ts,f->endTimestamp ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// ts may now only be inside or before f
|
||||||
|
|
||||||
|
// if f is the first frag then ts must be inside it
|
||||||
|
if( f->prev == nullptr )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// is ts before f
|
||||||
|
return time::isLTE(ts,f->prev->endTimestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _ts_is_after_frag( const frag_t* f, const time::spec_t& ts )
|
||||||
|
{
|
||||||
|
return time::isGT(ts,f->endTimestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan from through the fragment list to find the fragment containing ts.
|
||||||
|
frag_t* _timestamp_to_frag( preset_sel_t* p, const time::spec_t& ts, frag_t* init_frag=nullptr )
|
||||||
|
{
|
||||||
|
frag_t* f = init_frag==nullptr ? p->fragL : init_frag;
|
||||||
|
for(; f!=nullptr; f=f->link)
|
||||||
|
if( _ts_is_in_frag(f,ts) )
|
||||||
|
return f;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rc_t _validate_preset_id( const frag_t* frag, unsigned preset_id )
|
rc_t _validate_preset_id( const frag_t* frag, unsigned preset_id )
|
||||||
{
|
{
|
||||||
bool fl = (preset_id < frag->presetN) && (frag->presetA[ preset_id ].preset_idx == preset_id);
|
bool fl = (preset_id < frag->presetN) && (frag->presetA[ preset_id ].preset_idx == preset_id);
|
||||||
@ -335,11 +384,12 @@ const cw::preset_sel::frag_t* cw::preset_sel::get_fragment( handle_t h, unsigned
|
|||||||
return _find_frag(p,fragId);
|
return _find_frag(p,fragId);
|
||||||
}
|
}
|
||||||
|
|
||||||
cw::rc_t cw::preset_sel::create_fragment( handle_t h, unsigned fragId, unsigned end_loc )
|
cw::rc_t cw::preset_sel::create_fragment( handle_t h, unsigned fragId, unsigned end_loc, time::spec_t end_timestamp )
|
||||||
{
|
{
|
||||||
preset_sel_t* p = _handleToPtr(h);
|
preset_sel_t* p = _handleToPtr(h);
|
||||||
frag_t* f = mem::allocZ<frag_t>();
|
frag_t* f = mem::allocZ<frag_t>();
|
||||||
f->endLoc = end_loc;
|
f->endLoc = end_loc;
|
||||||
|
f->endTimestamp = end_timestamp;
|
||||||
f->fragId = fragId;
|
f->fragId = fragId;
|
||||||
f->dryFl = false;
|
f->dryFl = false;
|
||||||
f->gain = p->defaultGain;
|
f->gain = p->defaultGain;
|
||||||
@ -351,15 +401,47 @@ cw::rc_t cw::preset_sel::create_fragment( handle_t h, unsigned fragId, unsigned
|
|||||||
for(unsigned i=0; i<p->presetLabelN; ++i)
|
for(unsigned i=0; i<p->presetLabelN; ++i)
|
||||||
f->presetA[i].preset_idx = i;
|
f->presetA[i].preset_idx = i;
|
||||||
|
|
||||||
|
// if the list is empty
|
||||||
frag_t* f0;
|
if( p->fragL == nullptr )
|
||||||
for(f0=p->fragL; f0!=nullptr; f0=f0->link)
|
{
|
||||||
if( f0->link == nullptr )
|
|
||||||
break;
|
|
||||||
if( f0 == nullptr )
|
|
||||||
p->fragL = f;
|
p->fragL = f;
|
||||||
else
|
return kOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
frag_t* f0 = p->fragL;
|
||||||
|
for(; f0->link!=nullptr; f0 = f0->link)
|
||||||
|
if( end_loc < f0->endLoc )
|
||||||
|
break;
|
||||||
|
//
|
||||||
|
assert( f0 != nullptr );
|
||||||
|
|
||||||
|
// if f is after the last current fragment ...
|
||||||
|
if( f0->link == nullptr )
|
||||||
|
{
|
||||||
|
// ... insert f at the end of the list
|
||||||
f0->link = f;
|
f0->link = f;
|
||||||
|
f->prev = f0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Insert f before f0
|
||||||
|
|
||||||
|
f->link = f0;
|
||||||
|
f->prev = f0->prev;
|
||||||
|
|
||||||
|
// if f0 was first on the list
|
||||||
|
if( f0->prev == nullptr )
|
||||||
|
{
|
||||||
|
assert( p->fragL == f0 );
|
||||||
|
p->fragL = f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
f0->prev->link = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
f0->prev = f;
|
||||||
|
}
|
||||||
|
|
||||||
return kOkRC;
|
return kOkRC;
|
||||||
}
|
}
|
||||||
@ -441,6 +523,51 @@ cw::rc_t cw::preset_sel::get_value( handle_t h, unsigned fragId, unsigned varId,
|
|||||||
cw::rc_t cw::preset_sel::get_value( handle_t h, unsigned fragId, unsigned varId, unsigned presetId, double& valueRef )
|
cw::rc_t cw::preset_sel::get_value( handle_t h, unsigned fragId, unsigned varId, unsigned presetId, double& valueRef )
|
||||||
{ return _get_value(h,fragId,varId,presetId,valueRef); }
|
{ return _get_value(h,fragId,varId,presetId,valueRef); }
|
||||||
|
|
||||||
|
bool cw::preset_sel::track_timestamp( handle_t h, const time::spec_t& ts, const cw::preset_sel::frag_t*& frag_Ref )
|
||||||
|
{
|
||||||
|
preset_sel_t* p = _handleToPtr(h);
|
||||||
|
frag_t* f = nullptr;
|
||||||
|
bool frag_changed_fl = false;
|
||||||
|
|
||||||
|
// if this is the first call to 'track_timestamp()'.
|
||||||
|
if( p->last_ts_frag == nullptr )
|
||||||
|
f = _timestamp_to_frag(p,ts);
|
||||||
|
else
|
||||||
|
// if the 'ts' is in the same frag as previous call.
|
||||||
|
if( _ts_is_in_frag(p->last_ts_frag,ts) )
|
||||||
|
f = p->last_ts_frag;
|
||||||
|
else
|
||||||
|
// if 'ts' is in a later frag
|
||||||
|
if( _ts_is_after_frag(p->last_ts_frag,ts) )
|
||||||
|
f = _timestamp_to_frag(p,ts,p->last_ts_frag);
|
||||||
|
else // ts is prior to 'last_ts_frag'
|
||||||
|
f = _timestamp_to_frag(p,ts);
|
||||||
|
|
||||||
|
// 'f' will be null at this point if 'ts' is past the last preset.
|
||||||
|
// In this case we should leave 'last_ts_frag' unchanged.
|
||||||
|
|
||||||
|
// if 'f' is valid but different from 'last_ts_frag'
|
||||||
|
if( f != nullptr && f != p->last_ts_frag )
|
||||||
|
{
|
||||||
|
p->last_ts_frag = f;
|
||||||
|
frag_changed_fl = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
frag_Ref = p->last_ts_frag;
|
||||||
|
|
||||||
|
return frag_changed_fl;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned cw::preset_sel::fragment_play_preset_index( const frag_t* frag )
|
||||||
|
{
|
||||||
|
for(unsigned i=0; i<frag->presetN; ++i)
|
||||||
|
if( frag->presetA[i].playFl )
|
||||||
|
return frag->presetA[i].preset_idx;
|
||||||
|
|
||||||
|
return kInvalidIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cw::rc_t cw::preset_sel::write( handle_t h, const char* fn )
|
cw::rc_t cw::preset_sel::write( handle_t h, const char* fn )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
@ -452,3 +579,22 @@ cw::rc_t cw::preset_sel::read( handle_t h, const char* fn )
|
|||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::preset_sel::report( handle_t h )
|
||||||
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
preset_sel_t* p = _handleToPtr(h);
|
||||||
|
unsigned i = 0;
|
||||||
|
time::spec_t t0;
|
||||||
|
time::setZero(t0);
|
||||||
|
|
||||||
|
for(frag_t* f=p->fragL; f!=nullptr; f=f->link,++i)
|
||||||
|
{
|
||||||
|
unsigned elapsedMs = time::elapsedMs(t0,f->endTimestamp);
|
||||||
|
double mins = elapsedMs / 60000.0;
|
||||||
|
|
||||||
|
cwLogInfo("%3i id:%3i end loc:%3i end min:%7.2f",i,f->fragId,f->endLoc, mins);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@ -12,13 +12,14 @@ namespace cw
|
|||||||
{
|
{
|
||||||
bool playFl; // play this preset
|
bool playFl; // play this preset
|
||||||
unsigned preset_idx; // preset index into preset_labelA[].
|
unsigned preset_idx; // preset index into preset_labelA[].
|
||||||
unsigned order;
|
unsigned order; //
|
||||||
} preset_t;
|
} preset_t;
|
||||||
|
|
||||||
typedef struct frag_str
|
typedef struct frag_str
|
||||||
{
|
{
|
||||||
unsigned fragId;
|
unsigned fragId;
|
||||||
unsigned endLoc;
|
unsigned endLoc; // The endLoc is included in this fragment. The begin loc is f->prev->endLoc+1
|
||||||
|
time::spec_t endTimestamp;
|
||||||
|
|
||||||
bool dryFl;
|
bool dryFl;
|
||||||
double gain;
|
double gain;
|
||||||
@ -31,6 +32,7 @@ namespace cw
|
|||||||
bool uiSelectFl;
|
bool uiSelectFl;
|
||||||
|
|
||||||
struct frag_str* link;
|
struct frag_str* link;
|
||||||
|
struct frag_str* prev;
|
||||||
} frag_t;
|
} frag_t;
|
||||||
|
|
||||||
|
|
||||||
@ -43,7 +45,7 @@ namespace cw
|
|||||||
kPresetOrderVarId, // preset order value
|
kPresetOrderVarId, // preset order value
|
||||||
kPresetSelectVarId, // select a preset to play
|
kPresetSelectVarId, // select a preset to play
|
||||||
kPlayEnableVarId, // include in the segment to play
|
kPlayEnableVarId, // include in the segment to play
|
||||||
kDryFlVarId, // play this fragion dry
|
kDryFlVarId, // play this fragment dry
|
||||||
};
|
};
|
||||||
|
|
||||||
rc_t create( handle_t& hRef, const object_t* cfg );
|
rc_t create( handle_t& hRef, const object_t* cfg );
|
||||||
@ -58,7 +60,7 @@ namespace cw
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
rc_t create_fragment( handle_t h, unsigned fragId, unsigned end_loc );
|
rc_t create_fragment( handle_t h, unsigned fragId, unsigned end_loc, time::spec_t endTimestamp );
|
||||||
rc_t delete_fragment( handle_t h, unsigned fragId );
|
rc_t delete_fragment( handle_t h, unsigned fragId );
|
||||||
|
|
||||||
bool is_fragment_loc( handle_t h, unsigned loc );
|
bool is_fragment_loc( handle_t h, unsigned loc );
|
||||||
@ -75,8 +77,19 @@ namespace cw
|
|||||||
rc_t get_value( handle_t h, unsigned fragId, unsigned varId, unsigned presetId, unsigned& valueRef );
|
rc_t get_value( handle_t h, unsigned fragId, unsigned varId, unsigned presetId, unsigned& valueRef );
|
||||||
rc_t get_value( handle_t h, unsigned fragId, unsigned varId, unsigned presetId, double& valueRef );
|
rc_t get_value( handle_t h, unsigned fragId, unsigned varId, unsigned presetId, double& valueRef );
|
||||||
|
|
||||||
|
// Call this function to determine which fragment the timestamp 'ts' is contained by.
|
||||||
|
// This call is optimized to be called in time critical functions where 'ts' is expected to be increasing.
|
||||||
|
// If 'ts' is past the last defined fragment then the last fragment is returned.
|
||||||
|
// If no fragments are defined 'frag_Ref' is set to nullptr.
|
||||||
|
// The return value is true when the value of frag_Ref changes from the previous call.
|
||||||
|
bool track_timestamp( handle_t h, const time::spec_t& ts, const cw::preset_sel::frag_t*& frag_Ref );
|
||||||
|
|
||||||
|
// Return the preset index marked to play on this fragment.
|
||||||
|
unsigned fragment_play_preset_index( const frag_t* frag );
|
||||||
|
|
||||||
rc_t write( handle_t h, const char* fn );
|
rc_t write( handle_t h, const char* fn );
|
||||||
rc_t read( handle_t h, const char* fn );
|
rc_t read( handle_t h, const char* fn );
|
||||||
|
rc_t report( handle_t h );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user