|
@@ -21,6 +21,7 @@
|
21
|
21
|
#include "cmDspCtx.h"
|
22
|
22
|
#include "cmDspClass.h"
|
23
|
23
|
#include "cmDspUi.h"
|
|
24
|
+#include "cmDspSys.h"
|
24
|
25
|
#include "cmMath.h"
|
25
|
26
|
|
26
|
27
|
|
|
@@ -404,7 +405,16 @@ enum
|
404
|
405
|
{
|
405
|
406
|
kFnScId,
|
406
|
407
|
kSelScId,
|
407
|
|
- kSendScId
|
|
408
|
+ kSendScId,
|
|
409
|
+ kStatusScId,
|
|
410
|
+ kD0ScId,
|
|
411
|
+ kD1ScId,
|
|
412
|
+ kSmpIdxScId,
|
|
413
|
+ kLocIdxScId,
|
|
414
|
+ kEvtIdxScId,
|
|
415
|
+ kDynScId,
|
|
416
|
+ kValTypeScId,
|
|
417
|
+ kValueScId
|
408
|
418
|
};
|
409
|
419
|
|
410
|
420
|
cmDspClass_t _cmScoreDC;
|
|
@@ -413,15 +423,25 @@ typedef struct
|
413
|
423
|
{
|
414
|
424
|
cmDspInst_t inst;
|
415
|
425
|
cmScH_t scH;
|
|
426
|
+ cmDspCtx_t* ctx; // temporary ctx ptr used during cmScore callback in _cmDspScoreRecv()
|
416
|
427
|
} cmDspScore_t;
|
417
|
428
|
|
418
|
429
|
cmDspInst_t* _cmDspScoreAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
|
419
|
430
|
{
|
420
|
431
|
cmDspVarArg_t args[] =
|
421
|
432
|
{
|
422
|
|
- { "fn", kFnScId, 0, 0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "Score file." },
|
423
|
|
- { "sel", kSelScId, 0, 0, kInDsvFl | kOutDsvFl | kUIntDsvFl, "Selected score element index."},
|
424
|
|
- { "send", kSendScId, 0, 0, kInDsvFl | kTypeDsvMask, "Resend last selected score element."},
|
|
433
|
+ { "fn", kFnScId, 0, 0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "Score file." },
|
|
434
|
+ { "sel", kSelScId, 0, 0, kInDsvFl | kOutDsvFl | kUIntDsvFl, "Selected score element index input."},
|
|
435
|
+ { "send", kSendScId, 0, 0, kInDsvFl | kTypeDsvMask, "Resend last selected score element."},
|
|
436
|
+ { "status", kStatusScId, 0, 0, kInDsvFl | kIntDsvFl, "Performed MIDI status value output" },
|
|
437
|
+ { "d0", kD0ScId, 0, 0, kInDsvFl | kUIntDsvFl, "Performed MIDI msg data byte 0" },
|
|
438
|
+ { "d1", kD1ScId, 0, 0, kInDsvFl | kUIntDsvFl, "Performed MIDI msg data byte 1" },
|
|
439
|
+ { "smpidx", kSmpIdxScId, 0, 0, kInDsvFl | kUIntDsvFl, "Performed MIDi msg time tag as a sample index." },
|
|
440
|
+ { "loc", kLocIdxScId, 0, 0, kInDsvFl | kUIntDsvFl, "Performance score location."},
|
|
441
|
+ { "evtidx", kEvtIdxScId, 0, 0, kOutDsvFl | kUIntDsvFl, "Performed event index of following dynamcis level."},
|
|
442
|
+ { "dyn", kDynScId, 0, 0, kOutDsvFl | kUIntDsvFl, "Dynamic level of previous event index."},
|
|
443
|
+ { "type", kValTypeScId,0, 0, kOutDsvFl | kUIntDsvFl, "Output variable type."},
|
|
444
|
+ { "value", kValueScId, 0, 0, kOutDsvFl | kDoubleDsvFl, "Output variable value."},
|
425
|
445
|
{ NULL, 0, 0, 0, 0 }
|
426
|
446
|
};
|
427
|
447
|
|
|
@@ -430,7 +450,7 @@ cmDspInst_t* _cmDspScoreAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
|
430
|
450
|
cmDspSetDefaultUInt( ctx, &p->inst, kSelScId, 0, cmInvalidId);
|
431
|
451
|
|
432
|
452
|
// create the UI control
|
433
|
|
- cmDspUiScoreCreate(ctx,&p->inst,kFnScId,kSelScId);
|
|
453
|
+ cmDspUiScoreCreate(ctx,&p->inst,kFnScId,kSelScId,kSmpIdxScId,kD0ScId,kD1ScId,kLocIdxScId,kEvtIdxScId,kDynScId,kValTypeScId,kValueScId);
|
434
|
454
|
|
435
|
455
|
p->scH = cmScNullHandle;
|
436
|
456
|
|
|
@@ -448,40 +468,94 @@ cmDspRC_t _cmDspScoreFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
448
|
468
|
return rc;
|
449
|
469
|
}
|
450
|
470
|
|
|
471
|
+// Callback from cmScore triggered from _cmDspScoreRecv() during call to cmScoreSetPerfEvent().
|
|
472
|
+void _cmDspScoreCb( void* arg, const void* data, unsigned byteCnt )
|
|
473
|
+{
|
|
474
|
+ cmDspInst_t* inst = (cmDspInst_t*)arg;
|
|
475
|
+ cmDspScore_t* p = (cmDspScore_t*)inst;
|
|
476
|
+ cmScMsg_t m;
|
|
477
|
+ if( cmScoreDecode(data,byteCnt,&m) == kOkScRC )
|
|
478
|
+ {
|
|
479
|
+ switch( m.typeId )
|
|
480
|
+ {
|
|
481
|
+ case kDynMsgScId:
|
|
482
|
+ cmDspSetUInt( p->ctx,inst, kEvtIdxScId, m.u.dyn.evtIdx );
|
|
483
|
+ cmDspSetUInt( p->ctx,inst, kDynScId, m.u.dyn.dynLvl );
|
|
484
|
+ break;
|
|
485
|
+
|
|
486
|
+ case kVarMsgScId:
|
|
487
|
+ cmDspSetUInt( p->ctx,inst, kValTypeScId, m.u.meas.varId);
|
|
488
|
+ cmDspSetDouble(p->ctx,inst, kValueScId, m.u.meas.value);
|
|
489
|
+ break;
|
|
490
|
+
|
|
491
|
+ default:
|
|
492
|
+ { assert(0); }
|
|
493
|
+ }
|
|
494
|
+ }
|
|
495
|
+}
|
451
|
496
|
|
452
|
497
|
cmDspRC_t _cmDspScoreReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
453
|
498
|
{
|
454
|
|
- cmDspRC_t rc = kOkDspRC;
|
455
|
|
- cmDspScore_t* p = (cmDspScore_t*)inst;
|
|
499
|
+ cmDspRC_t rc = kOkDspRC;
|
|
500
|
+ cmDspScore_t* p = (cmDspScore_t*)inst;
|
|
501
|
+ const cmChar_t* tlFn = NULL;
|
|
502
|
+ unsigned* dynRefArray = NULL;
|
|
503
|
+ unsigned dynRefCnt = 0;
|
456
|
504
|
|
457
|
505
|
cmDspApplyAllDefaults(ctx,inst);
|
458
|
506
|
|
459
|
|
- const cmChar_t* tlFn;
|
|
507
|
+
|
|
508
|
+ if( cmDspRsrcUIntArray(ctx->dspH, &dynRefCnt, &dynRefArray, "dynRef", NULL ) != kOkDspRC )
|
|
509
|
+ {
|
|
510
|
+ rc = cmErrMsg(&inst->classPtr->err, kRsrcNotFoundDspRC, "The dynamics reference array resource was not found.");
|
|
511
|
+ goto errLabel;
|
|
512
|
+ }
|
|
513
|
+
|
460
|
514
|
if((tlFn = cmDspStrcz(inst, kFnScId )) != NULL )
|
461
|
|
- if( cmScoreInitialize(ctx->cmCtx, &p->scH, tlFn, NULL, NULL ) != kOkTlRC )
|
|
515
|
+ if( cmScoreInitialize(ctx->cmCtx, &p->scH, tlFn, dynRefArray, dynRefCnt, _cmDspScoreCb, p ) != kOkTlRC )
|
462
|
516
|
rc = cmErrMsg(&inst->classPtr->err, kInstResetFailDspRC, "Score file open failed.");
|
463
|
517
|
|
|
518
|
+ errLabel:
|
464
|
519
|
return rc;
|
465
|
520
|
}
|
466
|
521
|
|
467
|
522
|
cmDspRC_t _cmDspScoreRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
468
|
523
|
{
|
|
524
|
+ cmDspScore_t* p = (cmDspScore_t*)inst;
|
|
525
|
+
|
|
526
|
+ if( evt->dstVarId == kSendScId )
|
|
527
|
+ {
|
|
528
|
+ unsigned selIdx;
|
|
529
|
+ if((selIdx = cmDspUInt(inst,kSelScId)) != cmInvalidIdx )
|
|
530
|
+ {
|
|
531
|
+ cmDspSetUInt(ctx,inst,kSelScId, selIdx );
|
|
532
|
+ cmScoreClearPerfInfo(p->scH);
|
|
533
|
+ }
|
|
534
|
+ return kOkDspRC;
|
|
535
|
+ }
|
|
536
|
+
|
|
537
|
+ cmDspSetEvent(ctx,inst,evt);
|
|
538
|
+
|
469
|
539
|
switch( evt->dstVarId )
|
470
|
540
|
{
|
471
|
541
|
case kSelScId:
|
472
|
|
- cmDspSetEvent(ctx,inst,evt);
|
|
542
|
+ cmScoreClearPerfInfo(p->scH);
|
473
|
543
|
break;
|
474
|
544
|
|
475
|
|
- case kSendScId:
|
|
545
|
+ case kStatusScId:
|
|
546
|
+ //printf("st:%x\n",cmDspUInt(inst,kStatusScId));
|
|
547
|
+ break;
|
|
548
|
+
|
|
549
|
+ case kLocIdxScId:
|
476
|
550
|
{
|
477
|
|
- unsigned selIdx;
|
478
|
|
- if((selIdx = cmDspUInt(inst,kSelScId)) != cmInvalidIdx )
|
479
|
|
- cmDspSetUInt(ctx,inst,kSelScId, selIdx );
|
|
551
|
+ assert( cmDspUInt(inst,kStatusScId ) == kNoteOnMdId );
|
|
552
|
+ p->ctx = ctx; // setup p->ctx for use in _cmDspScoreCb()
|
|
553
|
+
|
|
554
|
+ // this call may result in callbacks to _cmDspScoreCb()
|
|
555
|
+ cmScoreExecPerfEvent(p->scH, cmDspUInt(inst,kLocIdxScId), cmDspUInt(inst,kSmpIdxScId), cmDspUInt(inst,kD0ScId), cmDspUInt(inst,kD1ScId) );
|
480
|
556
|
}
|
481
|
557
|
break;
|
482
|
558
|
|
483
|
|
- default:
|
484
|
|
- {assert(0);}
|
485
|
559
|
}
|
486
|
560
|
|
487
|
561
|
return kOkDspRC;
|
|
@@ -619,6 +693,7 @@ cmDspRC_t _cmDspMidiFilePlayOpen(cmDspCtx_t* ctx, cmDspInst_t* inst )
|
619
|
693
|
|
620
|
694
|
// convert midi msg times to absolute time in samples
|
621
|
695
|
cmMidiFileTickToSamples(p->mfH,cmDspSampleRate(ctx),true);
|
|
696
|
+
|
622
|
697
|
}
|
623
|
698
|
return rc;
|
624
|
699
|
}
|
|
@@ -716,6 +791,7 @@ enum
|
716
|
791
|
kD0SfId,
|
717
|
792
|
kD1SfId,
|
718
|
793
|
kSmpIdxSfId,
|
|
794
|
+ kCmdSfId,
|
719
|
795
|
kOutSfId
|
720
|
796
|
};
|
721
|
797
|
|
|
@@ -724,8 +800,10 @@ cmDspClass_t _cmScFolDC;
|
724
|
800
|
typedef struct
|
725
|
801
|
{
|
726
|
802
|
cmDspInst_t inst;
|
727
|
|
- cmScFol* sfp;
|
|
803
|
+ cmScTrk* sfp;
|
728
|
804
|
cmScH_t scH;
|
|
805
|
+ unsigned printSymId;
|
|
806
|
+ unsigned quietSymId;
|
729
|
807
|
} cmDspScFol_t;
|
730
|
808
|
|
731
|
809
|
cmDspInst_t* _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
|
|
@@ -742,6 +820,7 @@ cmDspInst_t* _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
|
742
|
820
|
{ "d0", kD0SfId, 0, 0, kInDsvFl | kUIntDsvFl, "MIDI data byte 0"},
|
743
|
821
|
{ "d1", kD1SfId, 0, 0, kInDsvFl | kUIntDsvFl, "MIDI data byte 1"},
|
744
|
822
|
{ "smpidx",kSmpIdxSfId, 0, 0, kInDsvFl | kUIntDsvFl, "MIDI time tag as a sample index"},
|
|
823
|
+ { "cmd", kCmdSfId, 0, 0, kInDsvFl | kSymDsvFl, "Command input: print | quiet"},
|
745
|
824
|
{ "out", kOutSfId, 0, 0, kOutDsvFl| kUIntDsvFl, "Current score index."},
|
746
|
825
|
{ NULL, 0, 0, 0, 0, NULL }
|
747
|
826
|
};
|
|
@@ -752,7 +831,9 @@ cmDspInst_t* _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
|
752
|
831
|
return NULL;
|
753
|
832
|
|
754
|
833
|
|
755
|
|
- p->sfp = cmScFolAlloc(ctx->cmProcCtx, NULL, 0, cmScNullHandle, 0, 0, 0, 0 );
|
|
834
|
+ p->sfp = cmScTrkAlloc(ctx->cmProcCtx, NULL, 0, cmScNullHandle, 0, 0, 0, 0 );
|
|
835
|
+ p->printSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"print");
|
|
836
|
+ p->quietSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"quiet");
|
756
|
837
|
|
757
|
838
|
cmDspSetDefaultUInt( ctx, &p->inst, kBufCntSfId, 0, 7);
|
758
|
839
|
cmDspSetDefaultUInt( ctx, &p->inst, kMinLkAhdSfId, 0, 10);
|
|
@@ -760,6 +841,7 @@ cmDspInst_t* _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
|
760
|
841
|
cmDspSetDefaultUInt( ctx, &p->inst, kMinVelSfId, 0, 5);
|
761
|
842
|
cmDspSetDefaultUInt( ctx, &p->inst, kIndexSfId, 0, 0);
|
762
|
843
|
cmDspSetDefaultUInt( ctx, &p->inst, kOutSfId, 0, 0);
|
|
844
|
+ cmDspSetDefaultSymbol(ctx,&p->inst, kCmdSfId, p->quietSymId );
|
763
|
845
|
|
764
|
846
|
return &p->inst;
|
765
|
847
|
}
|
|
@@ -767,23 +849,33 @@ cmDspInst_t* _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
|
767
|
849
|
cmDspRC_t _cmDspScFolFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
768
|
850
|
{
|
769
|
851
|
cmDspScFol_t* p = (cmDspScFol_t*)inst;
|
770
|
|
- cmScFolFree(&p->sfp);
|
|
852
|
+ cmScTrkFree(&p->sfp);
|
771
|
853
|
cmScoreFinalize(&p->scH);
|
772
|
854
|
return kOkDspRC;
|
773
|
855
|
}
|
774
|
856
|
|
775
|
857
|
cmDspRC_t _cmDspScFolOpenScore( cmDspCtx_t* ctx, cmDspInst_t* inst )
|
776
|
858
|
{
|
|
859
|
+ cmDspRC_t rc = kOkDspRC;
|
|
860
|
+ cmDspScFol_t* p = (cmDspScFol_t*)inst;
|
|
861
|
+ unsigned* dynRefArray = NULL;
|
|
862
|
+ unsigned dynRefCnt = 0;
|
777
|
863
|
const cmChar_t* fn;
|
778
|
|
- cmDspScFol_t* p = (cmDspScFol_t*)inst;
|
779
|
864
|
|
780
|
865
|
if((fn = cmDspStrcz(inst,kFnSfId)) == NULL || strlen(fn)==0 )
|
781
|
866
|
return cmErrMsg(&inst->classPtr->err, kInvalidArgDspRC, "No score file name supplied.");
|
782
|
867
|
|
783
|
|
- if( cmScoreInitialize(ctx->cmCtx, &p->scH, fn, NULL, NULL ) != kOkScRC )
|
|
868
|
+ if( cmDspRsrcUIntArray(ctx->dspH, &dynRefCnt, &dynRefArray, "dynRef", NULL ) != kOkDspRC )
|
|
869
|
+ {
|
|
870
|
+ rc = cmErrMsg(&inst->classPtr->err, kRsrcNotFoundDspRC, "The dynamics reference array resource was not found.");
|
|
871
|
+ goto errLabel;
|
|
872
|
+ }
|
|
873
|
+
|
|
874
|
+ if( cmScoreInitialize(ctx->cmCtx, &p->scH, fn, NULL, 0, NULL, NULL ) != kOkScRC )
|
784
|
875
|
return cmErrMsg(&inst->classPtr->err, kSubSysFailDspRC, "Unable to open the score '%s'.",fn);
|
785
|
876
|
|
786
|
|
- return kOkDspRC;
|
|
877
|
+ errLabel:
|
|
878
|
+ return rc;
|
787
|
879
|
}
|
788
|
880
|
|
789
|
881
|
cmDspRC_t _cmDspScFolReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
|
@@ -796,7 +888,7 @@ cmDspRC_t _cmDspScFolReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
796
|
888
|
return rc;
|
797
|
889
|
|
798
|
890
|
if( cmScoreIsValid(p->scH) )
|
799
|
|
- if( cmScFolInit(p->sfp, cmDspSampleRate(ctx), p->scH, cmDspUInt(inst,kBufCntSfId), cmDspUInt(inst,kMinLkAhdSfId), cmDspUInt(inst,kMaxWndCntSfId), cmDspUInt(inst,kMinVelSfId) ) != cmOkRC )
|
|
891
|
+ if( cmScTrkInit(p->sfp, cmDspSampleRate(ctx), p->scH, cmDspUInt(inst,kBufCntSfId), cmDspUInt(inst,kMinLkAhdSfId), cmDspUInt(inst,kMaxWndCntSfId), cmDspUInt(inst,kMinVelSfId) ) != cmOkRC )
|
800
|
892
|
rc = cmErrMsg(&inst->classPtr->err, kSubSysFailDspRC, "Internal score follower allocation failed.");
|
801
|
893
|
|
802
|
894
|
return rc;
|
|
@@ -814,14 +906,14 @@ cmDspRC_t _cmDspScFolRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
814
|
906
|
{
|
815
|
907
|
case kIndexSfId:
|
816
|
908
|
if( cmScoreIsValid(p->scH) )
|
817
|
|
- if( cmScFolReset( p->sfp, cmDspUInt(inst,kIndexSfId) ) != cmOkRC )
|
|
909
|
+ if( cmScTrkReset( p->sfp, cmDspUInt(inst,kIndexSfId) ) != cmOkRC )
|
818
|
910
|
cmErrMsg(&inst->classPtr->err, kSubSysFailDspRC, "Score follower reset to score index '%i' failed.");
|
819
|
911
|
break;
|
820
|
912
|
|
821
|
913
|
case kStatusSfId:
|
822
|
914
|
if( cmScoreIsValid(p->scH))
|
823
|
915
|
{
|
824
|
|
- unsigned idx = cmScFolExec(p->sfp, ctx->cycleCnt, cmDspUInt(inst,kStatusSfId), cmDspUInt(inst,kD0SfId), cmDspUInt(inst,kD1SfId));
|
|
916
|
+ unsigned idx = cmScTrkExec(p->sfp, ctx->cycleCnt, cmDspUInt(inst,kStatusSfId), cmDspUInt(inst,kD0SfId), cmDspUInt(inst,kD1SfId));
|
825
|
917
|
if( idx != cmInvalidIdx )
|
826
|
918
|
cmDspSetUInt(ctx,inst,kOutSfId,idx);
|
827
|
919
|
}
|
|
@@ -830,6 +922,15 @@ cmDspRC_t _cmDspScFolRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
830
|
922
|
case kFnSfId:
|
831
|
923
|
_cmDspScFolOpenScore(ctx,inst);
|
832
|
924
|
break;
|
|
925
|
+
|
|
926
|
+ case kCmdSfId:
|
|
927
|
+ if( cmDspSymbol(inst,kCmdSfId) == p->printSymId )
|
|
928
|
+ p->sfp->printFl = true;
|
|
929
|
+ else
|
|
930
|
+ if( cmDspSymbol(inst,kCmdSfId) == p->quietSymId )
|
|
931
|
+ p->sfp->printFl = false;
|
|
932
|
+
|
|
933
|
+ break;
|
833
|
934
|
}
|
834
|
935
|
}
|
835
|
936
|
|