|
@@ -879,6 +879,7 @@ enum
|
879
|
879
|
kSmpIdxSfId,
|
880
|
880
|
kCmdSfId,
|
881
|
881
|
kOutSfId,
|
|
882
|
+ kRecentSfId,
|
882
|
883
|
kDynSfId,
|
883
|
884
|
kEvenSfId,
|
884
|
885
|
kTempoSfId,
|
|
@@ -904,6 +905,7 @@ typedef struct cmDspScFol_str
|
904
|
905
|
cmDspScFolCbArg_t arg;
|
905
|
906
|
unsigned printSymId;
|
906
|
907
|
unsigned quietSymId;
|
|
908
|
+ unsigned maxScLocIdx;
|
907
|
909
|
} cmDspScFol_t;
|
908
|
910
|
|
909
|
911
|
cmDspInst_t* _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
|
|
@@ -921,7 +923,8 @@ cmDspInst_t* _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
|
921
|
923
|
{ "d1", kD1SfId, 0, 0, kInDsvFl | kUIntDsvFl, "MIDI data byte 1"},
|
922
|
924
|
{ "smpidx",kSmpIdxSfId, 0, 0, kInDsvFl | kUIntDsvFl, "MIDI time tag as a sample index"},
|
923
|
925
|
{ "cmd", kCmdSfId, 0, 0, kInDsvFl | kSymDsvFl, "Command input: print | quiet"},
|
924
|
|
- { "out", kOutSfId, 0, 0, kOutDsvFl| kUIntDsvFl, "Current score location index."},
|
|
926
|
+ { "out", kOutSfId, 0, 0, kOutDsvFl| kUIntDsvFl, "Maximum score location index."},
|
|
927
|
+ { "recent",kRecentSfId, 0, 0, kOutDsvFl| kUIntDsvFl, "Most recent score location index."},
|
925
|
928
|
{ "dyn", kDynSfId, 0, 0, kOutDsvFl| kDoubleDsvFl, "Dynamic value."},
|
926
|
929
|
{ "even", kEvenSfId, 0, 0, kOutDsvFl| kDoubleDsvFl, "Evenness value."},
|
927
|
930
|
{ "tempo", kTempoSfId, 0, 0, kOutDsvFl| kDoubleDsvFl, "Tempo value."},
|
|
@@ -939,6 +942,7 @@ cmDspInst_t* _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
|
939
|
942
|
p->smp = cmScMeasAlloc( ctx->cmProcCtx, NULL, cmScNullHandle, 0, NULL, 0 );
|
940
|
943
|
p->printSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"print");
|
941
|
944
|
p->quietSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"quiet");
|
|
945
|
+ p->maxScLocIdx= cmInvalidIdx;
|
942
|
946
|
|
943
|
947
|
cmDspSetDefaultUInt( ctx, &p->inst, kBufCntSfId, 0, 7);
|
944
|
948
|
cmDspSetDefaultUInt( ctx, &p->inst, kMaxWndCntSfId, 0, 10);
|
|
@@ -946,6 +950,7 @@ cmDspInst_t* _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
|
946
|
950
|
cmDspSetDefaultUInt( ctx, &p->inst, kMinVelSfId, 0, 5);
|
947
|
951
|
cmDspSetDefaultUInt( ctx, &p->inst, kIndexSfId, 0, 0);
|
948
|
952
|
cmDspSetDefaultUInt( ctx, &p->inst, kOutSfId, 0, 0);
|
|
953
|
+ cmDspSetDefaultUInt( ctx, &p->inst, kRecentSfId, 0, 0);
|
949
|
954
|
cmDspSetDefaultDouble( ctx, &p->inst, kDynSfId, 0, 0);
|
950
|
955
|
cmDspSetDefaultDouble( ctx, &p->inst, kEvenSfId, 0, 0);
|
951
|
956
|
cmDspSetDefaultDouble( ctx, &p->inst, kTempoSfId, 0, 0);
|
|
@@ -1094,6 +1099,8 @@ cmDspRC_t _cmDspScFolRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
1094
|
1099
|
case kIndexSfId:
|
1095
|
1100
|
if( cmScoreIsValid(p->scH) )
|
1096
|
1101
|
{
|
|
1102
|
+ p->maxScLocIdx = cmInvalidIdx;
|
|
1103
|
+
|
1097
|
1104
|
if( cmScMeasReset( p->smp ) != cmOkRC )
|
1098
|
1105
|
cmErrMsg(&inst->classPtr->err, kSubSysFailDspRC, "Score measure unit reset to score index '%i' failed.");
|
1099
|
1106
|
|
|
@@ -1115,7 +1122,22 @@ cmDspRC_t _cmDspScFolRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
1115
|
1122
|
// this call may result in a callback to _cmScFolMatcherCb()
|
1116
|
1123
|
if( cmScMatcherExec(p->sfp, cmDspUInt(inst,kSmpIdxSfId), cmDspUInt(inst,kStatusSfId), cmDspUInt(inst,kD0SfId), cmDspUInt(inst,kD1SfId), &scLocIdx) == cmOkRC )
|
1117
|
1124
|
if( scLocIdx != cmInvalidIdx )
|
1118
|
|
- cmDspSetUInt(ctx,inst,kOutSfId,scLocIdx);
|
|
1125
|
+ {
|
|
1126
|
+ // It is possible that the internal score follower may go backwards.
|
|
1127
|
+ // In this case it will report a given score location multiple times or out of time order.
|
|
1128
|
+ // The 'out' port will only be updated under the circumstances that no later
|
|
1129
|
+ // score location has been seen - so the last output from 'out' always reports
|
|
1130
|
+ // the furthest possible progress in the score. THe 'recent' output simply reports
|
|
1131
|
+ // the most recent output from the internal score follower which may include
|
|
1132
|
+ // previously reported or out of order score locations.
|
|
1133
|
+ cmDspSetUInt(ctx,inst,kRecentSfId,scLocIdx);
|
|
1134
|
+
|
|
1135
|
+ if( p->maxScLocIdx==cmInvalidIdx || p->maxScLocIdx < scLocIdx )
|
|
1136
|
+ {
|
|
1137
|
+ p->maxScLocIdx = scLocIdx;
|
|
1138
|
+ cmDspSetUInt(ctx,inst,kOutSfId,scLocIdx);
|
|
1139
|
+ }
|
|
1140
|
+ }
|
1119
|
1141
|
}
|
1120
|
1142
|
break;
|
1121
|
1143
|
|