2012-10-30 03:52:39 +00:00
# include "cmPrefix.h"
# include "cmGlobal.h"
# include "cmFloatTypes.h"
# include "cmComplexTypes.h"
# include "cmRpt.h"
# include "cmErr.h"
# include "cmCtx.h"
# include "cmMem.h"
# include "cmMallocDebug.h"
# include "cmLinkedHeap.h"
# include "cmFile.h"
# include "cmSymTbl.h"
# include "cmJson.h"
2013-02-09 07:48:54 +00:00
# include "cmText.h"
2012-10-30 03:52:39 +00:00
# include "cmPrefs.h"
# include "cmDspValue.h"
# include "cmMsgProtocol.h"
# include "cmThread.h"
# include "cmUdpPort.h"
# include "cmUdpNet.h"
2013-12-15 23:53:16 +00:00
# include "cmTime.h"
2012-10-30 03:52:39 +00:00
# include "cmAudioSys.h"
# include "cmDspCtx.h"
# include "cmDspClass.h"
2013-03-02 01:40:04 +00:00
# include "cmDspStore.h"
2012-10-30 03:52:39 +00:00
# include "cmDspUi.h"
2012-12-13 23:38:45 +00:00
# include "cmDspSys.h"
2012-10-30 03:52:39 +00:00
# include "cmMath.h"
# include "cmAudioFile.h"
# include "cmFileSys.h"
# include "cmProcObj.h"
# include "cmProcTemplateMain.h"
# include "cmProc.h"
# include "cmMidi.h"
# include "cmProc2.h"
# include "cmVectOpsTemplateMain.h"
2012-11-16 20:13:36 +00:00
# include "cmAudioFile.h"
# include "cmMidiFile.h"
# include "cmTimeLine.h"
2012-11-18 01:33:10 +00:00
# include "cmScore.h"
# include "cmProc4.h"
2013-12-15 23:53:16 +00:00
# include "cmSyncRecd.h"
2012-11-16 20:13:36 +00:00
2012-10-30 03:52:39 +00:00
enum
{
kWndSmpCntKrId ,
kHopFactKrId ,
kModeKrId ,
kThreshKrId ,
kLwrSlopeKrId ,
kUprSlopeKrId ,
kOffsetKrId ,
kInvertKrId ,
2013-03-02 01:40:04 +00:00
kBypassKrId ,
kWetKrId ,
2012-10-30 03:52:39 +00:00
kAudioInKrId ,
kAudioOutKrId
} ;
typedef struct
{
cmDspInst_t inst ;
cmCtx * ctx ;
cmSpecDist_t * sdp ;
} cmDspKr_t ;
cmDspClass_t _cmKrDC ;
2012-11-16 01:42:29 +00:00
//==========================================================================================================================================
2012-10-30 03:52:39 +00:00
cmDspInst_t * _cmDspKrAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
cmDspVarArg_t args [ ] =
{
{ " wndn " , kWndSmpCntKrId , 0 , 0 , kInDsvFl | kUIntDsvFl | kReqArgDsvFl , " Window sample count " } ,
{ " hopf " , kHopFactKrId , 0 , 0 , kInDsvFl | kUIntDsvFl | kOptArgDsvFl , " Hop factor " } ,
{ " mode " , kModeKrId , 0 , 0 , kInDsvFl | kUIntDsvFl | kOptArgDsvFl , " Mode 0=bypass 1=basic 2=spec cnt 3=amp env " } ,
{ " thrh " , kThreshKrId , 0 , 0 , kInDsvFl | kDoubleDsvFl | kOptArgDsvFl , " Threshold " } ,
{ " lwrs " , kLwrSlopeKrId , 0 , 0 , kInDsvFl | kDoubleDsvFl | kOptArgDsvFl , " Lower Slope " } ,
{ " uprs " , kUprSlopeKrId , 0 , 0 , kInDsvFl | kDoubleDsvFl | kOptArgDsvFl , " Upper Slope " } ,
{ " offs " , kOffsetKrId , 0 , 0 , kInDsvFl | kDoubleDsvFl | kOptArgDsvFl , " Offset " } ,
{ " invt " , kInvertKrId , 0 , 0 , kInDsvFl | kUIntDsvFl | kOptArgDsvFl , " Invert " } ,
2013-03-02 01:40:04 +00:00
{ " bypass " , kBypassKrId , 0 , 0 , kInDsvFl | kBoolDsvFl | kOptArgDsvFl , " Bypass enable flag. " } ,
{ " wet " , kWetKrId , 0 , 0 , kInDsvFl | kSampleDsvFl , " Wet mix level. " } ,
2012-10-30 03:52:39 +00:00
{ " in " , kAudioInKrId , 0 , 0 , kInDsvFl | kAudioBufDsvFl , " Audio Input " } ,
{ " out " , kAudioOutKrId , 0 , 1 , kOutDsvFl | kAudioBufDsvFl , " Audio Output " } ,
{ NULL , 0 , 0 , 0 , 0 }
} ;
cmDspKr_t * p = cmDspInstAlloc ( cmDspKr_t , ctx , classPtr , args , instSymId , id , storeSymId , va_cnt , vl ) ;
unsigned defWndSmpCnt = cmDspDefaultUInt ( & p - > inst , kWndSmpCntKrId ) ;
unsigned wndSmpCnt = cmNextPowerOfTwo ( defWndSmpCnt ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kWndSmpCntKrId , defWndSmpCnt , wndSmpCnt ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kHopFactKrId , 0 , 4 ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kModeKrId , 0 , kBasicModeSdId ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kThreshKrId , 0 , 60.0 ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kLwrSlopeKrId , 0 , 2.0 ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kUprSlopeKrId , 0 , 0.0 ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kOffsetKrId , 0 , 30.0 ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kInvertKrId , 0 , 0 ) ;
2013-03-02 01:40:04 +00:00
cmDspSetDefaultUInt ( ctx , & p - > inst , kBypassKrId , 0 , 0 ) ;
cmDspSetDefaultSample ( ctx , & p - > inst , kWetKrId , 0 , 1.0 ) ;
2012-10-30 03:52:39 +00:00
//_cmDspKrCmInit(ctx,p); // initialize the cm library
p - > ctx = cmCtxAlloc ( NULL , ctx - > rpt , ctx - > lhH , ctx - > stH ) ;
return & p - > inst ;
}
cmDspRC_t _cmDspKrFree ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspKr_t * p = ( cmDspKr_t * ) inst ;
cmSpecDistFree ( & p - > sdp ) ;
cmCtxFree ( & p - > ctx ) ;
//_cmDspKrCmFinal(ctx,p); // finalize the cm library
return rc ;
}
cmDspRC_t _cmDspKrSetup ( cmDspCtx_t * ctx , cmDspKr_t * p )
{
cmDspRC_t rc = kOkDspRC ;
unsigned wndSmpCnt = cmDspUInt ( & p - > inst , kWndSmpCntKrId ) ;
unsigned hopFact = cmDspUInt ( & p - > inst , kHopFactKrId ) ;
2013-03-02 01:40:04 +00:00
unsigned olaWndTypeId = kHannWndId ;
2012-10-30 03:52:39 +00:00
cmSpecDistFree ( & p - > sdp ) ;
2013-03-02 01:40:04 +00:00
2012-10-30 03:52:39 +00:00
p - > sdp = cmSpecDistAlloc ( p - > ctx , NULL , cmDspSamplesPerCycle ( ctx ) , cmDspSampleRate ( ctx ) , wndSmpCnt , hopFact , olaWndTypeId ) ;
assert ( p - > sdp ! = NULL ) ;
if ( ( rc = cmDspZeroAudioBuf ( ctx , & p - > inst , kAudioOutKrId ) ) ! = kOkDspRC )
return rc ;
return rc ;
}
cmDspRC_t _cmDspKrReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspKr_t * p = ( cmDspKr_t * ) inst ;
cmDspRC_t rc ;
if ( ( rc = cmDspApplyAllDefaults ( ctx , inst ) ) ! = kOkDspRC )
return rc ;
return _cmDspKrSetup ( ctx , p ) ;
}
cmDspRC_t _cmDspKrExec ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspKr_t * p = ( cmDspKr_t * ) inst ;
cmDspRC_t rc = kOkDspRC ;
unsigned iChIdx = 0 ;
const cmSample_t * ip = cmDspAudioBuf ( ctx , inst , kAudioInKrId , iChIdx ) ;
unsigned iSmpCnt = cmDspVarRows ( inst , kAudioInKrId ) ;
2013-02-09 07:48:54 +00:00
// if no connected
if ( iSmpCnt = = 0 )
return rc ;
2012-10-30 03:52:39 +00:00
unsigned oChIdx = 0 ;
cmSample_t * op = cmDspAudioBuf ( ctx , inst , kAudioOutKrId , oChIdx ) ;
unsigned oSmpCnt = cmDspVarRows ( inst , kAudioOutKrId ) ;
const cmSample_t * sp ;
2013-03-02 01:40:04 +00:00
cmSample_t wet = cmDspSample ( inst , kWetKrId ) ;
2012-10-30 03:52:39 +00:00
cmSpecDistExec ( p - > sdp , ip , iSmpCnt ) ;
if ( ( sp = cmSpecDistOut ( p - > sdp ) ) ! = NULL )
2013-03-02 01:40:04 +00:00
{
cmVOS_MultVVS ( op , oSmpCnt , sp , wet ) ;
}
if ( wet < 1.0 )
cmVOS_MultSumVVS ( op , oSmpCnt , ip , 1.0 - wet ) ;
2012-10-30 03:52:39 +00:00
return rc ;
}
cmDspRC_t _cmDspKrRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspKr_t * p = ( cmDspKr_t * ) inst ;
cmDspRC_t rc = kOkDspRC ;
2013-03-02 01:40:04 +00:00
2012-10-30 03:52:39 +00:00
cmDspSetEvent ( ctx , inst , evt ) ;
switch ( evt - > dstVarId )
{
case kWndSmpCntKrId :
case kHopFactKrId :
_cmDspKrSetup ( ctx , p ) ;
2013-03-02 01:40:04 +00:00
// THIS IS A HACK
// WHEN WND OR HOP CHANGE THE RESULTING CHANGES
// SHOULD BE ISOLATED IN cmSpecDist() AND THE
// CURRENT STATE OF THE PARAMETERS SHOULD NOT BE
// LOST - IF THE CHANGES WERE ISOLATED WITHIN PVANL
// AND PVSYN IT MIGHT BE POSSIBLE TO DO WITH
// MINIMAL AUDIO INTERUPTION.
p - > sdp - > mode = cmDspUInt ( inst , kModeKrId ) ;
p - > sdp - > thresh = cmDspDouble ( inst , kThreshKrId ) ;
p - > sdp - > uprSlope = cmDspDouble ( inst , kUprSlopeKrId ) ;
p - > sdp - > lwrSlope = cmDspDouble ( inst , kLwrSlopeKrId ) ;
p - > sdp - > offset = cmDspDouble ( inst , kOffsetKrId ) ;
p - > sdp - > invertFl = cmDspUInt ( inst , kInvertKrId ) ! = 0 ;
2012-10-30 03:52:39 +00:00
printf ( " wsn:%i hsn:%i \n " , p - > sdp - > wndSmpCnt , p - > sdp - > hopSmpCnt ) ;
break ;
case kModeKrId :
p - > sdp - > mode = cmDspUInt ( inst , kModeKrId ) ;
printf ( " mode:%i \n " , p - > sdp - > mode ) ;
break ;
case kThreshKrId :
p - > sdp - > thresh = cmDspDouble ( inst , kThreshKrId ) ;
2013-03-02 01:40:04 +00:00
//printf("thr:p:%p sdp:%p %f\n",p,p->sdp,p->sdp->thresh);
2012-10-30 03:52:39 +00:00
break ;
case kUprSlopeKrId :
p - > sdp - > uprSlope = cmDspDouble ( inst , kUprSlopeKrId ) ;
2013-03-02 01:40:04 +00:00
//printf("upr slope:%f\n",p->sdp->uprSlope);
2012-10-30 03:52:39 +00:00
break ;
case kLwrSlopeKrId :
p - > sdp - > lwrSlope = cmDspDouble ( inst , kLwrSlopeKrId ) ;
2013-03-02 01:40:04 +00:00
//printf("upr slope:%f\n",p->sdp->lwrSlope);
2012-10-30 03:52:39 +00:00
break ;
case kOffsetKrId :
p - > sdp - > offset = cmDspDouble ( inst , kOffsetKrId ) ;
break ;
case kInvertKrId :
p - > sdp - > invertFl = cmDspUInt ( inst , kInvertKrId ) ! = 0 ;
break ;
2013-03-02 01:40:04 +00:00
case kWetKrId :
break ;
2012-10-30 03:52:39 +00:00
default :
{ assert ( 0 ) ; }
}
return rc ;
}
struct cmDspClass_str * cmKrClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmKrDC , ctx , " Kr " ,
NULL ,
_cmDspKrAlloc ,
_cmDspKrFree ,
_cmDspKrReset ,
_cmDspKrExec ,
_cmDspKrRecv ,
NULL , NULL ,
" Fourier based non-linear transformer. " ) ;
return & _cmKrDC ;
}
2012-11-16 01:42:29 +00:00
//==========================================================================================================================================
2012-11-18 01:33:10 +00:00
// Time Line UI Object
2012-11-16 01:42:29 +00:00
enum
{
2012-11-16 18:01:57 +00:00
kTlFileTlId ,
2013-08-12 07:11:59 +00:00
kPrefixPathTlId ,
2012-11-16 20:13:36 +00:00
kSelTlId ,
2012-11-27 07:07:22 +00:00
kCursTlId ,
kResetTlId ,
2012-11-16 20:13:36 +00:00
kAudFnTlId ,
2013-09-26 06:46:11 +00:00
kAudLblTlId ,
2012-11-17 06:07:46 +00:00
kMidiFnTlId ,
2013-09-26 06:46:11 +00:00
kMidiLblTlId ,
2012-11-18 01:33:10 +00:00
kBegAudSmpIdxTlId ,
kEndAudSmpIdxTlId ,
kBegMidiSmpIdxTlId ,
kEndMidiSmpIdxTlId
2012-11-16 01:42:29 +00:00
} ;
cmDspClass_t _cmTimeLineDC ;
typedef struct
{
cmDspInst_t inst ;
2012-11-16 20:13:36 +00:00
cmTlH_t tlH ;
2012-11-27 07:07:22 +00:00
unsigned afIdx ;
2012-11-16 01:42:29 +00:00
} cmDspTimeLine_t ;
cmDspInst_t * _cmDspTimeLineAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
cmDspVarArg_t args [ ] =
{
2012-11-27 07:07:22 +00:00
{ " tlfile " , kTlFileTlId , 0 , 0 , kInDsvFl | kStrzDsvFl | kReqArgDsvFl , " Time line file. " } ,
2013-08-12 07:11:59 +00:00
{ " path " , kPrefixPathTlId , 0 , 0 , kInDsvFl | kStrzDsvFl | kReqArgDsvFl , " Time line data file prefix path " } ,
2012-11-27 07:07:22 +00:00
{ " sel " , kSelTlId , 0 , 0 , kInDsvFl | kOutDsvFl | kUIntDsvFl , " Selected marker id. " } ,
{ " curs " , kCursTlId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Current audio file index. " } ,
{ " reset " , kResetTlId , 0 , 0 , kInDsvFl | kSymDsvFl , " Resend all outputs. " } ,
{ " afn " , kAudFnTlId , 0 , 0 , kOutDsvFl | kStrzDsvFl , " Selected Audio file. " } ,
2013-09-26 06:46:11 +00:00
{ " albl " , kAudLblTlId , 0 , 0 , kOutDsvFl | kStrzDsvFl , " Select Audio file time line label. " } ,
2012-11-27 07:07:22 +00:00
{ " mfn " , kMidiFnTlId , 0 , 0 , kOutDsvFl | kStrzDsvFl , " Selected MIDI file. " } ,
2013-09-26 06:46:11 +00:00
{ " mlbl " , kMidiLblTlId , 0 , 0 , kOutDsvFl | kStrzDsvFl , " Select MIDI file time line label. " } ,
2012-11-27 07:07:22 +00:00
{ " absi " , kBegAudSmpIdxTlId , 0 , 0 , kOutDsvFl | kIntDsvFl , " Begin audio sample index. " } ,
{ " aesi " , kEndAudSmpIdxTlId , 0 , 0 , kOutDsvFl | kIntDsvFl , " End audio sample index. " } ,
{ " mbsi " , kBegMidiSmpIdxTlId , 0 , 0 , kOutDsvFl | kIntDsvFl , " Begin MIDI sample index. " } ,
{ " mesi " , kEndMidiSmpIdxTlId , 0 , 0 , kOutDsvFl | kIntDsvFl , " End MIDI sample index. " } ,
2012-11-16 01:42:29 +00:00
{ NULL , 0 , 0 , 0 , 0 }
} ;
cmDspTimeLine_t * p = cmDspInstAlloc ( cmDspTimeLine_t , ctx , classPtr , args , instSymId , id , storeSymId , va_cnt , vl ) ;
2012-11-16 20:13:36 +00:00
2012-11-18 01:33:10 +00:00
cmDspSetDefaultUInt ( ctx , & p - > inst , kSelTlId , 0 , cmInvalidId ) ;
2012-11-27 07:07:22 +00:00
cmDspSetDefaultUInt ( ctx , & p - > inst , kCursTlId , 0 , 0 ) ;
2012-11-18 01:33:10 +00:00
cmDspSetDefaultStrcz ( ctx , & p - > inst , kAudFnTlId , NULL , " " ) ;
2013-09-26 06:46:11 +00:00
cmDspSetDefaultStrcz ( ctx , & p - > inst , kAudLblTlId , NULL , " " ) ;
2012-11-18 01:33:10 +00:00
cmDspSetDefaultStrcz ( ctx , & p - > inst , kMidiFnTlId , NULL , " " ) ;
2013-09-26 06:46:11 +00:00
cmDspSetDefaultStrcz ( ctx , & p - > inst , kMidiLblTlId , NULL , " " ) ;
2012-11-18 01:33:10 +00:00
cmDspSetDefaultInt ( ctx , & p - > inst , kBegAudSmpIdxTlId , 0 , cmInvalidIdx ) ;
cmDspSetDefaultInt ( ctx , & p - > inst , kEndAudSmpIdxTlId , 0 , cmInvalidIdx ) ;
cmDspSetDefaultInt ( ctx , & p - > inst , kBegMidiSmpIdxTlId , 0 , cmInvalidIdx ) ;
cmDspSetDefaultInt ( ctx , & p - > inst , kEndMidiSmpIdxTlId , 0 , cmInvalidIdx ) ;
2012-11-16 01:42:29 +00:00
// create the UI control
2013-08-12 07:11:59 +00:00
cmDspUiTimeLineCreate ( ctx , & p - > inst , kTlFileTlId , kPrefixPathTlId , kSelTlId , kCursTlId ) ;
2012-11-16 20:13:36 +00:00
p - > tlH = cmTimeLineNullHandle ;
2012-11-16 01:42:29 +00:00
return & p - > inst ;
}
2012-11-16 20:13:36 +00:00
cmDspRC_t _cmDspTimeLineFree ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspTimeLine_t * p = ( cmDspTimeLine_t * ) inst ;
if ( cmTimeLineFinalize ( & p - > tlH ) ! = kOkTlRC )
return cmErrMsg ( & inst - > classPtr - > err , kInstFinalFailDspRC , " Time-line finalize failed. " ) ;
return rc ;
}
2012-11-16 01:42:29 +00:00
cmDspRC_t _cmDspTimeLineReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
2012-11-16 20:13:36 +00:00
cmDspRC_t rc = kOkDspRC ;
cmDspTimeLine_t * p = ( cmDspTimeLine_t * ) inst ;
2012-11-16 01:42:29 +00:00
cmDspApplyAllDefaults ( ctx , inst ) ;
2012-11-16 20:13:36 +00:00
const cmChar_t * tlFn ;
2013-08-12 07:11:59 +00:00
const cmChar_t * tlPrePath = cmDspStrcz ( inst , kPrefixPathTlId ) ;
2012-11-16 20:13:36 +00:00
if ( ( tlFn = cmDspStrcz ( inst , kTlFileTlId ) ) ! = NULL )
2013-08-12 07:11:59 +00:00
if ( cmTimeLineInitializeFromFile ( ctx - > cmCtx , & p - > tlH , NULL , NULL , tlFn , tlPrePath ) ! = kOkTlRC )
rc = cmErrMsg ( & inst - > classPtr - > err , kInstResetFailDspRC , " Time-line file open failed. " ) ;
2012-11-16 20:13:36 +00:00
return rc ;
2012-11-16 01:42:29 +00:00
}
cmDspRC_t _cmDspTimeLineRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
2012-11-17 06:07:46 +00:00
cmDspTimeLine_t * p = ( cmDspTimeLine_t * ) inst ;
2012-11-16 01:42:29 +00:00
switch ( evt - > dstVarId )
{
2013-08-12 07:11:59 +00:00
case kPrefixPathTlId :
2013-05-22 22:13:41 +00:00
cmDspSetEvent ( ctx , inst , evt ) ;
break ;
2012-11-27 07:07:22 +00:00
case kCursTlId :
cmDspSetEvent ( ctx , inst , evt ) ;
break ;
case kResetTlId :
2012-11-16 20:13:36 +00:00
case kSelTlId :
2012-11-17 06:07:46 +00:00
{
unsigned markerId ;
cmDspSetEvent ( ctx , inst , evt ) ;
// get the id of the selected marker
if ( ( markerId = cmDspUInt ( inst , kSelTlId ) ) ! = cmInvalidId )
{
// get the marker object
cmTlObj_t * op ;
if ( ( op = cmTimeLineIdToObj ( p - > tlH , cmInvalidId , markerId ) ) ! = NULL )
{
assert ( op - > typeId = = kMarkerTlId ) ;
2012-11-27 07:07:22 +00:00
p - > afIdx = op - > begSmpIdx ;
2012-11-18 01:33:10 +00:00
cmDspSetInt ( ctx , inst , kBegAudSmpIdxTlId , op - > begSmpIdx ) ;
cmDspSetInt ( ctx , inst , kEndAudSmpIdxTlId , op - > begSmpIdx + op - > durSmpCnt ) ;
2012-11-17 06:07:46 +00:00
// locate the audio file assoc'd with the marker
cmTlAudioFile_t * afp ;
if ( ( afp = cmTimeLineAudioFileAtTime ( p - > tlH , op - > seqId , op - > seqSmpIdx ) ) ! = NULL )
2013-09-26 06:46:11 +00:00
{
2012-11-17 06:07:46 +00:00
cmDspSetStrcz ( ctx , inst , kAudFnTlId , afp - > fn ) ;
2013-09-26 06:46:11 +00:00
cmDspSetStrcz ( ctx , inst , kAudLblTlId , afp - > obj . name ) ;
}
2012-11-17 06:07:46 +00:00
// locate the midi file assoc'd with the marker
cmTlMidiFile_t * mfp ;
if ( ( mfp = cmTimeLineMidiFileAtTime ( p - > tlH , op - > seqId , op - > seqSmpIdx ) ) ! = NULL )
2012-11-18 01:33:10 +00:00
{
cmDspSetInt ( ctx , inst , kBegMidiSmpIdxTlId , op - > seqSmpIdx - mfp - > obj . seqSmpIdx ) ;
cmDspSetInt ( ctx , inst , kEndMidiSmpIdxTlId , op - > seqSmpIdx + op - > durSmpCnt - mfp - > obj . seqSmpIdx ) ;
2012-11-17 06:07:46 +00:00
cmDspSetStrcz ( ctx , inst , kMidiFnTlId , mfp - > fn ) ;
2013-09-26 06:46:11 +00:00
cmDspSetStrcz ( ctx , inst , kMidiLblTlId , mfp - > obj . name ) ;
2012-11-18 01:33:10 +00:00
}
2012-11-17 06:07:46 +00:00
}
}
}
2012-11-16 20:13:36 +00:00
2012-11-16 01:42:29 +00:00
break ;
default :
{ assert ( 0 ) ; }
}
return kOkDspRC ;
}
struct cmDspClass_str * cmTimeLineClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmTimeLineDC , ctx , " TimeLine " ,
NULL ,
_cmDspTimeLineAlloc ,
2012-11-16 20:13:36 +00:00
_cmDspTimeLineFree ,
2012-11-16 01:42:29 +00:00
_cmDspTimeLineReset ,
NULL ,
_cmDspTimeLineRecv ,
NULL , NULL ,
" Time Line control. " ) ;
return & _cmTimeLineDC ;
}
2012-11-27 07:07:22 +00:00
//==========================================================================================================================================
// Score UI Object
enum
{
kFnScId ,
kSelScId ,
2012-12-13 23:38:45 +00:00
kSendScId ,
kStatusScId ,
kD0ScId ,
kD1ScId ,
kSmpIdxScId ,
kLocIdxScId ,
2013-12-18 15:01:47 +00:00
kCmdScId ,
2012-12-13 23:38:45 +00:00
kEvtIdxScId ,
kDynScId ,
kValTypeScId ,
kValueScId
2012-11-27 07:07:22 +00:00
} ;
cmDspClass_t _cmScoreDC ;
typedef struct
{
cmDspInst_t inst ;
cmScH_t scH ;
2012-12-13 23:38:45 +00:00
cmDspCtx_t * ctx ; // temporary ctx ptr used during cmScore callback in _cmDspScoreRecv()
2013-12-18 15:01:47 +00:00
unsigned printSymId ;
2012-11-27 07:07:22 +00:00
} cmDspScore_t ;
cmDspInst_t * _cmDspScoreAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
cmDspVarArg_t args [ ] =
{
2012-12-13 23:38:45 +00:00
{ " fn " , kFnScId , 0 , 0 , kInDsvFl | kStrzDsvFl | kReqArgDsvFl , " Score file. " } ,
{ " sel " , kSelScId , 0 , 0 , kInDsvFl | kOutDsvFl | kUIntDsvFl , " Selected score element index input. " } ,
{ " send " , kSendScId , 0 , 0 , kInDsvFl | kTypeDsvMask , " Resend last selected score element. " } ,
{ " status " , kStatusScId , 0 , 0 , kInDsvFl | kIntDsvFl , " Performed MIDI status value output " } ,
{ " d0 " , kD0ScId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Performed MIDI msg data byte 0 " } ,
{ " d1 " , kD1ScId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Performed MIDI msg data byte 1 " } ,
{ " smpidx " , kSmpIdxScId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Performed MIDi msg time tag as a sample index. " } ,
{ " loc " , kLocIdxScId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Performance score location. " } ,
2013-12-18 15:01:47 +00:00
{ " cmd " , kCmdScId , 0 , 0 , kInDsvFl | kSymDsvFl , " cmd: dump " } ,
2012-12-13 23:38:45 +00:00
{ " evtidx " , kEvtIdxScId , 0 , 0 , kOutDsvFl | kUIntDsvFl , " Performed event index of following dynamcis level. " } ,
{ " dyn " , kDynScId , 0 , 0 , kOutDsvFl | kUIntDsvFl , " Dynamic level of previous event index. " } ,
{ " type " , kValTypeScId , 0 , 0 , kOutDsvFl | kUIntDsvFl , " Output variable type. " } ,
{ " value " , kValueScId , 0 , 0 , kOutDsvFl | kDoubleDsvFl , " Output variable value. " } ,
2012-11-27 07:07:22 +00:00
{ NULL , 0 , 0 , 0 , 0 }
} ;
cmDspScore_t * p = cmDspInstAlloc ( cmDspScore_t , ctx , classPtr , args , instSymId , id , storeSymId , va_cnt , vl ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kSelScId , 0 , cmInvalidId ) ;
2013-12-18 15:01:47 +00:00
p - > printSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " dump " ) ;
2012-11-27 07:07:22 +00:00
// create the UI control
2012-12-13 23:38:45 +00:00
cmDspUiScoreCreate ( ctx , & p - > inst , kFnScId , kSelScId , kSmpIdxScId , kD0ScId , kD1ScId , kLocIdxScId , kEvtIdxScId , kDynScId , kValTypeScId , kValueScId ) ;
2012-11-27 07:07:22 +00:00
p - > scH = cmScNullHandle ;
return & p - > inst ;
}
cmDspRC_t _cmDspScoreFree ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspScore_t * p = ( cmDspScore_t * ) inst ;
if ( cmScoreFinalize ( & p - > scH ) ! = kOkTlRC )
return cmErrMsg ( & inst - > classPtr - > err , kInstFinalFailDspRC , " Score finalize failed. " ) ;
return rc ;
}
2012-12-13 23:38:45 +00:00
// Callback from cmScore triggered from _cmDspScoreRecv() during call to cmScoreSetPerfEvent().
void _cmDspScoreCb ( void * arg , const void * data , unsigned byteCnt )
{
cmDspInst_t * inst = ( cmDspInst_t * ) arg ;
cmDspScore_t * p = ( cmDspScore_t * ) inst ;
cmScMsg_t m ;
if ( cmScoreDecode ( data , byteCnt , & m ) = = kOkScRC )
{
switch ( m . typeId )
{
case kDynMsgScId :
cmDspSetUInt ( p - > ctx , inst , kEvtIdxScId , m . u . dyn . evtIdx ) ;
cmDspSetUInt ( p - > ctx , inst , kDynScId , m . u . dyn . dynLvl ) ;
break ;
case kVarMsgScId :
cmDspSetUInt ( p - > ctx , inst , kValTypeScId , m . u . meas . varId ) ;
cmDspSetDouble ( p - > ctx , inst , kValueScId , m . u . meas . value ) ;
break ;
default :
{ assert ( 0 ) ; }
}
}
}
2012-11-27 07:07:22 +00:00
cmDspRC_t _cmDspScoreReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
2012-12-13 23:38:45 +00:00
cmDspRC_t rc = kOkDspRC ;
cmDspScore_t * p = ( cmDspScore_t * ) inst ;
const cmChar_t * tlFn = NULL ;
unsigned * dynRefArray = NULL ;
unsigned dynRefCnt = 0 ;
2012-11-27 07:07:22 +00:00
cmDspApplyAllDefaults ( ctx , inst ) ;
2012-12-13 23:38:45 +00:00
if ( cmDspRsrcUIntArray ( ctx - > dspH , & dynRefCnt , & dynRefArray , " dynRef " , NULL ) ! = kOkDspRC )
{
rc = cmErrMsg ( & inst - > classPtr - > err , kRsrcNotFoundDspRC , " The dynamics reference array resource was not found. " ) ;
goto errLabel ;
}
2012-11-27 07:07:22 +00:00
if ( ( tlFn = cmDspStrcz ( inst , kFnScId ) ) ! = NULL )
2013-11-20 03:30:10 +00:00
{
2013-11-19 06:30:27 +00:00
if ( cmScoreInitialize ( ctx - > cmCtx , & p - > scH , tlFn , cmDspSampleRate ( ctx ) , dynRefArray , dynRefCnt , _cmDspScoreCb , p , ctx - > stH ) ! = kOkTlRC )
2012-11-27 07:07:22 +00:00
rc = cmErrMsg ( & inst - > classPtr - > err , kInstResetFailDspRC , " Score file open failed. " ) ;
2013-11-20 03:30:10 +00:00
//else
// cmScorePrintLoc(p->scH);
}
2012-12-13 23:38:45 +00:00
errLabel :
2012-11-27 07:07:22 +00:00
return rc ;
}
cmDspRC_t _cmDspScoreRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
2012-12-13 23:38:45 +00:00
cmDspScore_t * p = ( cmDspScore_t * ) inst ;
if ( evt - > dstVarId = = kSendScId )
{
unsigned selIdx ;
if ( ( selIdx = cmDspUInt ( inst , kSelScId ) ) ! = cmInvalidIdx )
{
cmDspSetUInt ( ctx , inst , kSelScId , selIdx ) ;
cmScoreClearPerfInfo ( p - > scH ) ;
}
return kOkDspRC ;
}
cmDspSetEvent ( ctx , inst , evt ) ;
2012-11-27 07:07:22 +00:00
switch ( evt - > dstVarId )
{
case kSelScId :
2012-12-13 23:38:45 +00:00
cmScoreClearPerfInfo ( p - > scH ) ;
2012-11-27 07:07:22 +00:00
break ;
2012-12-13 23:38:45 +00:00
case kStatusScId :
//printf("st:%x\n",cmDspUInt(inst,kStatusScId));
break ;
case kLocIdxScId :
2012-11-27 07:07:22 +00:00
{
2012-12-13 23:38:45 +00:00
assert ( cmDspUInt ( inst , kStatusScId ) = = kNoteOnMdId ) ;
p - > ctx = ctx ; // setup p->ctx for use in _cmDspScoreCb()
// this call may result in callbacks to _cmDspScoreCb()
cmScoreExecPerfEvent ( p - > scH , cmDspUInt ( inst , kLocIdxScId ) , cmDspUInt ( inst , kSmpIdxScId ) , cmDspUInt ( inst , kD0ScId ) , cmDspUInt ( inst , kD1ScId ) ) ;
2012-11-27 07:07:22 +00:00
}
break ;
2013-12-18 15:01:47 +00:00
case kCmdScId :
if ( cmDspSymbol ( inst , kCmdScId ) = = p - > printSymId )
cmScorePrintLoc ( p - > scH ) ;
break ;
2012-11-27 07:07:22 +00:00
}
return kOkDspRC ;
}
struct cmDspClass_str * cmScoreClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmScoreDC , ctx , " Score " ,
NULL ,
_cmDspScoreAlloc ,
_cmDspScoreFree ,
_cmDspScoreReset ,
NULL ,
_cmDspScoreRecv ,
NULL , NULL ,
" Score control. " ) ;
return & _cmScoreDC ;
}
2012-11-17 06:07:46 +00:00
//==========================================================================================================================================
2012-11-18 01:33:10 +00:00
// MIDI File Player
2012-11-17 06:07:46 +00:00
enum
{
kFnMfId ,
kSelMfId ,
kBsiMfId ,
kEsiMfId ,
kStatusMfId ,
kD0MfId ,
2012-12-04 01:12:09 +00:00
kD1MfId ,
2013-09-26 06:46:11 +00:00
kSmpIdxMfId ,
kIdMfId
2012-11-17 06:07:46 +00:00
} ;
cmDspClass_t _cmMidiFilePlayDC ;
typedef struct
{
cmDspInst_t inst ;
cmMidiFileH_t mfH ;
2012-11-18 01:33:10 +00:00
unsigned curMsgIdx ; // current midi file msg index
int csi ; // current sample index
int bsi ; // starting sample index
int esi ; // ending sample index
2012-11-17 06:07:46 +00:00
unsigned startSymId ;
unsigned stopSymId ;
unsigned contSymId ;
2012-12-17 20:53:41 +00:00
bool errFl ;
2012-11-17 06:07:46 +00:00
} cmDspMidiFilePlay_t ;
/*
' bsi ' and ' esi ' give the starting and ending sample for MIDI file playback .
These indexes are relative to the start of the file .
When the player recieves a ' start ' msg it sets the current sample index
' si ' to ' bsi ' and begins scanning for the next note to play .
On each call to the _cmDspMidiFilePlayExec ( ) msgs that fall in the interval
si : si + sPc - 1 will be transmitted . ( where sPc are the number of samples per DSP cycle ) .
*/
cmDspInst_t * _cmDspMidiFilePlayAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
cmDspVarArg_t args [ ] =
{
2012-11-18 01:33:10 +00:00
{ " fn " , kFnMfId , 0 , 0 , kInDsvFl | kStrzDsvFl , " File name " } ,
2012-11-17 06:07:46 +00:00
{ " sel " , kSelMfId , 0 , 0 , kInDsvFl | kSymDsvFl , " start | stop | continue " } ,
2012-12-04 01:12:09 +00:00
{ " bsi " , kBsiMfId , 0 , 0 , kInDsvFl | kIntDsvFl , " Starting sample. " } ,
{ " esi " , kEsiMfId , 0 , 0 , kInDsvFl | kIntDsvFl , " Ending sample. " } ,
{ " status " , kStatusMfId , 0 , 0 , kOutDsvFl | kIntDsvFl , " Status value output " } ,
2012-11-17 06:07:46 +00:00
{ " d0 " , kD0MfId , 0 , 0 , kOutDsvFl | kUIntDsvFl , " Data byte 0 " } ,
{ " d1 " , kD1MfId , 0 , 0 , kOutDsvFl | kUIntDsvFl , " Data byte 1 " } ,
2013-09-26 06:46:11 +00:00
{ " smpidx " , kSmpIdxMfId , 0 , 0 , kOutDsvFl | kUIntDsvFl , " Msg time tag as a sample index. " } ,
{ " id " , kIdMfId , 0 , 0 , kOutDsvFl | kUIntDsvFl , " MIDI file msg unique id. " } ,
2012-11-17 06:07:46 +00:00
{ NULL , 0 , 0 , 0 , 0 }
} ;
cmDspMidiFilePlay_t * p = cmDspInstAlloc ( cmDspMidiFilePlay_t , ctx , classPtr , args , instSymId , id , storeSymId , va_cnt , vl ) ;
p - > startSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " start " ) ;
p - > stopSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " stop " ) ;
p - > contSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " continue " ) ;
p - > mfH = cmMidiFileNullHandle ;
2012-11-18 01:33:10 +00:00
cmDspSetDefaultStrcz ( ctx , & p - > inst , kFnMfId , NULL , " " ) ;
cmDspSetDefaultSymbol ( ctx , & p - > inst , kSelMfId , p - > stopSymId ) ;
cmDspSetDefaultInt ( ctx , & p - > inst , kBsiMfId , 0 , 0 ) ;
cmDspSetDefaultInt ( ctx , & p - > inst , kEsiMfId , 0 , 0 ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kStatusMfId , 0 , 0 ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kD0MfId , 0 , 0 ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kD1MfId , 0 , 0 ) ;
2012-11-17 06:07:46 +00:00
return & p - > inst ;
}
cmDspRC_t _cmDspMidiFilePlayFree ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspMidiFilePlay_t * p = ( cmDspMidiFilePlay_t * ) inst ;
if ( cmMidiFileClose ( & p - > mfH ) )
return cmErrMsg ( & inst - > classPtr - > err , kInstFinalFailDspRC , " MIDI file close failed. " ) ;
return kOkDspRC ;
}
// return the index of the msg following smpIdx
2012-12-17 20:53:41 +00:00
unsigned _cmDspMidiFilePlaySeekMsgIdx ( cmDspCtx_t * ctx , cmDspInst_t * inst , unsigned smpIdx )
2012-11-17 06:07:46 +00:00
{
2012-12-17 20:53:41 +00:00
cmDspMidiFilePlay_t * p = ( cmDspMidiFilePlay_t * ) inst ;
if ( cmMidiFileIsValid ( p - > mfH ) = = false )
{
cmErrMsg ( & inst - > classPtr - > err , kInvalidStateDspRC , " The MIDI file player has not been given a valid MIDI file. " ) ;
return cmInvalidIdx ;
}
2012-11-17 06:07:46 +00:00
unsigned i ;
unsigned n = cmMidiFileMsgCount ( p - > mfH ) ;
const cmMidiTrackMsg_t * * a = cmMidiFileMsgArray ( p - > mfH ) ;
for ( i = 0 ; i < n ; + + i )
2012-11-18 01:33:10 +00:00
if ( a [ i ] - > dtick > smpIdx )
2012-11-17 06:07:46 +00:00
break ;
return i = = n ? cmInvalidIdx : i ;
}
cmDspRC_t _cmDspMidiFilePlayOpen ( cmDspCtx_t * ctx , cmDspInst_t * inst )
{
2012-11-18 01:33:10 +00:00
cmDspRC_t rc = kOkDspRC ;
const cmChar_t * fn = cmDspStrcz ( inst , kFnMfId ) ;
2012-11-17 06:07:46 +00:00
cmDspMidiFilePlay_t * p = ( cmDspMidiFilePlay_t * ) inst ;
2012-12-17 20:53:41 +00:00
p - > errFl = false ;
2012-11-18 01:33:10 +00:00
if ( fn = = NULL | | strlen ( fn ) = = 0 )
return rc ;
2012-11-17 06:07:46 +00:00
if ( cmMidiFileOpen ( fn , & p - > mfH , ctx - > cmCtx ) ! = kOkFileRC )
rc = cmErrMsg ( & inst - > classPtr - > err , kInstResetFailDspRC , " MIDI file open failed. " ) ;
else
{
2012-11-18 01:33:10 +00:00
p - > curMsgIdx = 0 ;
p - > bsi = cmDspInt ( inst , kBsiMfId ) ;
p - > esi = cmDspInt ( inst , kEsiMfId ) ;
p - > csi = 0 ;
2012-12-17 20:53:41 +00:00
2012-11-18 01:33:10 +00:00
// force the first msg to occurr one quarter note into the file
cmMidiFileSetDelay ( p - > mfH , cmMidiFileTicksPerQN ( p - > mfH ) ) ;
// convert midi msg times to absolute time in samples
cmMidiFileTickToSamples ( p - > mfH , cmDspSampleRate ( ctx ) , true ) ;
2012-12-13 23:38:45 +00:00
2012-11-17 06:07:46 +00:00
}
return rc ;
}
cmDspRC_t _cmDspMidiFilePlayReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspApplyAllDefaults ( ctx , inst ) ;
return _cmDspMidiFilePlayOpen ( ctx , inst ) ;
}
cmDspRC_t _cmDspMidiFilePlayExec ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
2012-11-18 01:33:10 +00:00
cmDspRC_t rc = kOkDspRC ;
cmDspMidiFilePlay_t * p = ( cmDspMidiFilePlay_t * ) inst ;
unsigned sPc = cmDspSamplesPerCycle ( ctx ) ;
2012-11-17 06:07:46 +00:00
2012-12-17 20:53:41 +00:00
2012-11-18 01:33:10 +00:00
if ( cmDspSymbol ( inst , kSelMfId ) ! = p - > stopSymId )
{
2012-12-17 20:53:41 +00:00
if ( cmMidiFileIsValid ( p - > mfH ) = = false )
{
if ( p - > errFl = = false )
{
rc = cmErrMsg ( & inst - > classPtr - > err , kInvalidStateDspRC , " The MIDI file player has not been given a valid MIDI file. " ) ;
p - > errFl = true ;
}
return rc ;
}
2012-11-18 01:33:10 +00:00
const cmMidiTrackMsg_t * * mpp = cmMidiFileMsgArray ( p - > mfH ) ;
unsigned msgN = cmMidiFileMsgCount ( p - > mfH ) ;
2012-11-17 06:07:46 +00:00
2012-11-18 01:33:10 +00:00
for ( ; p - > curMsgIdx < msgN & & p - > csi < = mpp [ p - > curMsgIdx ] - > dtick & & mpp [ p - > curMsgIdx ] - > dtick < ( p - > csi + sPc ) ; + + p - > curMsgIdx )
{
const cmMidiTrackMsg_t * mp = mpp [ p - > curMsgIdx ] ;
switch ( mp - > status )
{
2013-09-30 01:46:48 +00:00
case kNoteOffMdId :
2012-11-18 01:33:10 +00:00
case kNoteOnMdId :
case kCtlMdId :
2012-12-04 01:12:09 +00:00
cmDspSetUInt ( ctx , inst , kSmpIdxMfId , mp - > dtick ) ;
2012-11-18 01:33:10 +00:00
cmDspSetUInt ( ctx , inst , kD1MfId , mp - > u . chMsgPtr - > d1 ) ;
cmDspSetUInt ( ctx , inst , kD0MfId , mp - > u . chMsgPtr - > d0 ) ;
cmDspSetUInt ( ctx , inst , kStatusMfId , mp - > status ) ;
2013-09-26 06:46:11 +00:00
cmDspSetUInt ( ctx , inst , kIdMfId , mp - > uid ) ;
2012-11-18 01:33:10 +00:00
break ;
}
}
}
2012-11-17 06:07:46 +00:00
2012-11-18 01:33:10 +00:00
p - > csi + = sPc ;
2012-11-17 06:07:46 +00:00
return rc ;
}
cmDspRC_t _cmDspMidiFilePlayRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspMidiFilePlay_t * p = ( cmDspMidiFilePlay_t * ) inst ;
cmDspSetEvent ( ctx , inst , evt ) ;
switch ( evt - > dstVarId )
{
case kFnMfId :
_cmDspMidiFilePlayOpen ( ctx , inst ) ;
break ;
case kSelMfId :
{
if ( cmDspSymbol ( inst , kSelMfId ) = = p - > startSymId )
{
2012-11-18 01:33:10 +00:00
p - > csi = cmDspInt ( inst , kBsiMfId ) ;
2012-12-17 20:53:41 +00:00
p - > curMsgIdx = _cmDspMidiFilePlaySeekMsgIdx ( ctx , inst , p - > csi ) ;
2012-11-17 06:07:46 +00:00
}
break ;
}
2012-11-18 01:33:10 +00:00
}
2012-11-17 06:07:46 +00:00
return kOkDspRC ;
}
struct cmDspClass_str * cmMidiFilePlayClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmMidiFilePlayDC , ctx , " MidiFilePlay " ,
NULL ,
_cmDspMidiFilePlayAlloc ,
_cmDspMidiFilePlayFree ,
_cmDspMidiFilePlayReset ,
_cmDspMidiFilePlayExec ,
_cmDspMidiFilePlayRecv ,
NULL , NULL ,
2013-09-26 06:46:11 +00:00
" MIDI file player. " ) ;
2012-11-17 06:07:46 +00:00
return & _cmMidiFilePlayDC ;
}
2012-11-18 01:33:10 +00:00
//==========================================================================================================================================
enum
{
kFnSfId ,
2012-11-27 22:20:54 +00:00
kBufCntSfId ,
2012-12-04 01:12:09 +00:00
kMaxWndCntSfId ,
kMinVelSfId ,
2013-12-10 21:32:19 +00:00
kMeasflSfId ,
2012-11-18 01:33:10 +00:00
kIndexSfId ,
kStatusSfId ,
kD0SfId ,
kD1SfId ,
2012-12-04 01:12:09 +00:00
kSmpIdxSfId ,
2012-12-13 23:38:45 +00:00
kCmdSfId ,
2013-01-31 01:37:23 +00:00
kOutSfId ,
2013-11-03 19:53:17 +00:00
kRecentSfId ,
2013-12-10 21:32:19 +00:00
kVlocSfId ,
kVtypSfId ,
kVvalSfId ,
kVcostSfId ,
2013-03-02 01:40:04 +00:00
kSymSfId
2012-11-18 01:33:10 +00:00
} ;
cmDspClass_t _cmScFolDC ;
2013-01-31 01:37:23 +00:00
struct cmDspScFol_str ;
2012-11-18 01:33:10 +00:00
typedef struct
{
2013-01-31 01:37:23 +00:00
cmDspCtx_t * ctx ;
struct cmDspScFol_str * sfp ;
} cmDspScFolCbArg_t ;
typedef struct cmDspScFol_str
{
cmDspInst_t inst ;
cmScMatcher * sfp ;
cmScMeas * smp ;
cmScH_t scH ;
cmDspScFolCbArg_t arg ;
unsigned printSymId ;
unsigned quietSymId ;
2013-11-03 19:53:17 +00:00
unsigned maxScLocIdx ;
2013-12-10 21:32:19 +00:00
bool liveFl ;
2012-11-18 01:33:10 +00:00
} cmDspScFol_t ;
cmDspInst_t * _cmDspScFolAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
cmDspVarArg_t args [ ] =
{
2013-12-10 21:32:19 +00:00
{ " fn " , kFnSfId , 0 , 0 , kInDsvFl | kStrzDsvFl | kReqArgDsvFl , " Score file. " } ,
{ " bufcnt " , kBufCntSfId , 0 , 0 , kInDsvFl | kUIntDsvFl | kOptArgDsvFl , " Event buffer element count. " } ,
{ " wndcnt " , kMaxWndCntSfId , 0 , 0 , kInDsvFl | kUIntDsvFl | kOptArgDsvFl , " Maximum window length. " } ,
{ " minvel " , kMinVelSfId , 0 , 0 , kInDsvFl | kUIntDsvFl | kOptArgDsvFl , " Minimum velocity. " } ,
{ " measfl " , kMeasflSfId , 0 , 0 , kInDsvFl | kBoolDsvFl | kOptArgDsvFl , " Enable measurements " } ,
2012-12-04 01:12:09 +00:00
{ " index " , kIndexSfId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Tracking start location. " } ,
{ " status " , kStatusSfId , 0 , 0 , kInDsvFl | kUIntDsvFl , " MIDI status byte " } ,
{ " d0 " , kD0SfId , 0 , 0 , kInDsvFl | kUIntDsvFl , " MIDI data byte 0 " } ,
{ " d1 " , kD1SfId , 0 , 0 , kInDsvFl | kUIntDsvFl , " MIDI data byte 1 " } ,
{ " smpidx " , kSmpIdxSfId , 0 , 0 , kInDsvFl | kUIntDsvFl , " MIDI time tag as a sample index " } ,
2012-12-13 23:38:45 +00:00
{ " cmd " , kCmdSfId , 0 , 0 , kInDsvFl | kSymDsvFl , " Command input: print | quiet " } ,
2013-11-03 19:53:17 +00:00
{ " out " , kOutSfId , 0 , 0 , kOutDsvFl | kUIntDsvFl , " Maximum score location index. " } ,
{ " recent " , kRecentSfId , 0 , 0 , kOutDsvFl | kUIntDsvFl , " Most recent score location index. " } ,
2013-12-10 21:32:19 +00:00
{ " vloc " , kVlocSfId , 0 , 0 , kOutDsvFl | kUIntDsvFl , " Score location at which the variable value becomes active. " } ,
{ " vtyp " , kVtypSfId , 0 , 0 , kOutDsvFl | kUIntDsvFl , " Variable type: 0=even=kEvenVarScId 1=dyn=kDynVarScId 2=tempo=kTempoVarScId. " } ,
{ " vval " , kVvalSfId , 0 , 0 , kOutDsvFl | kDoubleDsvFl , " Variable value. " } ,
{ " vcost " , kVcostSfId , 0 , 0 , kOutDsvFl | kDoubleDsvFl , " Variable match cost value. " } ,
2013-03-02 01:40:04 +00:00
{ " sym " , kSymSfId , 0 , 0 , kOutDsvFl | kSymDsvFl , " Symbol associated with a global variable which has changed value. " } ,
2012-12-04 01:12:09 +00:00
{ NULL , 0 , 0 , 0 , 0 , NULL }
2012-11-18 01:33:10 +00:00
} ;
cmDspScFol_t * p ;
if ( ( p = cmDspInstAlloc ( cmDspScFol_t , ctx , classPtr , args , instSymId , id , storeSymId , va_cnt , vl ) ) = = NULL )
return NULL ;
2013-01-31 01:37:23 +00:00
p - > sfp = cmScMatcherAlloc ( ctx - > cmProcCtx , NULL , 0 , cmScNullHandle , 0 , 0 , NULL , NULL ) ;
p - > smp = cmScMeasAlloc ( ctx - > cmProcCtx , NULL , cmScNullHandle , 0 , NULL , 0 ) ;
2012-12-13 23:38:45 +00:00
p - > printSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " print " ) ;
p - > quietSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " quiet " ) ;
2013-11-03 19:53:17 +00:00
p - > maxScLocIdx = cmInvalidIdx ;
2012-11-18 01:33:10 +00:00
2013-01-31 01:37:23 +00:00
cmDspSetDefaultUInt ( ctx , & p - > inst , kBufCntSfId , 0 , 7 ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kMaxWndCntSfId , 0 , 10 ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kMinVelSfId , 0 , 5 ) ;
2013-12-10 21:32:19 +00:00
cmDspSetDefaultBool ( ctx , & p - > inst , kMeasflSfId , 0 , 0 ) ;
2013-01-31 01:37:23 +00:00
cmDspSetDefaultUInt ( ctx , & p - > inst , kIndexSfId , 0 , 0 ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kOutSfId , 0 , 0 ) ;
2013-11-03 19:53:17 +00:00
cmDspSetDefaultUInt ( ctx , & p - > inst , kRecentSfId , 0 , 0 ) ;
2013-01-31 01:37:23 +00:00
cmDspSetDefaultSymbol ( ctx , & p - > inst , kCmdSfId , p - > quietSymId ) ;
2012-11-18 01:33:10 +00:00
return & p - > inst ;
}
cmDspRC_t _cmDspScFolFree ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspScFol_t * p = ( cmDspScFol_t * ) inst ;
2013-01-31 01:37:23 +00:00
cmScMatcherFree ( & p - > sfp ) ;
cmScMeasFree ( & p - > smp ) ;
2012-11-18 01:33:10 +00:00
cmScoreFinalize ( & p - > scH ) ;
return kOkDspRC ;
}
2013-02-09 07:48:54 +00:00
// This is a callback function from cmScMatcherExec() which is called when
// this cmDspFol object receives a new score location index.
2013-01-31 01:37:23 +00:00
void _cmScFolMatcherCb ( cmScMatcher * p , void * arg , cmScMatcherResult_t * rp )
{
cmDspScFolCbArg_t * ap = ( cmDspScFolCbArg_t * ) arg ;
2013-02-09 07:48:54 +00:00
2013-01-31 01:37:23 +00:00
if ( cmScMeasExec ( ap - > sfp - > smp , rp - > mni , rp - > locIdx , rp - > scEvtIdx , rp - > flags , rp - > smpIdx , rp - > pitch , rp - > vel ) = = cmOkRC )
{
2013-02-09 07:48:54 +00:00
cmDspInst_t * inst = & ( ap - > sfp - > inst ) ;
2013-01-31 01:37:23 +00:00
2013-02-09 07:48:54 +00:00
// send 'set' values that were calculated on the previous call to cmScMeasExec()
2013-01-31 01:37:23 +00:00
unsigned i ;
2013-02-09 07:48:54 +00:00
for ( i = ap - > sfp - > smp - > vsi ; i < ap - > sfp - > smp - > nsi ; + + i )
2013-05-26 16:34:40 +00:00
if ( ap - > sfp - > smp - > set [ i ] . value ! = DBL_MAX )
2013-01-31 01:37:23 +00:00
{
2013-12-10 21:32:19 +00:00
/*
2013-10-16 23:29:48 +00:00
switch ( ap - > sfp - > smp - > set [ i ] . sp - > varId )
{
case kEvenVarScId :
cmDspSetDouble ( ap - > ctx , inst , kEvenSfId , ap - > sfp - > smp - > set [ i ] . value ) ;
break ;
2013-01-31 01:37:23 +00:00
2013-10-16 23:29:48 +00:00
case kDynVarScId :
cmDspSetDouble ( ap - > ctx , inst , kDynSfId , ap - > sfp - > smp - > set [ i ] . value ) ;
break ;
2013-01-31 01:37:23 +00:00
2013-10-16 23:29:48 +00:00
case kTempoVarScId :
cmDspSetDouble ( ap - > ctx , inst , kTempoSfId , ap - > sfp - > smp - > set [ i ] . value ) ;
break ;
2013-03-02 01:40:04 +00:00
2013-10-16 23:29:48 +00:00
default :
{ assert ( 0 ) ; }
}
2013-03-02 01:40:04 +00:00
2013-10-16 23:29:48 +00:00
cmDspSetDouble ( ap - > ctx , inst , kCostSfId , ap - > sfp - > smp - > set [ i ] . match_cost ) ;
2013-12-10 21:32:19 +00:00
*/
2013-03-02 01:40:04 +00:00
2013-10-16 23:29:48 +00:00
// Set the values in the global variable storage
cmDspValue_t vv , cv ;
unsigned j ;
cmDsvSetDouble ( & vv , ap - > sfp - > smp - > set [ i ] . value ) ;
cmDsvSetDouble ( & cv , ap - > sfp - > smp - > set [ i ] . match_cost ) ;
2013-03-02 01:40:04 +00:00
2013-10-16 23:29:48 +00:00
for ( j = 0 ; j < ap - > sfp - > smp - > set [ i ] . sp - > sectCnt ; + + j )
{
cmDspStoreSetValueViaSym ( ap - > ctx - > dsH , ap - > sfp - > smp - > set [ i ] . sp - > symArray [ j ] , & vv ) ;
cmDspStoreSetValueViaSym ( ap - > ctx - > dsH , ap - > sfp - > smp - > set [ i ] . sp - > costSymArray [ j ] , & cv ) ;
cmDspSetSymbol ( ap - > ctx , inst , kSymSfId , ap - > sfp - > smp - > set [ i ] . sp - > symArray [ j ] ) ;
cmDspSetSymbol ( ap - > ctx , inst , kSymSfId , ap - > sfp - > smp - > set [ i ] . sp - > costSymArray [ j ] ) ;
2013-12-10 21:32:19 +00:00
if ( cmDspBool ( inst , kMeasflSfId ) )
{
cmDspSetUInt ( ap - > ctx , inst , kVlocSfId , ap - > sfp - > smp - > set [ i ] . sp - > sectArray [ j ] - > locPtr - > index ) ;
cmDspSetDouble ( ap - > ctx , inst , kVvalSfId , ap - > sfp - > smp - > set [ i ] . value ) ;
cmDspSetDouble ( ap - > ctx , inst , kVcostSfId , ap - > sfp - > smp - > set [ i ] . match_cost ) ;
cmDspSetUInt ( ap - > ctx , inst , kVtypSfId , ap - > sfp - > smp - > set [ i ] . sp - > varId ) ;
}
2013-10-16 23:29:48 +00:00
}
2013-03-02 01:40:04 +00:00
2013-10-16 23:29:48 +00:00
}
2013-02-09 07:48:54 +00:00
/*
// trigger 'section' starts
for ( i = ap - > sfp - > smp - > vsli ; i < ap - > sfp - > smp - > nsli ; + + i )
{
const cmScoreLoc_t * locPtr = cmScoreLoc ( ap - > sfp - > smp - > mp - > scH , i ) ;
if ( locPtr - > begSectPtr ! = NULL )
cmDspSetUInt ( ap - > ctx , inst , kSectIndexSfId , locPtr - > begSectPtr - > index ) ;
}
*/
2013-01-31 01:37:23 +00:00
}
}
2012-11-18 01:33:10 +00:00
cmDspRC_t _cmDspScFolOpenScore ( cmDspCtx_t * ctx , cmDspInst_t * inst )
{
2013-01-31 01:37:23 +00:00
cmDspRC_t rc = kOkDspRC ;
cmDspScFol_t * p = ( cmDspScFol_t * ) inst ;
2012-11-18 01:33:10 +00:00
const cmChar_t * fn ;
if ( ( fn = cmDspStrcz ( inst , kFnSfId ) ) = = NULL | | strlen ( fn ) = = 0 )
return cmErrMsg ( & inst - > classPtr - > err , kInvalidArgDspRC , " No score file name supplied. " ) ;
2013-03-02 01:40:04 +00:00
if ( cmScoreInitialize ( ctx - > cmCtx , & p - > scH , fn , cmDspSampleRate ( ctx ) , NULL , 0 , NULL , NULL , ctx - > stH ) ! = kOkScRC )
2012-11-18 01:33:10 +00:00
return cmErrMsg ( & inst - > classPtr - > err , kSubSysFailDspRC , " Unable to open the score '%s'. " , fn ) ;
2013-01-31 01:37:23 +00:00
if ( cmScoreIsValid ( p - > scH ) )
{
unsigned * dynRefArray = NULL ;
unsigned dynRefCnt = 0 ;
// initialize the cmScMatcher
if ( cmScMatcherInit ( p - > sfp , cmDspSampleRate ( ctx ) , p - > scH , cmDspUInt ( inst , kMaxWndCntSfId ) , cmDspUInt ( inst , kBufCntSfId ) , _cmScFolMatcherCb , p - > smp ) ! = cmOkRC )
rc = cmErrMsg ( & inst - > classPtr - > err , kSubSysFailDspRC , " Internal score follower allocation failed. " ) ;
// read the dynamics reference array
if ( cmDspRsrcUIntArray ( ctx - > dspH , & dynRefCnt , & dynRefArray , " dynRef " , NULL ) ! = kOkDspRC )
{
rc = cmErrMsg ( & inst - > classPtr - > err , kRsrcNotFoundDspRC , " The dynamics reference array resource was not found. " ) ;
goto errLabel ;
}
// initialize the cmScMeas object.
if ( cmScMeasInit ( p - > smp , p - > scH , cmDspSampleRate ( ctx ) , dynRefArray , dynRefCnt ) ! = cmOkRC )
rc = cmErrMsg ( & inst - > classPtr - > err , kSubSysFailDspRC , " Internal scMeas object initialization failed. " ) ;
}
2012-12-13 23:38:45 +00:00
errLabel :
return rc ;
2012-11-18 01:33:10 +00:00
}
cmDspRC_t _cmDspScFolReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
2013-01-31 01:37:23 +00:00
cmDspRC_t rc ;
if ( ( rc = cmDspApplyAllDefaults ( ctx , inst ) ) ! = kOkDspRC )
2012-11-18 01:33:10 +00:00
return rc ;
2013-01-31 01:37:23 +00:00
return _cmDspScFolOpenScore ( ctx , inst ) ;
2012-11-18 01:33:10 +00:00
}
cmDspRC_t _cmDspScFolRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspScFol_t * p = ( cmDspScFol_t * ) inst ;
if ( ( rc = cmDspSetEvent ( ctx , inst , evt ) ) = = kOkDspRC & & p - > sfp ! = NULL )
{
switch ( evt - > dstVarId )
{
case kIndexSfId :
2012-11-19 06:41:27 +00:00
if ( cmScoreIsValid ( p - > scH ) )
2013-01-31 01:37:23 +00:00
{
2013-11-03 19:53:17 +00:00
p - > maxScLocIdx = cmInvalidIdx ;
2013-01-31 01:37:23 +00:00
if ( cmScMeasReset ( p - > smp ) ! = cmOkRC )
cmErrMsg ( & inst - > classPtr - > err , kSubSysFailDspRC , " Score measure unit reset to score index '%i' failed. " ) ;
if ( cmScMatcherReset ( p - > sfp , cmDspUInt ( inst , kIndexSfId ) ) ! = cmOkRC )
2012-11-19 06:41:27 +00:00
cmErrMsg ( & inst - > classPtr - > err , kSubSysFailDspRC , " Score follower reset to score index '%i' failed. " ) ;
2013-01-31 01:37:23 +00:00
}
2012-11-18 01:33:10 +00:00
break ;
case kStatusSfId :
2012-11-19 06:41:27 +00:00
if ( cmScoreIsValid ( p - > scH ) )
2012-11-18 01:33:10 +00:00
{
2013-01-31 01:37:23 +00:00
unsigned scLocIdx = cmInvalidIdx ;
// setup the cmScMeas() callback arg.
p - > arg . ctx = ctx ;
p - > arg . sfp = p ;
p - > sfp - > cbArg = & p - > arg ;
// this call may result in a callback to _cmScFolMatcherCb()
if ( cmScMatcherExec ( p - > sfp , cmDspUInt ( inst , kSmpIdxSfId ) , cmDspUInt ( inst , kStatusSfId ) , cmDspUInt ( inst , kD0SfId ) , cmDspUInt ( inst , kD1SfId ) , & scLocIdx ) = = cmOkRC )
if ( scLocIdx ! = cmInvalidIdx )
2013-11-03 19:53:17 +00:00
{
// It is possible that the internal score follower may go backwards.
// In this case it will report a given score location multiple times or out of time order.
// The 'out' port will only be updated under the circumstances that no later
// score location has been seen - so the last output from 'out' always reports
// the furthest possible progress in the score. THe 'recent' output simply reports
// the most recent output from the internal score follower which may include
// previously reported or out of order score locations.
cmDspSetUInt ( ctx , inst , kRecentSfId , scLocIdx ) ;
if ( p - > maxScLocIdx = = cmInvalidIdx | | p - > maxScLocIdx < scLocIdx )
{
p - > maxScLocIdx = scLocIdx ;
cmDspSetUInt ( ctx , inst , kOutSfId , scLocIdx ) ;
}
}
2012-11-18 01:33:10 +00:00
}
break ;
case kFnSfId :
_cmDspScFolOpenScore ( ctx , inst ) ;
break ;
2012-12-13 23:38:45 +00:00
case kCmdSfId :
if ( cmDspSymbol ( inst , kCmdSfId ) = = p - > printSymId )
p - > sfp - > printFl = true ;
else
if ( cmDspSymbol ( inst , kCmdSfId ) = = p - > quietSymId )
p - > sfp - > printFl = false ;
break ;
2012-11-18 01:33:10 +00:00
}
}
return rc ;
}
struct cmDspClass_str * cmScFolClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmScFolDC , ctx , " ScFol " ,
NULL ,
_cmDspScFolAlloc ,
_cmDspScFolFree ,
_cmDspScFolReset ,
NULL ,
_cmDspScFolRecv ,
NULL , NULL ,
" Score Follower " ) ;
return & _cmScFolDC ;
}
2013-02-09 07:48:54 +00:00
//==========================================================================================================================================
enum
{
2013-03-02 01:40:04 +00:00
kScLocIdxMdId ,
kResetIdxMdId ,
2013-09-30 18:03:47 +00:00
kCmdMdId ,
kPostMdId
2013-02-09 07:48:54 +00:00
} ;
cmDspClass_t _cmModulatorDC ;
typedef struct
{
cmDspInst_t inst ;
cmScModulator * mp ;
cmDspCtx_t * tmp_ctx ; // used to temporarily hold the current cmDspCtx during callback
2013-03-02 01:40:04 +00:00
cmChar_t * fn ;
cmChar_t * modLabel ;
unsigned onSymId ;
unsigned offSymId ;
2013-09-30 18:03:47 +00:00
unsigned postSymId ;
2013-02-09 07:48:54 +00:00
} cmDspScMod_t ;
2013-09-30 18:03:47 +00:00
void _cmDspScModCb ( void * arg , unsigned varSymId , double value , bool postFl )
2013-02-09 07:48:54 +00:00
{
cmDspScMod_t * p = ( cmDspScMod_t * ) arg ;
cmDspVar_t * varPtr ;
if ( ( varPtr = cmDspVarSymbolToPtr ( p - > tmp_ctx , & p - > inst , varSymId , 0 ) ) = = NULL )
return ;
cmDspSetDouble ( p - > tmp_ctx , & p - > inst , varPtr - > constId , value ) ;
2013-09-30 18:03:47 +00:00
if ( postFl )
cmDspSetSymbol ( p - > tmp_ctx , & p - > inst , kPostMdId , p - > postSymId ) ;
2013-02-09 07:48:54 +00:00
}
cmDspInst_t * _cmDspScModAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
va_list vl1 ;
va_copy ( vl1 , vl ) ;
cmDspVarArg_t args [ ] =
{
2013-03-02 01:40:04 +00:00
{ " index " , kScLocIdxMdId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Score follower index input. " } ,
{ " reset " , kResetIdxMdId , 0 , 0 , kInDsvFl | kUIntDsvFl | kOptArgDsvFl , " Reset the modulator and go to the score index. " } ,
{ " cmd " , kCmdMdId , 0 , 0 , kInDsvFl | kSymDsvFl | kOptArgDsvFl , " on | off. " } ,
2013-09-30 18:03:47 +00:00
{ " post " , kPostMdId , 0 , 0 , kOutDsvFl | kSymDsvFl , " Sends 'post' symbol after a message transmission if the 'post' flag is set in scMod. " } ,
2013-02-09 07:48:54 +00:00
{ NULL , 0 , 0 , 0 , 0 }
} ;
// validate the argument count
if ( va_cnt ! = 2 )
{
cmDspClassErr ( ctx , classPtr , kInvalidArgDspRC , " The Modulator requires at least two arguments. " ) ;
return NULL ;
}
// read the modulator file and label strings
const cmChar_t * fn = va_arg ( vl1 , const cmChar_t * ) ;
const cmChar_t * modLabel = va_arg ( vl1 , const cmChar_t * ) ;
2013-03-02 01:40:04 +00:00
va_end ( vl1 ) ;
2013-02-09 07:48:54 +00:00
// validate the file
if ( fn = = NULL | | cmFsIsFile ( fn ) = = false )
{
cmDspClassErr ( ctx , classPtr , kInvalidArgDspRC , " The Modulator file '%s' is not valid. " , cmStringNullGuard ( fn ) ) ;
return NULL ;
}
// allocate the internal modulator object
cmScModulator * mp = cmScModulatorAlloc ( ctx - > cmProcCtx , NULL , ctx - > cmCtx , ctx - > stH , cmDspSampleRate ( ctx ) , cmDspSamplesPerCycle ( ctx ) , fn , modLabel , _cmDspScModCb , NULL ) ;
if ( mp = = NULL )
{
cmDspClassErr ( ctx , classPtr , kInvalidArgDspRC , " The internal modulator object initialization failed. " ) ;
return NULL ;
}
2013-03-02 01:40:04 +00:00
unsigned fixArgCnt = sizeof ( args ) / sizeof ( args [ 0 ] ) - 1 ;
unsigned argCnt = fixArgCnt + cmScModulatorOutVarCount ( mp ) ;
2013-02-09 07:48:54 +00:00
cmDspVarArg_t a [ argCnt + 1 ] ;
unsigned i ;
cmDspArgCopy ( a , argCnt , 0 , args , fixArgCnt ) ;
for ( i = fixArgCnt ; i < argCnt ; + + i )
{
unsigned varIdx = i - fixArgCnt ;
2013-03-02 01:40:04 +00:00
const cmScModVar_t * vp = cmScModulatorOutVar ( mp , varIdx ) ;
2013-02-09 07:48:54 +00:00
const cmChar_t * label = cmSymTblLabel ( ctx - > stH , vp - > varSymId ) ;
const cmChar_t * docStr = cmTsPrintfS ( " Variable output for %s " , label ) ;
cmDspArgSetup ( ctx , a + i , label , cmInvalidId , i , 0 , 0 , kOutDsvFl | kDoubleDsvFl , docStr ) ;
}
cmDspArgSetupNull ( a + argCnt ) ; // set terminating arg. flags
2013-03-02 01:40:04 +00:00
cmDspScMod_t * p = cmDspInstAlloc ( cmDspScMod_t , ctx , classPtr , a , instSymId , id , storeSymId , va_cnt , vl ) ;
p - > fn = cmMemAllocStr ( fn ) ;
p - > modLabel = cmMemAllocStr ( modLabel ) ;
p - > mp = mp ;
p - > onSymId = cmSymTblId ( ctx - > stH , " on " ) ;
p - > offSymId = cmSymTblId ( ctx - > stH , " off " ) ;
2013-09-30 18:03:47 +00:00
p - > postSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " post " ) ;
2013-02-09 07:48:54 +00:00
mp - > cbArg = p ; // set the modulator callback arg
2013-03-02 01:40:04 +00:00
2013-02-09 07:48:54 +00:00
2013-03-02 01:40:04 +00:00
cmDspSetDefaultUInt ( ctx , & p - > inst , kScLocIdxMdId , 0 , 0 ) ;
cmDspSetDefaultSymbol ( ctx , & p - > inst , kCmdMdId , p - > offSymId ) ;
2013-02-09 07:48:54 +00:00
return & p - > inst ;
}
cmDspRC_t _cmDspScModFree ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspScMod_t * p = ( cmDspScMod_t * ) inst ;
2013-03-02 01:40:04 +00:00
2013-02-09 07:48:54 +00:00
if ( cmScModulatorFree ( & p - > mp ) ! = kOkTlRC )
return cmErrMsg ( & inst - > classPtr - > err , kInstFinalFailDspRC , " Modulator release failed. " ) ;
2013-03-02 01:40:04 +00:00
cmMemFree ( p - > fn ) ;
cmMemFree ( p - > modLabel ) ;
2013-02-09 07:48:54 +00:00
return rc ;
}
cmDspRC_t _cmDspScModReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspApplyAllDefaults ( ctx , inst ) ;
return rc ;
}
cmDspRC_t _cmDspScModRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
2013-03-02 01:40:04 +00:00
cmDspScMod_t * p = ( cmDspScMod_t * ) inst ;
2013-02-09 07:48:54 +00:00
cmDspSetEvent ( ctx , inst , evt ) ;
2013-03-02 01:40:04 +00:00
switch ( evt - > dstVarId )
{
case kResetIdxMdId :
cmDspSetUInt ( ctx , inst , kScLocIdxMdId , cmDspUInt ( inst , kResetIdxMdId ) ) ;
break ;
case kCmdMdId :
{
unsigned symId = cmDspSymbol ( inst , kCmdMdId ) ;
if ( symId = = p - > onSymId )
cmScModulatorReset ( p - > mp , ctx - > cmCtx , cmDspUInt ( inst , kScLocIdxMdId ) ) ;
}
break ;
}
2013-02-09 07:48:54 +00:00
return kOkDspRC ;
}
cmDspRC_t _cmDspScModExec ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspScMod_t * p = ( cmDspScMod_t * ) inst ;
2013-03-02 01:40:04 +00:00
if ( cmDspSymbol ( inst , kCmdMdId ) ! = p - > offSymId )
{
p - > tmp_ctx = ctx ;
cmScModulatorExec ( p - > mp , cmDspUInt ( inst , kScLocIdxMdId ) ) ;
}
2013-02-09 07:48:54 +00:00
return rc ;
}
struct cmDspClass_str * cmScModClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmModulatorDC , ctx , " ScMod " ,
NULL ,
_cmDspScModAlloc ,
_cmDspScModFree ,
_cmDspScModReset ,
_cmDspScModExec ,
_cmDspScModRecv ,
NULL , NULL ,
" Score Driven Variable Modulator. " ) ;
return & _cmModulatorDC ;
}
2013-03-02 01:40:04 +00:00
//==========================================================================================================================================
enum
{
kInChCntGsId ,
kOutGroupCntGsId ,
kGroupSelIdxGsId ,
kBaseInFloatGsId
} ;
cmDspClass_t _cmGSwitchDC ;
typedef struct
{
cmDspInst_t inst ;
unsigned iChCnt ;
unsigned oGroupCnt ;
unsigned baseInFloatGsId ;
unsigned baseInSymGsId ;
unsigned baseInBoolGsId ;
unsigned baseOutFloatGsId ;
unsigned baseOutSymGsId ;
unsigned baseOutBoolGsId ;
} cmDspGSwitch_t ;
cmDspInst_t * _cmDspGSwitchAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
va_list vl1 ;
va_copy ( vl1 , vl ) ;
cmDspVarArg_t args [ ] =
{
{ " ichs " , kInChCntGsId , 0 , 0 , kUIntDsvFl | kReqArgDsvFl , " Input channel count. " } ,
{ " ochs " , kOutGroupCntGsId , 0 , 0 , kUIntDsvFl | kReqArgDsvFl , " Output group count. " } ,
{ " sel " , kGroupSelIdxGsId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Group select index. " } ,
{ NULL , 0 , 0 , 0 , 0 }
} ;
// validate the argument count
if ( va_cnt ! = 2 )
{
cmDspClassErr ( ctx , classPtr , kInvalidArgDspRC , " The GSwitch requires at least two arguments. " ) ;
return NULL ;
}
// read the input ch and output group count
unsigned iChCnt = va_arg ( vl1 , unsigned ) ;
unsigned oGroupCnt = va_arg ( vl1 , unsigned ) ;
va_end ( vl1 ) ;
// validate the channel counts
if ( iChCnt = = 0 | | oGroupCnt = = 0 )
{
cmDspClassErr ( ctx , classPtr , kInvalidArgDspRC , " The GSwitch input channel count and group count must be greater than zero. " ) ;
return NULL ;
}
unsigned typeCnt = 3 ; // i.e. float,sym,bool
unsigned baseInFloatGsId = kBaseInFloatGsId ;
unsigned baseInSymGsId = baseInFloatGsId + iChCnt ;
unsigned baseInBoolGsId = baseInSymGsId + iChCnt ;
unsigned baseOutFloatGsId = baseInBoolGsId + iChCnt ;
unsigned baseOutSymGsId = baseOutFloatGsId + ( iChCnt * oGroupCnt ) ;
unsigned baseOutBoolGsId = baseOutSymGsId + ( iChCnt * oGroupCnt ) ;
unsigned fixArgCnt = 3 ;
unsigned varArgCnt = ( iChCnt * typeCnt ) + ( iChCnt * typeCnt * oGroupCnt ) ;
unsigned argCnt = fixArgCnt + varArgCnt ;
cmDspVarArg_t a [ argCnt + 1 ] ;
unsigned i ;
cmDspArgCopy ( a , argCnt , 0 , args , fixArgCnt ) ;
cmDspArgSetupN ( ctx , a , argCnt , baseInFloatGsId , iChCnt , " f-in " , baseInFloatGsId , 0 , 0 , kInDsvFl | kDoubleDsvFl , " Float input " ) ;
cmDspArgSetupN ( ctx , a , argCnt , baseInSymGsId , iChCnt , " s-in " , baseInSymGsId , 0 , 0 , kInDsvFl | kSymDsvFl , " Symbol input " ) ;
cmDspArgSetupN ( ctx , a , argCnt , baseInBoolGsId , iChCnt , " b-in " , baseInBoolGsId , 0 , 0 , kInDsvFl | kBoolDsvFl , " Bool input " ) ;
unsigned labelCharCnt = 63 ;
cmChar_t label [ labelCharCnt + 1 ] ;
label [ labelCharCnt ] = 0 ;
unsigned gsid = baseOutFloatGsId ;
for ( i = 0 ; i < oGroupCnt ; + + i , gsid + = iChCnt )
{
snprintf ( label , labelCharCnt , " f-out-%i " , i ) ;
cmDspArgSetupN ( ctx , a , argCnt , gsid , iChCnt , label , gsid , 0 , 0 , kInDsvFl | kDoubleDsvFl , " Float output " ) ;
}
gsid = baseOutSymGsId ;
for ( i = 0 ; i < oGroupCnt ; + + i , gsid + = iChCnt )
{
snprintf ( label , labelCharCnt , " s-out-%i " , i ) ;
cmDspArgSetupN ( ctx , a , argCnt , gsid , iChCnt , label , gsid , 0 , 0 , kInDsvFl | kSymDsvFl , " Symbol output " ) ;
}
gsid = baseOutBoolGsId ;
for ( i = 0 ; i < oGroupCnt ; + + i , gsid + = iChCnt )
{
snprintf ( label , labelCharCnt , " b-out-%i " , i ) ;
cmDspArgSetupN ( ctx , a , argCnt , gsid , iChCnt , label , gsid , 0 , 0 , kInDsvFl | kBoolDsvFl , " Bool output " ) ;
}
cmDspArgSetupNull ( a + argCnt ) ; // set terminating arg. flags
cmDspGSwitch_t * p = cmDspInstAlloc ( cmDspGSwitch_t , ctx , classPtr , a , instSymId , id , storeSymId , va_cnt , vl ) ;
p - > iChCnt = iChCnt ;
p - > oGroupCnt = oGroupCnt ;
p - > baseInFloatGsId = baseInFloatGsId ;
p - > baseInSymGsId = baseInSymGsId ;
p - > baseInBoolGsId = baseInBoolGsId ;
p - > baseOutFloatGsId = baseOutFloatGsId ;
p - > baseOutSymGsId = baseOutSymGsId ;
p - > baseOutBoolGsId = baseOutBoolGsId ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kGroupSelIdxGsId , 0 , 0 ) ;
return & p - > inst ;
}
cmDspRC_t _cmDspGSwitchReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspApplyAllDefaults ( ctx , inst ) ;
return rc ;
}
cmDspRC_t _cmDspGSwitchRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspGSwitch_t * p = ( cmDspGSwitch_t * ) inst ;
// if this is the group selector
if ( evt - > dstVarId = = kGroupSelIdxGsId )
{
unsigned idx ;
if ( ( idx = cmDsvGetUInt ( evt - > valuePtr ) ) > p - > oGroupCnt )
cmDspInstErr ( ctx , inst , kInvalidArgDspRC , " The GSwitch group select index %i is out of range %i. " , idx , p - > oGroupCnt ) ;
else
cmDspSetEvent ( ctx , inst , evt ) ;
return rc ;
}
// get the group selector
unsigned groupIdx = cmDspUInt ( inst , kGroupSelIdxGsId ) ;
assert ( groupIdx < p - > oGroupCnt ) ;
// if this is a float input
if ( p - > baseInFloatGsId < = evt - > dstVarId & & evt - > dstVarId < p - > baseInFloatGsId + p - > iChCnt )
{
unsigned outVarId = p - > baseOutFloatGsId + ( groupIdx * p - > iChCnt ) + ( evt - > dstVarId - p - > baseInFloatGsId ) ;
cmDspValueSet ( ctx , inst , outVarId , evt - > valuePtr , 0 ) ;
return rc ;
}
// if this is a symbol input
if ( p - > baseInSymGsId < = evt - > dstVarId & & evt - > dstVarId < p - > baseInSymGsId + p - > iChCnt )
{
unsigned outVarId = p - > baseOutSymGsId + ( groupIdx * p - > iChCnt ) + ( evt - > dstVarId - p - > baseInSymGsId ) ;
cmDspValueSet ( ctx , inst , outVarId , evt - > valuePtr , 0 ) ;
return rc ;
}
// if this is a bool input
if ( p - > baseInBoolGsId < = evt - > dstVarId & & evt - > dstVarId < p - > baseInBoolGsId + p - > iChCnt )
{
unsigned outVarId = p - > baseOutBoolGsId + ( groupIdx * p - > iChCnt ) + ( evt - > dstVarId - p - > baseInBoolGsId ) ;
cmDspValueSet ( ctx , inst , outVarId , evt - > valuePtr , 0 ) ;
return rc ;
}
return rc ;
}
struct cmDspClass_str * cmGSwitchClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmGSwitchDC , ctx , " GSwitch " ,
NULL ,
_cmDspGSwitchAlloc ,
NULL ,
_cmDspGSwitchReset ,
NULL ,
_cmDspGSwitchRecv ,
NULL , NULL ,
" Ganged switch. " ) ;
return & _cmGSwitchDC ;
}
2013-04-20 17:37:20 +00:00
//==========================================================================================================================================
enum
{
kMinInSrId ,
kMaxInSrId ,
kMinOutSrId ,
kMaxOutSrId ,
kValInSrId ,
kValOutSrId ,
} ;
cmDspClass_t _cmScaleRangeDC ;
typedef struct
{
cmDspInst_t inst ;
} cmDspScaleRange_t ;
cmDspInst_t * _cmDspScaleRangeAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
va_list vl1 ;
va_copy ( vl1 , vl ) ;
cmDspVarArg_t args [ ] =
{
{ " min_in " , kMinInSrId , 0 , 0 , kInDsvFl | kDoubleDsvFl , " Min Input value. " } ,
{ " max_in " , kMaxInSrId , 0 , 0 , kInDsvFl | kDoubleDsvFl , " Min Input value. " } ,
{ " min_out " , kMinOutSrId , 0 , 0 , kInDsvFl | kDoubleDsvFl , " Min Input value. " } ,
{ " max_out " , kMaxOutSrId , 0 , 0 , kInDsvFl | kDoubleDsvFl , " Min Input value. " } ,
{ " val_in " , kValInSrId , 0 , 0 , kInDsvFl | kDoubleDsvFl , " Input value. " } ,
{ " val_out " , kValOutSrId , 0 , 0 , kOutDsvFl | kDoubleDsvFl , " Output value " } ,
{ NULL , 0 , 0 , 0 , 0 }
} ;
cmDspScaleRange_t * p = cmDspInstAlloc ( cmDspScaleRange_t , ctx , classPtr , args , instSymId , id , storeSymId , va_cnt , vl ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kMinInSrId , 0 , 0 ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kMaxInSrId , 0 , 1.0 ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kMinOutSrId , 0 , 0 ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kMaxOutSrId , 0 , 1.0 ) ;
return & p - > inst ;
}
cmDspRC_t _cmDspScaleRangeReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspApplyAllDefaults ( ctx , inst ) ;
return rc ;
}
cmDspRC_t _cmDspScaleRangeRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
2013-05-01 22:09:46 +00:00
//cmDspScaleRange_t* p = (cmDspScaleRange_t*)inst;
2013-04-20 17:37:20 +00:00
cmDspSetEvent ( ctx , inst , evt ) ;
if ( evt - > dstVarId = = kValInSrId )
{
double val = cmDspDouble ( inst , kValInSrId ) ;
double min_in = cmDspDouble ( inst , kMinInSrId ) ;
double max_in = cmDspDouble ( inst , kMaxInSrId ) ;
double min_out = cmDspDouble ( inst , kMinOutSrId ) ;
double max_out = cmDspDouble ( inst , kMaxOutSrId ) ;
double x = cmMax ( min_in , cmMin ( max_in , val ) ) ;
x = ( x - min_in ) / ( max_in - min_in ) ;
x = min_out + x * ( max_out - min_out ) ;
cmDspSetDouble ( ctx , inst , kValOutSrId , x ) ;
//printf("%f (%f %f) : (%f %f) %f\n",val,min_in,max_in,min_out,max_out,x);
}
return rc ;
}
struct cmDspClass_str * cmScaleRangeClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmScaleRangeDC , ctx , " ScaleRange " ,
NULL ,
_cmDspScaleRangeAlloc ,
NULL ,
_cmDspScaleRangeReset ,
NULL ,
_cmDspScaleRangeRecv ,
NULL , NULL ,
" Scale a value inside an input range to a value in the output range. " ) ;
return & _cmScaleRangeDC ;
}
2013-07-10 19:24:08 +00:00
//==========================================================================================================================================
enum
{
kCntAmId ,
kSflocAmId ,
kLocAmId ,
kTypeAmId ,
kValueAmId ,
kCstAmId ,
kCmdAmId ,
2013-08-12 07:11:59 +00:00
kScLocAmId ,
2013-07-10 19:24:08 +00:00
kEvenAmId ,
kDynAmId ,
kTempoAmId ,
kCostAmId
} ;
cmDspClass_t _cmActiveMeasDC ;
2013-12-11 17:43:22 +00:00
typedef struct cmDspAmRecd_str
2013-07-10 19:24:08 +00:00
{
unsigned loc ;
unsigned type ;
double value ;
double cost ;
2013-12-11 17:43:22 +00:00
struct cmDspAmRecd_str * link ;
} cmDspAmRecd_t ;
2013-07-10 19:24:08 +00:00
2013-12-11 17:43:22 +00:00
/*
2013-07-10 19:24:08 +00:00
int cmDspActiveMeasRecdCompare ( const void * p0 , const void * p1 )
{
return ( ( int ) ( ( cmDspActiveMeasRecd_t * ) p0 ) - > loc ) - ( int ) ( ( ( cmDspActiveMeasRecd_t * ) p1 ) - > loc ) ;
}
2013-12-11 17:43:22 +00:00
*/
2013-07-10 19:24:08 +00:00
typedef struct
{
cmDspInst_t inst ;
unsigned addSymId ;
unsigned clearSymId ;
2013-07-10 21:19:33 +00:00
unsigned printSymId ;
unsigned rewindSymId ;
2013-12-11 17:43:22 +00:00
cmDspAmRecd_t * array ; // array[cnt]
unsigned cnt ;
cmDspAmRecd_t * list ; // first recd in list sorted on 'loc'.
cmDspAmRecd_t * avail ; // next empty recd
cmDspAmRecd_t * sent ; // last recd sent
2013-07-10 19:24:08 +00:00
} cmDspActiveMeas_t ;
2013-12-11 17:43:22 +00:00
void _cmDspAmAllocList ( cmDspActiveMeas_t * p , unsigned cnt )
{
assert ( p - > array = = NULL ) ;
cmDspAmRecd_t * r = cmMemAllocZ ( cmDspAmRecd_t , cnt ) ;
p - > cnt = cnt ;
p - > array = r ;
p - > list = NULL ;
p - > avail = r ;
p - > sent = NULL ;
}
cmDspRC_t _cmDspActiveMeasAdd ( cmDspCtx_t * ctx , cmDspActiveMeas_t * p , unsigned loc , unsigned type , double value , double cost )
{
assert ( type ! = kInvalidVarScId ) ;
cmDspAmRecd_t * rp = p - > list ;
cmDspAmRecd_t * pp = NULL ;
// search for the location to add the new record
for ( ; rp ! = NULL ; rp = rp - > link )
{
// if this loc and type already exists then replace the value and cost fields
if ( rp - > loc = = loc & & rp - > type = = type )
goto foundLabel ;
// if this loc should be inserted before rp
if ( loc < rp - > loc )
break ;
pp = rp ;
}
// if the pre-allocated list is full
if ( p - > avail > = p - > array + p - > cnt )
return cmDspInstErr ( ctx , & p - > inst , kInvalidArgDspRC , " Unable to store new measurement record. All preallocated active measurement slots are in use. " ) ;
// if prepending to the list
if ( pp = = NULL )
{
rp = p - > avail ;
rp - > link = p - > list ;
p - > list = rp ;
}
else
{
// if appending to the list after pp
if ( rp = = NULL )
{
// nothing to do
}
else // if inserting between pp and rp
{
p - > avail - > link = rp ;
}
rp = p - > avail ;
pp - > link = rp ;
}
p - > avail + = 1 ;
foundLabel :
rp - > loc = loc ;
rp - > type = type ;
rp - > value = value ;
rp - > cost = cost ;
return kOkDspRC ;
}
2013-07-10 19:24:08 +00:00
cmDspInst_t * _cmDspActiveMeasAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
cmDspVarArg_t args [ ] =
{
{ " cnt " , kCntAmId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Maximum count of active measurements. " } ,
{ " sfloc " , kSflocAmId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Score follower location input. " } ,
{ " loc " , kLocAmId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Meas. location. " } ,
2013-12-11 17:43:22 +00:00
{ " type " , kTypeAmId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Meas. Type. (even,dyn,...) " } ,
2013-07-10 19:24:08 +00:00
{ " val " , kValueAmId , 0 , 0 , kInDsvFl | kDoubleDsvFl , " Meas. Value. " } ,
{ " cst " , kCstAmId , 0 , 0 , kInDsvFl | kDoubleDsvFl , " Meas. Cost. " } ,
2013-07-10 21:19:33 +00:00
{ " cmd " , kCmdAmId , 0 , 0 , kInDsvFl | kSymDsvFl , " Commands:add | clear | dump | rewind " } ,
2013-08-12 07:11:59 +00:00
{ " scloc " , kScLocAmId , 0 , 0 , kOutDsvFl | kUIntDsvFl , " Score location " } ,
2013-07-10 19:24:08 +00:00
{ " even " , kEvenAmId , 0 , 0 , kOutDsvFl | kDoubleDsvFl , " Even out " } ,
{ " dyn " , kDynAmId , 0 , 0 , kOutDsvFl | kDoubleDsvFl , " Dyn out " } ,
{ " tempo " , kTempoAmId , 0 , 0 , kOutDsvFl | kDoubleDsvFl , " Tempo out " } ,
{ " cost " , kCostAmId , 0 , 0 , kOutDsvFl | kDoubleDsvFl , " Cost out " } ,
{ NULL , 0 , 0 , 0 , 0 }
} ;
cmDspActiveMeas_t * p = cmDspInstAlloc ( cmDspActiveMeas_t , ctx , classPtr , args , instSymId , id , storeSymId , va_cnt , vl ) ;
p - > addSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " add " ) ;
p - > clearSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " clear " ) ;
2013-07-10 21:19:33 +00:00
p - > printSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " dump " ) ;
p - > rewindSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " rewind " ) ;
2013-07-10 19:24:08 +00:00
2013-12-11 17:43:22 +00:00
cmDspSetDefaultUInt ( ctx , & p - > inst , kCntAmId , 0 , 256 ) ;
2013-08-12 07:11:59 +00:00
cmDspSetDefaultUInt ( ctx , & p - > inst , kScLocAmId , 0 , 0 ) ;
2013-07-10 19:24:08 +00:00
cmDspSetDefaultDouble ( ctx , & p - > inst , kEvenAmId , 0 , 0 ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kDynAmId , 0 , 0 ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kTempoAmId , 0 , 0 ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kTempoAmId , 0 , 0 ) ;
return & p - > inst ;
}
cmDspRC_t _cmDspActiveMeasPrint ( cmDspCtx_t * ctx , cmDspActiveMeas_t * p )
{
2013-12-11 17:43:22 +00:00
cmDspAmRecd_t * rp = p - > list ;
for ( ; rp ! = NULL ; rp = rp - > link )
2013-07-10 19:24:08 +00:00
{
const cmChar_t * label = " <null> " ;
2013-12-11 17:43:22 +00:00
switch ( rp - > type )
2013-07-10 19:24:08 +00:00
{
case kEvenVarScId : label = " even " ; break ;
case kDynVarScId : label = " dyn " ; break ;
case kTempoVarScId : label = " tempo " ; break ;
default :
{ assert ( 0 ) ; }
}
2013-12-11 17:43:22 +00:00
cmRptPrintf ( ctx - > rpt , " loc:%i %s %f %f \n " , rp - > loc , label , rp - > value , rp - > cost ) ;
2013-07-10 19:24:08 +00:00
}
return kOkDspRC ;
}
cmDspRC_t _cmDspActiveMeasClear ( cmDspCtx_t * ctx , cmDspActiveMeas_t * p )
{
2013-12-11 17:43:22 +00:00
memset ( p - > array , 0 , sizeof ( p - > array [ 0 ] ) * p - > cnt ) ;
p - > avail = p - > array ;
p - > list = NULL ;
p - > avail = p - > array ;
2013-07-10 19:24:08 +00:00
return kOkDspRC ;
}
cmDspRC_t _cmDspActiveMeasFree ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspActiveMeas_t * p = ( cmDspActiveMeas_t * ) inst ;
cmMemPtrFree ( & p - > array ) ;
return kOkDspRC ;
}
cmDspRC_t _cmDspActiveMeasReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspActiveMeas_t * p = ( cmDspActiveMeas_t * ) inst ;
cmDspApplyAllDefaults ( ctx , inst ) ;
unsigned cnt = cmMax ( 100 , cmDspUInt ( inst , kCntAmId ) ) ;
_cmDspActiveMeasFree ( ctx , inst , evt ) ;
2013-12-11 17:43:22 +00:00
_cmDspAmAllocList ( p , cnt ) ;
2013-07-10 19:24:08 +00:00
return rc ;
}
cmDspRC_t _cmDspActiveMeasRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
2013-12-11 17:43:22 +00:00
cmDspRC_t rc = kOkDspRC ;
2013-07-10 19:24:08 +00:00
cmDspActiveMeas_t * p = ( cmDspActiveMeas_t * ) inst ;
cmDspSetEvent ( ctx , inst , evt ) ;
2013-12-11 17:43:22 +00:00
switch ( evt - > dstVarId )
{
case kSflocAmId :
{
unsigned sfloc = cmDspUInt ( inst , kSflocAmId ) ; // get the recv'd score location
cmDspAmRecd_t * rp = p - > sent = = NULL ? p - > list : p - > sent - > link ; // get the next recd to send
bool fl = false ;
for ( ; rp ! = NULL ; rp = rp - > link )
if ( rp - > loc < = sfloc )
{
// deterimine the records type
unsigned varId = cmInvalidId ;
switch ( rp - > type )
{
case kEvenVarScId : varId = kEvenAmId ; break ;
case kDynVarScId : varId = kDynAmId ; break ;
case kTempoVarScId : varId = kTempoAmId ; break ;
default :
{ assert ( 0 ) ; }
}
// Sending the location triggers the avail-ch to switch - so the location should only
// be sent once.
if ( ! fl )
{
cmDspSetUInt ( ctx , inst , kScLocAmId , rp - > loc ) ;
fl = true ;
}
// transmit the records value and cost
cmDspSetDouble ( ctx , inst , varId , rp - > value ) ;
cmDspSetDouble ( ctx , inst , kCostAmId , rp - > cost ) ;
p - > sent = rp ;
}
}
break ;
case kCmdAmId :
{
unsigned cmdSymId = cmDspSymbol ( inst , kCmdAmId ) ;
if ( cmdSymId = = p - > addSymId )
rc = _cmDspActiveMeasAdd ( ctx , p , cmDspUInt ( inst , kLocAmId ) , cmDspUInt ( inst , kTypeAmId ) , cmDspDouble ( inst , kValueAmId ) , cmDspDouble ( inst , kCstAmId ) ) ;
else
if ( cmdSymId = = p - > clearSymId )
rc = _cmDspActiveMeasClear ( ctx , p ) ;
else
if ( cmdSymId = = p - > printSymId )
rc = _cmDspActiveMeasPrint ( ctx , p ) ;
else
if ( cmdSymId = = p - > rewindSymId )
p - > sent = NULL ;
}
break ;
}
/*
2013-07-10 19:24:08 +00:00
switch ( evt - > dstVarId )
{
case kSflocAmId :
if ( p - > nextFullIdx ! = cmInvalidIdx )
{
2013-08-12 07:11:59 +00:00
// get the recv'd score location
2013-07-10 19:24:08 +00:00
unsigned sflocIdx = cmDspUInt ( inst , kSflocAmId ) ;
2013-08-12 07:11:59 +00:00
unsigned prvLoc = cmInvalidIdx ;
// for each remaining avail record
2013-07-10 19:24:08 +00:00
for ( ; p - > nextFullIdx < p - > nextEmptyIdx ; p - > nextFullIdx + + )
{
cmDspActiveMeasRecd_t * r = p - > array + p - > nextFullIdx ;
2013-08-12 07:11:59 +00:00
// if this records score location is after the recv'd score loc then we're done
2013-07-10 19:24:08 +00:00
if ( r - > loc > sflocIdx )
break ;
2013-08-12 07:11:59 +00:00
// deterimine the records type
2013-07-10 19:24:08 +00:00
unsigned varId = cmInvalidId ;
switch ( r - > type )
{
case kEvenVarScId : varId = kEvenAmId ; break ;
case kDynVarScId : varId = kDynAmId ; break ;
case kTempoVarScId : varId = kTempoAmId ; break ;
default :
{ assert ( 0 ) ; }
}
2013-08-12 07:11:59 +00:00
// if this score location has not yet been sent then send it now
if ( prvLoc ! = r - > loc )
cmDspSetUInt ( ctx , inst , kScLocAmId , r - > loc ) ;
// transmit the records value and cost
2013-07-10 19:24:08 +00:00
cmDspSetDouble ( ctx , inst , varId , r - > value ) ;
2013-09-30 18:03:47 +00:00
cmDspSetDouble ( ctx , inst , kCostAmId , r - > cost ) ;
2013-08-12 07:11:59 +00:00
prvLoc = r - > loc ;
2013-07-10 19:24:08 +00:00
}
}
break ;
case kCmdAmId :
{
unsigned cmdSymId = cmDspSymbol ( inst , kCmdAmId ) ;
if ( cmdSymId = = p - > addSymId )
{
if ( p - > nextEmptyIdx > = p - > cnt )
cmDspInstErr ( ctx , inst , kProcFailDspRC , " The active measurement list is full cnt=%i. " , p - > cnt ) ;
else
{
cmDspActiveMeasRecd_t * r = p - > array + p - > nextEmptyIdx ;
r - > loc = cmDspUInt ( inst , kLocAmId ) ;
r - > type = cmDspUInt ( inst , kTypeAmId ) ;
r - > value = cmDspDouble ( inst , kValueAmId ) ;
r - > cost = cmDspDouble ( inst , kCstAmId ) ;
p - > nextEmptyIdx + = 1 ;
qsort ( p - > array , p - > nextEmptyIdx , sizeof ( p - > array [ 0 ] ) , cmDspActiveMeasRecdCompare ) ;
if ( p - > nextEmptyIdx = = 1 & & p - > nextFullIdx = = cmInvalidIdx )
p - > nextFullIdx = 0 ;
}
}
if ( cmdSymId = = p - > clearSymId )
rc = _cmDspActiveMeasClear ( ctx , p ) ;
else
if ( cmdSymId = = p - > printSymId )
rc = _cmDspActiveMeasPrint ( ctx , p ) ;
2013-07-10 21:19:33 +00:00
else
if ( cmdSymId = = p - > rewindSymId )
p - > nextFullIdx = 0 ;
2013-07-10 19:24:08 +00:00
}
break ;
}
2013-12-11 17:43:22 +00:00
*/
2013-07-10 19:24:08 +00:00
return rc ;
}
struct cmDspClass_str * cmActiveMeasClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmActiveMeasDC , ctx , " ActiveMeas " ,
NULL ,
_cmDspActiveMeasAlloc ,
_cmDspActiveMeasFree ,
_cmDspActiveMeasReset ,
NULL ,
_cmDspActiveMeasRecv ,
NULL , NULL ,
" Scale a value inside an input range to a value in the output range. " ) ;
return & _cmActiveMeasDC ;
}
2013-09-26 06:46:11 +00:00
//==========================================================================================================================================
// Audio MIDI Sync
2013-11-22 01:25:09 +00:00
/*
Usage :
1 ) In the program resource file setup a list of sync points .
' asmp ' refers to a sample offset into the audio file ' af '
which should match to the midi event index ' mid ' in the
midi file ' mf ' .
amSync :
[
{ af : " af-16 " asmp : 34735276 mf : " mf-10 " mid : 350 }
{ af : " af-16 " asmp : 71802194 mf : " mf-10 " mid : 787 }
]
2 ) Feed the ' fidx ' output from a wave table loaded with ' af ' into the ' asmp ' input port of this amSync object .
Feed the ' id ' output from the MIDI file player loaded with ' mf ' into the ' mid ' input port of this amSync object .
3 ) Run the players .
4 ) When the run is complete send any message to the ' sel ' port of this amSync object .
The ' frm : ' field of the printed output gives the difference in samples between
MIDI and audio sync points .
If the value is positive then the MIDI point is after the Audio point .
If the value is negative then the MIDI point is before the audio point .
*/
2013-09-26 06:46:11 +00:00
enum
{
kSelAmId ,
kAFnAmId ,
kASmpAmId ,
kMFnAmId ,
kMIdAmId ,
} ;
enum
{
kAfnAmFl = 0x01 ,
kMfnAmFl = 0x02 ,
kAsmpAmFl = 0x04 ,
kMidAmFl = 0x08 ,
} ;
cmDspClass_t _cmAmSyncDC ;
typedef struct cmDspAmSyncEntry_str
{
2013-11-20 16:56:28 +00:00
const cmChar_t * afn ; // audio file name
const cmChar_t * mfn ; // midi file name
2013-09-26 06:46:11 +00:00
unsigned asmp ; // Audio sample index to sync to MIDI event
unsigned mid ; // MIDI event unique id (cmMidiTrackMsg_t.uid)
2013-11-22 01:25:09 +00:00
int afi ; // closest DSP system cycle index to the reference audio sample index (asmp).
int mfi ; // DSP system cycle on which the reference MIDI event (mid) arrived.
2013-11-20 16:56:28 +00:00
unsigned state ; // as incoming msg match this record the state is updated with kXXXAmFl flags
2013-09-26 06:46:11 +00:00
} cmDspAmSyncEntry_t ;
typedef struct
{
cmDspInst_t inst ;
cmDspAmSyncEntry_t * array ;
unsigned arrayCnt ;
cmDspAmSyncEntry_t * acur ;
cmDspAmSyncEntry_t * mcur ;
} cmDspAmSync_t ;
cmDspInst_t * _cmDspAmSyncAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
cmDspVarArg_t args [ ] =
{
2013-09-26 19:48:55 +00:00
{ " sel " , kSelAmId , 0 , 0 , kInDsvFl | kTypeDsvMask , " Print and reset " } ,
2013-09-26 06:46:11 +00:00
{ " afn " , kAFnAmId , 0 , 0 , kInDsvFl | kStrzDsvFl , " Audio File name " } ,
{ " asmp " , kASmpAmId , 0 , 0 , kInDsvFl | kIntDsvFl , " Audio sample index " } ,
{ " mfn " , kMFnAmId , 0 , 0 , kInDsvFl | kStrzDsvFl , " MIDI File name " } ,
{ " mid " , kMIdAmId , 0 , 0 , kInDsvFl | kIntDsvFl , " MIDI Event Unique Id " } ,
{ NULL , 0 , 0 , 0 , 0 }
} ;
cmDspAmSync_t * p = cmDspInstAlloc ( cmDspAmSync_t , ctx , classPtr , args , instSymId , id , storeSymId , va_cnt , vl ) ;
return & p - > inst ;
}
cmDspRC_t _cmDspAmSyncFree ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspAmSync_t * p = ( cmDspAmSync_t * ) inst ;
cmMemFree ( p - > array ) ;
return kOkDspRC ;
}
cmDspRC_t _cmDspAmSyncReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspAmSync_t * p = ( cmDspAmSync_t * ) inst ;
cmDspApplyAllDefaults ( ctx , inst ) ;
cmJsonH_t jsH = cmDspSysPgmRsrcHandle ( ctx - > dspH ) ;
cmJsonNode_t * np ;
const cmChar_t * errLabelPtr ;
unsigned i ;
cmJsRC_t jsRC ;
if ( ( np = cmJsonFindValue ( jsH , " amSync " , NULL , kArrayTId ) ) = = NULL )
{
rc = cmDspInstErr ( ctx , inst , kRsrcNotFoundDspRC , " The AUDIO MIDI Sync cfg. record was not found. " ) ;
goto errLabel ;
}
p - > arrayCnt = cmJsonChildCount ( np ) ;
p - > array = cmMemResizeZ ( cmDspAmSyncEntry_t , p - > array , p - > arrayCnt ) ;
for ( i = 0 ; i < p - > arrayCnt ; + + i )
{
cmJsonNode_t * anp = cmJsonArrayElement ( np , i ) ;
cmDspAmSyncEntry_t * r = p - > array + i ;
if ( ( jsRC = cmJsonMemberValues ( anp , & errLabelPtr ,
" af " , kStringTId , & r - > afn ,
" asmp " , kIntTId , & r - > asmp ,
" mf " , kStringTId , & r - > mfn ,
" mid " , kIntTId , & r - > mid ,
NULL ) ) ! = kOkJsRC )
{
if ( jsRC = = kNodeNotFoundJsRC )
rc = cmDspInstErr ( ctx , inst , kRsrcNotFoundDspRC , " The Audio-MIDI Sync cfg. field '%s' was missing in the cfg. record at index %i. " , errLabelPtr , i ) ;
else
rc = cmDspInstErr ( ctx , inst , kInvalidArgDspRC , " The AUDIO MIDI Sync cfg. parse failed on the record at index %i. " , i ) ;
break ;
}
r - > afi = cmInvalidIdx ;
r - > mfi = cmInvalidIdx ;
r - > state = 0 ;
}
errLabel :
return rc ;
}
cmDspRC_t _cmDspAmSyncRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspAmSync_t * p = ( cmDspAmSync_t * ) inst ;
unsigned i ;
if ( evt - > dstVarId ! = kSelAmId )
cmDspSetEvent ( ctx , inst , evt ) ;
switch ( evt - > dstVarId )
{
case kSelAmId :
{
2013-09-26 15:56:14 +00:00
double srate = cmDspSysSampleRate ( ctx - > dspH ) ;
int fpc = cmDspSamplesPerCycle ( ctx ) ;
for ( i = 0 ; i < p - > arrayCnt ; + + i )
{
2013-09-26 19:48:55 +00:00
cmDspAmSyncEntry_t * r = p - > array + i ;
2013-09-26 15:56:14 +00:00
int dframes = r - > mfi - r - > afi ;
cmRptPrintf ( ctx - > rpt , " 0x%x : %s %i %i - %s %i %i : frm:%i smp:%i sec:%f \n " ,
2013-11-20 16:56:28 +00:00
r - > state ,
r - > afn ,
r - > asmp ,
r - > afi ,
r - > mfn ,
r - > mid ,
r - > mfi ,
dframes ,
dframes * fpc , dframes * fpc / srate ) ;
2013-09-26 19:48:55 +00:00
r - > afi = cmInvalidIdx ;
r - > mfi = cmInvalidIdx ;
r - > state = 0 ;
2013-09-26 15:56:14 +00:00
}
2013-09-26 19:48:55 +00:00
p - > acur = NULL ;
p - > mcur = NULL ;
2013-09-26 15:56:14 +00:00
}
2013-09-26 06:46:11 +00:00
break ;
case kAFnAmId :
{
2013-11-20 16:56:28 +00:00
// an audio file name just arrived - set p->acur to point to it
2013-09-26 06:46:11 +00:00
const cmChar_t * fn = cmDspStrcz ( inst , kAFnAmId ) ;
2013-11-20 16:56:28 +00:00
2013-09-26 06:46:11 +00:00
for ( i = 0 ; i < p - > arrayCnt ; + + i )
if ( strcmp ( fn , p - > array [ i ] . afn ) = = 0 )
{
p - > array [ i ] . state = cmSetFlag ( p - > array [ i ] . state , kAfnAmFl ) ;
2013-09-26 19:48:55 +00:00
p - > acur = p - > array + i ;
2013-09-26 06:46:11 +00:00
}
}
break ;
case kMFnAmId :
{
2013-11-22 01:25:09 +00:00
// a midi file name just arrived - set p->mcur to point to it
2013-09-26 06:46:11 +00:00
const cmChar_t * fn = cmDspStrcz ( inst , kMFnAmId ) ;
for ( i = 0 ; i < p - > arrayCnt ; + + i )
if ( strcmp ( fn , p - > array [ i ] . mfn ) = = 0 )
{
p - > array [ i ] . state = cmSetFlag ( p - > array [ i ] . state , kMfnAmFl ) ;
2013-09-26 19:48:55 +00:00
p - > mcur = p - > array + i ;
2013-09-26 06:46:11 +00:00
}
}
break ;
case kASmpAmId :
{
2013-11-20 16:56:28 +00:00
// a audio file sample index has just arrived
2013-09-26 19:48:55 +00:00
int v = cmDspInt ( inst , kASmpAmId ) ;
2013-11-20 16:56:28 +00:00
// if a valid audio file has been set
2013-09-26 19:48:55 +00:00
if ( p - > acur ! = NULL )
for ( i = 0 ; i < p - > arrayCnt ; + + i )
{
2013-11-22 01:25:09 +00:00
// if the audio sync point is before or on the new audio file sample index then
// this is the closest audio file index to the audio sync point - record the
// associated cycleCnt
2013-09-26 19:48:55 +00:00
cmDspAmSyncEntry_t * r = p - > array + i ;
if ( cmIsNotFlag ( r - > state , kAsmpAmFl ) & & r - > asmp < = v & & strcmp ( p - > acur - > afn , r - > afn ) = = 0 )
{
r - > afi = ctx - > cycleCnt ;
r - > state = cmSetFlag ( r - > state , kAsmpAmFl ) ;
break ;
}
}
2013-09-26 06:46:11 +00:00
}
break ;
case kMIdAmId :
{
2013-11-22 01:25:09 +00:00
// a new MIDI event was received
2013-09-26 06:46:11 +00:00
int v = cmDspInt ( inst , kMIdAmId ) ;
2013-09-26 19:48:55 +00:00
if ( p - > mcur ! = NULL )
for ( i = 0 ; i < p - > arrayCnt ; + + i )
{
2013-11-22 01:25:09 +00:00
// if the new MIDI event matched the MIDI sync point then record the
// current cycleCnt.
2013-09-26 19:48:55 +00:00
cmDspAmSyncEntry_t * r = p - > array + i ;
if ( cmIsNotFlag ( r - > state , kMidAmFl ) & & r - > mid = = v & & strcmp ( p - > mcur - > mfn , r - > mfn ) = = 0 )
{
r - > mfi = ctx - > cycleCnt ;
r - > state = cmSetFlag ( r - > state , kMidAmFl ) ;
break ;
}
}
2013-09-26 06:46:11 +00:00
}
break ;
}
return kOkDspRC ;
}
struct cmDspClass_str * cmAmSyncClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmAmSyncDC , ctx , " AmSync " ,
NULL ,
_cmDspAmSyncAlloc ,
_cmDspAmSyncFree ,
_cmDspAmSyncReset ,
NULL ,
_cmDspAmSyncRecv ,
NULL , NULL ,
" Audio - MIDI Sync Object. " ) ;
return & _cmAmSyncDC ;
}
2013-11-01 01:07:00 +00:00
//==========================================================================================================================================
enum
{
kPgmNmId ,
kStatusNmId ,
kD0NmId ,
kD1NmId ,
kThruNmId
} ;
cmDspClass_t _cmNanoMapDC ;
typedef struct
{
cmDspInst_t inst ;
} cmDspNanoMap_t ;
cmDspRC_t _cmDspNanoMapSend ( cmDspCtx_t * ctx , cmDspInst_t * inst , unsigned st , unsigned d0 , unsigned d1 )
{
cmDspSetUInt ( ctx , inst , kD1NmId , d1 ) ;
cmDspSetUInt ( ctx , inst , kD0NmId , d0 ) ;
cmDspSetUInt ( ctx , inst , kStatusNmId , st ) ;
return kOkDspRC ;
}
void _cmDspNanoMapPgm ( cmDspCtx_t * ctx , cmDspInst_t * inst , unsigned pgm )
{
unsigned i ;
for ( i = 0 ; i < kMidiChCnt ; + + i )
{
_cmDspNanoMapSend ( ctx , inst , kCtlMdId + i , 121 , 0 ) ; // reset all controllers
_cmDspNanoMapSend ( ctx , inst , kCtlMdId + i , 123 , 0 ) ; // turn all notes off
_cmDspNanoMapSend ( ctx , inst , kCtlMdId + i , 0 , 0 ) ; // switch to bank 0
_cmDspNanoMapSend ( ctx , inst , kPgmMdId + i , pgm , 0 ) ; // send pgm change
cmSleepMs ( 15 ) ;
}
}
cmDspInst_t * _cmDspNanoMapAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
cmDspVarArg_t args [ ] =
{
{ " pgm " , kPgmNmId , 0 , 0 , kInDsvFl | kUIntDsvFl | kOptArgDsvFl , " Reprogram all channels to this pgm. " } ,
{ " status " , kStatusNmId , 0 , 0 , kOutDsvFl | kInDsvFl | kUIntDsvFl | kOptArgDsvFl , " MIDI status " } ,
{ " d0 " , kD0NmId , 0 , 0 , kOutDsvFl | kInDsvFl | kUIntDsvFl | kOptArgDsvFl , " MIDI channel message d0 " } ,
{ " d1 " , kD1NmId , 0 , 0 , kOutDsvFl | kInDsvFl | kUIntDsvFl | kOptArgDsvFl , " MIDI channel message d1 " } ,
{ " thru " , kThruNmId , 0 , 0 , kInDsvFl | kBoolDsvFl | kOptArgDsvFl , " Enable pass through. " } ,
{ NULL , 0 , 0 , 0 , 0 }
} ;
cmDspNanoMap_t * p = cmDspInstAlloc ( cmDspNanoMap_t , ctx , classPtr , args , instSymId , id , storeSymId , va_cnt , vl ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kPgmNmId , 0 , 0 ) ;
return & p - > inst ;
}
cmDspRC_t _cmDspNanoMapReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspApplyAllDefaults ( ctx , inst ) ;
_cmDspNanoMapPgm ( ctx , inst , cmDspUInt ( inst , kPgmNmId ) ) ;
return rc ;
}
cmDspRC_t _cmDspNanoMapRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
//cmDspNanoMap_t* p = (cmDspNanoMap_t*)inst;
switch ( evt - > dstVarId )
{
case kPgmNmId :
cmDspSetEvent ( ctx , inst , evt ) ;
_cmDspNanoMapPgm ( ctx , inst , cmDspUInt ( inst , kPgmNmId ) ) ;
break ;
case kStatusNmId :
{
unsigned status = cmDsvGetUInt ( evt - > valuePtr ) ;
if ( ( status & 0xf0 ) = = kNoteOnMdId )
{
unsigned d0 = cmDspUInt ( inst , kD0NmId ) ;
unsigned ch = d0 % 8 ;
status = ( status & 0xf0 ) + ch ;
cmDspSetUInt ( ctx , inst , kStatusNmId , status ) ;
}
}
break ;
default :
cmDspSetEvent ( ctx , inst , evt ) ;
break ;
}
return kOkDspRC ;
}
struct cmDspClass_str * cmNanoMapClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmNanoMapDC , ctx , " NanoMap " ,
NULL ,
_cmDspNanoMapAlloc ,
NULL ,
_cmDspNanoMapReset ,
NULL ,
_cmDspNanoMapRecv ,
NULL ,
NULL ,
" Nanosynth Mapper " ) ;
return & _cmNanoMapDC ;
}
2013-11-19 06:30:27 +00:00
//==========================================================================================================================================
enum
{
kChCntPrId ,
kFnPrId ,
kSecsPrId ,
2013-11-19 16:08:08 +00:00
kMaxLaSecsPrId ,
kCurLaSecsPrId ,
2013-11-19 06:30:27 +00:00
kFadeRatePrId ,
2014-01-17 04:18:48 +00:00
kScInitLocIdxPrId ,
2013-11-19 06:30:27 +00:00
kScLocIdxPrId ,
kCmdPrId ,
kInAudioBasePrId
} ;
cmDspClass_t _cmRecdPlayDC ;
typedef struct
{
cmDspInst_t inst ;
cmRecdPlay * rcdply ;
cmScH_t scH ;
unsigned onSymId ;
unsigned offSymId ;
unsigned audioOutBaseId ;
unsigned chCnt ;
unsigned scLocIdx ;
} cmDspRecdPlay_t ;
2014-01-17 21:59:38 +00:00
cmDspRC_t _cmDspRecdPlayParseRsrc ( cmDspCtx_t * ctx , cmDspInst_t * inst , cmRecdPlay * rcdply )
{
cmDspRC_t rc = kOkDspRC ;
const cmChar_t * path = NULL ;
// read the 'recdplay' audio file path
if ( cmDspRsrcString ( ctx - > dspH , & path , " recdPlayPath " , NULL ) ! = kOkDspRC )
{
cmDspInstErr ( ctx , inst , kRsrcNotFoundDspRC , " The 'recdPlayPath' resource string was not found. " ) ;
}
if ( path = = NULL )
path = " " ;
cmJsonH_t jsH = cmDspSysPgmRsrcHandle ( ctx - > dspH ) ;
cmJsonNode_t * jnp = cmJsonFindValue ( jsH , " recdPlay " , NULL , kStringTId ) ;
if ( jnp = = NULL | | cmJsonIsArray ( jnp ) = = false )
{
// this is really a warning - the object does not require preloaded segments.
cmDspInstErr ( ctx , inst , kRsrcNotFoundDspRC , " The 'recdPlay' resource used to define pre-loaded segments was not found. " ) ;
return kOkDspRC ;
}
unsigned n = cmJsonChildCount ( jnp ) ;
unsigned i ;
// for each 'recdplay' segment record
for ( i = 0 ; i < n & & rc = = kOkDspRC ; + + i )
{
cmJsonNode_t * cnp = cmJsonArrayElement ( jnp , i ) ;
const cmChar_t * label = NULL ;
unsigned segSymId = cmInvalidId ;
const cmChar_t * errLabel = NULL ;
const cmChar_t * fn = NULL ;
// read the ith segment record
if ( cmJsonMemberValues ( cnp , & errLabel ,
" label " , kStringTId , & label ,
" file " , kStringTId , & fn ,
NULL ) ! = kOkJsRC )
{
rc = cmDspInstErr ( ctx , inst , kRsrcNotFoundDspRC , " The record at index %i in the 'recdPlay' pre-loaded segment list could not be parsed. " , i ) ;
goto errLabel ;
}
// find or generate the symbol id for the segment label symbol
if ( ( segSymId = cmSymTblRegisterSymbol ( ctx - > stH , label ) ) = = cmInvalidId )
{
rc = cmDspInstErr ( ctx , inst , kSymNotFoundDspRC , " The 'recdPlay' pre-load segment symbol '%s' could not be found or registered. " , cmStringNullGuard ( label ) ) ;
goto errLabel ;
}
// create the full path name for the segment audio file
if ( ( fn = cmFsMakeFn ( path , fn , NULL , NULL ) ) = = NULL )
{
rc = cmDspInstErr ( ctx , inst , kFileSysFailDspRC , " The 'recdPlay' file name '%s/%s' could not be generated. " , cmStringNullGuard ( path ) , cmStringNullGuard ( fn ) ) ;
goto errLabel ;
}
// pre-load the segment
if ( cmRecdPlayInsertRecord ( rcdply , segSymId , fn ) ! = cmOkRC )
rc = cmDspInstErr ( ctx , inst , kSubSysFailDspRC , " The 'recdPlay' segment label:'%s' file:'%s' could not be loaded. " , cmStringNullGuard ( label ) , cmStringNullGuard ( fn ) ) ;
cmFsFreeFn ( fn ) ;
}
errLabel :
return rc ;
}
2013-11-19 06:30:27 +00:00
cmDspRC_t _cmDspRecdPlayOpenScore ( cmDspCtx_t * ctx , cmDspInst_t * inst )
{
cmDspRC_t rc = kOkDspRC ;
const cmChar_t * fn ;
cmDspRecdPlay_t * p = ( cmDspRecdPlay_t * ) inst ;
p - > scLocIdx = 0 ;
if ( ( fn = cmDspStrcz ( inst , kFnPrId ) ) = = NULL | | strlen ( fn ) = = 0 )
2014-01-17 21:59:38 +00:00
return cmDspInstErr ( ctx , inst , kInvalidArgDspRC , " No score file name supplied. " ) ;
2013-11-19 06:30:27 +00:00
if ( cmScoreInitialize ( ctx - > cmCtx , & p - > scH , fn , cmDspSampleRate ( ctx ) , NULL , 0 , NULL , NULL , ctx - > stH ) ! = kOkScRC )
2014-01-17 21:59:38 +00:00
return cmDspInstErr ( ctx , inst , kSubSysFailDspRC , " Unable to open the score '%s'. " , fn ) ;
2013-11-19 06:30:27 +00:00
if ( cmScoreIsValid ( p - > scH ) )
{
unsigned i ;
unsigned markerCnt = cmScoreMarkerLabelCount ( p - > scH ) ;
2013-11-19 16:08:08 +00:00
double initFragSecs = cmDspDouble ( inst , kSecsPrId ) ;
double maxLaSecs = cmDspDouble ( inst , kMaxLaSecsPrId ) ;
double curLaSecs = cmDspDouble ( inst , kCurLaSecsPrId ) ;
2013-11-19 06:30:27 +00:00
2013-12-10 21:32:19 +00:00
printf ( " 2 max la secs:%f \n " , cmDspDouble ( inst , kMaxLaSecsPrId ) ) ;
2013-11-19 16:08:08 +00:00
if ( ( p - > rcdply = cmRecdPlayAlloc ( ctx - > cmProcCtx , NULL , cmDspSampleRate ( ctx ) , markerCnt , p - > chCnt , initFragSecs , maxLaSecs , curLaSecs ) ) = = NULL )
2013-11-19 06:30:27 +00:00
return cmErrMsg ( & inst - > classPtr - > err , kSubSysFailDspRC , " Unable to create the internal recorder-player object. " ) ;
for ( i = 0 ; i < markerCnt ; + + i )
cmRecdPlayRegisterFrag ( p - > rcdply , i , cmScoreMarkerLabelSymbolId ( p - > scH , i ) ) ;
2014-01-17 21:59:38 +00:00
if ( ( rc = _cmDspRecdPlayParseRsrc ( ctx , inst , p - > rcdply ) ) ! = kOkDspRC )
rc = cmDspInstErr ( ctx , inst , kInstResetFailDspRC , " The 'recdplay' segment pre-load failed. " ) ;
2014-01-16 21:05:45 +00:00
2014-01-17 04:18:48 +00:00
p - > scLocIdx = cmDspUInt ( inst , kScInitLocIdxPrId ) ;
2013-11-19 06:30:27 +00:00
}
return rc ;
}
cmDspInst_t * _cmDspRecdPlayAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
if ( va_cnt < 1 )
{
cmDspClassErr ( ctx , classPtr , kVarArgParseFailDspRC , " The 'RecdPlay' constructor must have a count of input ports. " ) ;
return NULL ;
}
va_list vl1 ;
va_copy ( vl1 , vl ) ;
int chCnt = va_arg ( vl , int ) ;
unsigned audioOutBase = kInAudioBasePrId + chCnt ;
cmDspRecdPlay_t * p = cmDspInstAllocV ( cmDspRecdPlay_t , ctx , classPtr , instSymId , id , storeSymId , va_cnt , vl1 ,
1 , " chs " , kChCntPrId , 0 , 0 , kUIntDsvFl | kReqArgDsvFl , " channel count. " ,
2013-12-10 21:32:19 +00:00
1 , " fn " , kFnPrId , 0 , 0 , kInDsvFl | kStrzDsvFl | kReqArgDsvFl , " Score file. " ,
2013-11-19 06:30:27 +00:00
1 , " secs " , kSecsPrId , 0 , 0 , kInDsvFl | kDoubleDsvFl | kReqArgDsvFl , " Initial fragment allocation in seconds. " ,
2013-12-10 21:32:19 +00:00
1 , " maxla " , kMaxLaSecsPrId , 0 , 0 , kInDsvFl | kDoubleDsvFl | kReqArgDsvFl , " Maximum look-ahead buffer in seconds. " ,
1 , " curla " , kCurLaSecsPrId , 0 , 0 , kInDsvFl | kDoubleDsvFl | kOptArgDsvFl , " Current look-head buffer in seconds. " ,
1 , " frate " , kFadeRatePrId , 0 , 0 , kInDsvFl | kDoubleDsvFl | kOptArgDsvFl , " Fade rate in dB per second. " ,
2014-01-17 04:18:48 +00:00
1 , " initIdx " , kScInitLocIdxPrId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Score search start location. " ,
2013-11-19 06:30:27 +00:00
1 , " index " , kScLocIdxPrId , 0 , 0 , kInDsvFl | kUIntDsvFl , " Score follower location index. " ,
1 , " cmd " , kCmdPrId , 0 , 0 , kInDsvFl | kSymDsvFl , " on=reset off=stop. " ,
chCnt , " in " , kInAudioBasePrId , 0 , 1 , kInDsvFl | kAudioBufDsvFl , " Audio input " ,
chCnt , " out " , audioOutBase , 0 , 1 , kOutDsvFl | kAudioBufDsvFl , " Audio output " ,
0 ) ;
va_end ( vl1 ) ;
p - > onSymId = cmSymTblId ( ctx - > stH , " on " ) ;
p - > offSymId = cmSymTblId ( ctx - > stH , " off " ) ;
p - > audioOutBaseId = audioOutBase ;
p - > chCnt = chCnt ;
p - > scLocIdx = 0 ;
2013-12-10 21:32:19 +00:00
printf ( " 0 max la secs:%f \n " , cmDspDouble ( & p - > inst , kMaxLaSecsPrId ) ) ;
2013-11-20 03:30:10 +00:00
cmDspSetDefaultDouble ( ctx , & p - > inst , kSecsPrId , 0.0 , 10.0 ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kMaxLaSecsPrId , 0.0 , 2.0 ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kCurLaSecsPrId , 0.0 , 0.1 ) ;
cmDspSetDefaultDouble ( ctx , & p - > inst , kFadeRatePrId , 0.0 , 1.0 ) ;
2014-01-17 04:18:48 +00:00
cmDspSetDefaultUInt ( ctx , & p - > inst , kScInitLocIdxPrId , 0 , 0 ) ;
2013-11-19 06:30:27 +00:00
2013-12-10 21:32:19 +00:00
printf ( " 1 max la secs:%f \n " , cmDspDouble ( & p - > inst , kMaxLaSecsPrId ) ) ;
2014-01-17 04:18:48 +00:00
2014-01-16 21:05:45 +00:00
2013-11-19 06:30:27 +00:00
return & p - > inst ;
}
cmDspRC_t _cmDspRecdPlayFree ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspRecdPlay_t * p = ( cmDspRecdPlay_t * ) inst ;
cmRecdPlayFree ( & p - > rcdply ) ;
cmScoreFinalize ( & p - > scH ) ;
return rc ;
}
cmDspRC_t _cmDspRecdPlayReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
2013-12-10 21:32:19 +00:00
cmDspRC_t rc ;
if ( ( rc = _cmDspRecdPlayOpenScore ( ctx , inst ) ) = = kOkDspRC )
cmDspApplyAllDefaults ( ctx , inst ) ;
2013-11-19 06:30:27 +00:00
2013-12-10 21:32:19 +00:00
return rc ;
2013-11-19 06:30:27 +00:00
}
cmDspRC_t _cmDspRecdPlayExec ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspRecdPlay_t * p = ( cmDspRecdPlay_t * ) inst ;
const cmSample_t * x [ p - > chCnt ] ;
cmSample_t * y [ p - > chCnt ] ;
2013-12-12 17:22:21 +00:00
unsigned n = 0 ;
2013-11-19 06:30:27 +00:00
unsigned i ;
unsigned actChCnt = 0 ;
for ( i = 0 ; i < p - > chCnt ; + + i )
{
if ( i = = 0 )
n = cmDspAudioBufSmpCount ( ctx , inst , kInAudioBasePrId + i , 0 ) ;
else
{ assert ( n = = cmDspAudioBufSmpCount ( ctx , inst , kInAudioBasePrId + i , 0 ) ) ; }
x [ i ] = cmDspAudioBuf ( ctx , inst , kInAudioBasePrId + i , 0 ) ;
if ( x [ i ] ! = NULL )
{
y [ i ] = cmDspAudioBuf ( ctx , inst , p - > audioOutBaseId + i , 0 ) ;
if ( y [ i ] ! = NULL )
{
assert ( n = = cmDspAudioBufSmpCount ( ctx , inst , p - > audioOutBaseId + i , 0 ) ) ;
cmVOS_Zero ( y [ i ] , n ) ;
actChCnt + = 1 ;
}
}
}
cmRecdPlayExec ( p - > rcdply , x , y , actChCnt , n ) ;
return rc ;
}
cmDspRC_t _cmDspRecdPlayRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRecdPlay_t * p = ( cmDspRecdPlay_t * ) inst ;
2013-12-10 21:32:19 +00:00
if ( p - > rcdply = = NULL )
return kOkDspRC ;
2013-11-19 06:30:27 +00:00
cmDspSetEvent ( ctx , inst , evt ) ;
switch ( evt - > dstVarId )
{
case kCmdPrId :
if ( cmDspSymbol ( inst , kCmdPrId ) = = p - > onSymId )
{
printf ( " rewind \n " ) ;
cmRecdPlayRewind ( p - > rcdply ) ;
2014-01-17 04:18:48 +00:00
p - > scLocIdx = cmDspUInt ( inst , kScInitLocIdxPrId ) ;
2013-11-19 06:30:27 +00:00
}
else
if ( cmDspSymbol ( inst , kCmdPrId ) = = p - > offSymId )
{
}
break ;
2013-11-19 16:08:08 +00:00
case kCurLaSecsPrId :
2013-11-20 03:30:10 +00:00
cmRecdPlaySetLaSecs ( p - > rcdply , cmDspDouble ( inst , kCurLaSecsPrId ) ) ;
2013-11-19 16:08:08 +00:00
break ;
2014-01-17 04:18:48 +00:00
case kScInitLocIdxPrId :
printf ( " init-idx:%i \n " , cmDspUInt ( inst , kScInitLocIdxPrId ) ) ;
break ;
2013-11-19 06:30:27 +00:00
case kScLocIdxPrId :
{
2014-01-17 04:18:48 +00:00
unsigned endScLocIdx = cmDspUInt ( inst , kScLocIdxPrId ) ;
if ( endScLocIdx < cmDspUInt ( inst , kScInitLocIdxPrId ) )
break ;
2013-11-19 06:30:27 +00:00
for ( ; p - > scLocIdx < = endScLocIdx ; p - > scLocIdx + = 1 )
{
cmScoreLoc_t * loc = cmScoreLoc ( p - > scH , p - > scLocIdx ) ;
cmScoreMarker_t * mp = loc - > markList ;
for ( ; mp ! = NULL ; mp = mp - > link )
switch ( mp - > markTypeId )
{
case kRecdBegScMId :
2014-01-17 04:18:48 +00:00
printf ( " recd-beg %s \n " , cmSymTblLabel ( ctx - > stH , mp - > labelSymId ) ) ;
2013-11-19 06:30:27 +00:00
cmRecdPlayBeginRecord ( p - > rcdply , mp - > labelSymId ) ;
break ;
case kRecdEndScMId :
2014-01-17 04:18:48 +00:00
printf ( " recd-end %s \n " , cmSymTblLabel ( ctx - > stH , mp - > labelSymId ) ) ;
2013-11-19 06:30:27 +00:00
cmRecdPlayEndRecord ( p - > rcdply , mp - > labelSymId ) ;
break ;
case kPlayBegScMId :
printf ( " play-beg \n " ) ;
cmRecdPlayBeginPlay ( p - > rcdply , mp - > labelSymId ) ;
break ;
case kPlayEndScMId :
2013-11-19 16:08:08 +00:00
printf ( " play-end \n " ) ;
2013-11-19 06:30:27 +00:00
cmRecdPlayEndPlay ( p - > rcdply , mp - > labelSymId ) ;
break ;
case kFadeScMId :
printf ( " fade-beg \n " ) ;
cmRecdPlayBeginFade ( p - > rcdply , mp - > labelSymId , cmDspDouble ( inst , kFadeRatePrId ) ) ;
break ;
default :
break ;
}
}
p - > scLocIdx = endScLocIdx + 1 ;
}
break ;
}
return kOkDspRC ;
}
struct cmDspClass_str * cmRecdPlayClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmRecdPlayDC , ctx , " RecdPlay " ,
NULL ,
_cmDspRecdPlayAlloc ,
_cmDspRecdPlayFree ,
_cmDspRecdPlayReset ,
_cmDspRecdPlayExec ,
_cmDspRecdPlayRecv ,
NULL ,
NULL ,
" Score controlled live recorder/player " ) ;
return & _cmRecdPlayDC ;
}
2013-11-24 15:42:07 +00:00
//==========================================================================================================================================
enum
{
2013-11-26 18:43:14 +00:00
kHopFactGrId ,
2013-11-24 15:42:07 +00:00
kInGrId ,
2013-11-26 18:43:14 +00:00
kHzBaseGrId ,
2013-11-24 15:42:07 +00:00
} ;
cmDspClass_t _cmGoertzelDC ;
typedef struct
{
cmDspInst_t inst ;
cmGoertzel * g ;
double outPhs ;
2013-11-26 18:43:14 +00:00
unsigned outBaseGrId ;
unsigned chCnt ;
2013-11-24 15:42:07 +00:00
} cmDspGoertzel_t ;
cmDspInst_t * _cmDspGoertzelAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
2013-11-26 18:43:14 +00:00
if ( va_cnt ! = 3 )
2013-11-24 15:42:07 +00:00
{
cmDspClassErr ( ctx , classPtr , kVarArgParseFailDspRC , " The 'Goertzel' constructor must have two arguments: a channel count and frequency array. " ) ;
return NULL ;
}
va_list vl1 ;
va_copy ( vl1 , vl ) ;
2013-11-26 18:43:14 +00:00
unsigned hopFact = va_arg ( vl , unsigned ) ;
int chCnt = va_arg ( vl , int ) ;
double * hzV = va_arg ( vl , double * ) ;
unsigned outBaseGrId = kHzBaseGrId + chCnt ;
unsigned i ;
2013-11-24 15:42:07 +00:00
2013-11-26 18:43:14 +00:00
cmDspGoertzel_t * p = cmDspInstAllocV ( cmDspGoertzel_t , ctx , classPtr , instSymId , id , storeSymId , 1 , vl1 ,
1 , " hop " , kHopFactGrId , 0 , 0 , kInDsvFl | kDoubleDsvFl , " Hop factor " ,
1 , " in " , kInGrId , 0 , 1 , kInDsvFl | kAudioBufDsvFl , " Audio input " ,
chCnt , " hz " , kHzBaseGrId , 0 , 0 , kInDsvFl | kDoubleDsvFl , " Hz input. " ,
chCnt , " out " , outBaseGrId , 0 , 1 , kOutDsvFl | kDoubleDsvFl , " Detector output " ,
2013-11-24 15:42:07 +00:00
0 ) ;
va_end ( vl1 ) ;
2013-11-26 18:43:14 +00:00
p - > outBaseGrId = outBaseGrId ;
p - > chCnt = chCnt ;
p - > g = cmGoertzelAlloc ( ctx - > cmProcCtx , NULL , 0 , NULL , 0 , 0 , 0 , 0 ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kHopFactGrId , 0 , cmMax ( hopFact , 1 ) ) ;
for ( i = 0 ; i < chCnt ; + + i )
cmDspSetDefaultDouble ( ctx , & p - > inst , kHzBaseGrId + i , 0.0 , hzV [ i ] ) ;
2013-11-24 15:42:07 +00:00
return & p - > inst ;
}
2013-11-26 18:43:14 +00:00
cmDspRC_t _cmDspGoertzelSetup ( cmDspCtx_t * ctx , cmDspInst_t * inst )
{
cmDspRC_t rc = kOkDspRC ;
cmDspGoertzel_t * p = ( cmDspGoertzel_t * ) inst ;
unsigned hopFact = cmDspUInt ( inst , kHopFactGrId ) ;
unsigned procSmpCnt = cmDspAudioBufSmpCount ( ctx , inst , kInGrId , 0 ) ;
unsigned wndSmpCnt = procSmpCnt * hopFact ;
double fcHzV [ p - > chCnt ] ;
unsigned i ;
for ( i = 0 ; i < p - > chCnt ; + + i )
{
double hz ;
if ( p - > g - > ch = = NULL | | p - > g - > ch [ i ] . hz = = 0 )
hz = cmDspDouble ( inst , kHzBaseGrId ) ;
else
hz = p - > g - > ch [ i ] . hz ;
fcHzV [ i ] = hz ;
}
if ( cmGoertzelInit ( p - > g , cmDspSysSampleRate ( ctx - > dspH ) , fcHzV , p - > chCnt , procSmpCnt , procSmpCnt , wndSmpCnt ) ! = cmOkRC )
rc = cmErrMsg ( & inst - > classPtr - > err , kSubSysFailDspRC , " Unable to initialize the internal Goertzel detector. " ) ;
return rc ;
}
2013-11-24 15:42:07 +00:00
cmDspRC_t _cmDspGoertzelFree ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspGoertzel_t * p = ( cmDspGoertzel_t * ) inst ;
cmGoertzelFree ( & p - > g ) ;
return rc ;
}
cmDspRC_t _cmDspGoertzelReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspGoertzel_t * p = ( cmDspGoertzel_t * ) inst ;
cmDspApplyAllDefaults ( ctx , inst ) ;
p - > outPhs = 0 ;
2013-11-26 18:43:14 +00:00
return _cmDspGoertzelSetup ( ctx , inst ) ;
2013-11-24 15:42:07 +00:00
}
cmDspRC_t _cmDspGoertzelExec ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspGoertzel_t * p = ( cmDspGoertzel_t * ) inst ;
const cmSample_t * x = cmDspAudioBuf ( ctx , inst , kInGrId , 0 ) ;
unsigned n = cmDspAudioBufSmpCount ( ctx , inst , kInGrId , 0 ) ;
double outMs = 50.0 ;
double outPhsMax = outMs * cmDspSysSampleRate ( ctx - > dspH ) / 1000.0 ;
2013-11-26 18:43:14 +00:00
double outV [ p - > chCnt ] ;
2013-11-24 15:42:07 +00:00
unsigned i ;
if ( x ! = NULL )
{
2013-11-26 18:43:14 +00:00
cmGoertzelExec ( p - > g , x , n , outV , p - > chCnt ) ;
2013-11-24 15:42:07 +00:00
p - > outPhs + = n ;
if ( p - > outPhs > outPhsMax )
{
while ( p - > outPhs > outPhsMax )
p - > outPhs - = outPhsMax ;
2013-11-26 18:43:14 +00:00
for ( i = 0 ; i < p - > chCnt ; + + i )
2013-11-24 15:42:07 +00:00
{
2013-11-26 18:43:14 +00:00
cmDspSetDouble ( ctx , inst , p - > outBaseGrId + i , outV [ i ] ) ;
2013-11-24 15:42:07 +00:00
//printf("%f ",outV[i]);
}
//printf("\n");
}
}
return rc ;
}
cmDspRC_t _cmDspGoertzelRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
2013-11-26 18:43:14 +00:00
cmDspGoertzel_t * p = ( cmDspGoertzel_t * ) inst ;
2013-11-24 15:42:07 +00:00
cmDspSetEvent ( ctx , inst , evt ) ;
2013-11-26 18:43:14 +00:00
if ( kHzBaseGrId < = evt - > dstVarId & & evt - > dstVarId < kHzBaseGrId + p - > chCnt )
cmGoertzelSetFcHz ( p - > g , evt - > dstVarId - kHzBaseGrId , cmDspDouble ( inst , evt - > dstVarId ) ) ;
else
{
if ( evt - > dstVarId = = kHopFactGrId )
{
_cmDspGoertzelSetup ( ctx , inst ) ;
}
}
2013-11-24 15:42:07 +00:00
return kOkDspRC ;
}
struct cmDspClass_str * cmGoertzelClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmGoertzelDC , ctx , " Goertzel " ,
NULL ,
_cmDspGoertzelAlloc ,
_cmDspGoertzelFree ,
_cmDspGoertzelReset ,
_cmDspGoertzelExec ,
_cmDspGoertzelRecv ,
NULL ,
NULL ,
" Goertzel Tone Detector Filter " ) ;
return & _cmGoertzelDC ;
}
2013-12-15 23:53:16 +00:00
//==========================================================================================================================================
enum
{
kRecdDirSrId ,
kSrFnSrId ,
kAfSrId ,
kBitsSrId ,
kCmdSrId ,
kStatusSrId ,
kD0SrId ,
kD1SrId ,
kSecSrId ,
kNSecSrId ,
kAinBaseSrId
} ;
cmDspClass_t _cmSyncRecdDC ;
typedef struct
{
cmDspInst_t inst ;
unsigned chCnt ;
cmTimeSpec_t ats ;
cmSyncRecdH_t srH ;
unsigned openSymId ;
unsigned closeSymId ;
const cmChar_t * aFn ;
const cmChar_t * srFn ;
unsigned smpIdx ;
} cmDspSyncRecd_t ;
cmDspRC_t _cmDspSyncRecdCreateFile ( cmDspCtx_t * ctx , cmDspInst_t * inst )
{
cmDspSyncRecd_t * p = ( cmDspSyncRecd_t * ) inst ;
const cmChar_t * aFn = cmDspStrcz ( inst , kAfSrId ) ;
const cmChar_t * srFn = cmDspStrcz ( inst , kSrFnSrId ) ;
const cmChar_t * dir = cmDspStrcz ( inst , kRecdDirSrId ) ;
if ( ! cmFsIsDir ( dir ) )
return cmDspInstErr ( ctx , & p - > inst , kInvalidArgDspRC , " '%s' is not a valid directory. " , cmStringNullGuard ( dir ) ) ;
cmMemPtrFree ( & p - > aFn ) ;
if ( cmFsGenFn ( dir , aFn , " aiff " , & p - > aFn ) ! = kOkFsRC )
return cmDspInstErr ( ctx , & p - > inst , kFileSysFailDspRC , " Audio file name generation failed for dir='%s' and prefix='%s'. " , cmStringNullGuard ( dir ) , cmStringNullGuard ( aFn ) ) ;
cmMemPtrFree ( & p - > srFn ) ;
if ( cmFsGenFn ( dir , srFn , " sr " , & p - > srFn ) ! = kOkFsRC )
return cmDspInstErr ( ctx , & p - > inst , kFileSysFailDspRC , " Sync-recd file name generation failed for dir='%s' and prefix='%s'. " , cmStringNullGuard ( dir ) , cmStringNullGuard ( srFn ) ) ;
unsigned bits = cmDspUInt ( inst , kBitsSrId ) ;
if ( cmSyncRecdCreate ( ctx - > cmCtx , & p - > srH , p - > srFn , p - > aFn , cmDspSampleRate ( ctx ) , p - > chCnt , bits ) ! = kOkSrRC )
return cmDspInstErr ( ctx , & p - > inst , kSubSysFailDspRC , " Sync-recd file create failed for '%s'. " , p - > srFn ) ;
p - > smpIdx = 0 ;
return kOkDspRC ;
}
cmDspInst_t * _cmDspSyncRecdAlloc ( cmDspCtx_t * ctx , cmDspClass_t * classPtr , unsigned storeSymId , unsigned instSymId , unsigned id , unsigned va_cnt , va_list vl )
{
cmDspSyncRecd_t * p = cmDspInstAllocV ( cmDspSyncRecd_t , ctx , classPtr , instSymId , id , storeSymId , va_cnt , vl ,
1 , " dir " , kRecdDirSrId , 0 , 0 , kInDsvFl | kStrzDsvFl | kReqArgDsvFl , " Recording directory. " ,
1 , " srfn " , kSrFnSrId , 0 , 0 , kInDsvFl | kStrzDsvFl | kReqArgDsvFl , " SyncRecd file prefix. " ,
1 , " afn " , kAfSrId , 0 , 0 , kInDsvFl | kStrzDsvFl | kReqArgDsvFl , " Audio file prefix. " ,
1 , " bits " , kBitsSrId , 0 , 0 , kInDsvFl | kUIntDsvFl | kOptArgDsvFl , " Audio file bits per sample. " ,
1 , " cmd " , kCmdSrId , 0 , 0 , kInDsvFl | kSymDsvFl , " Command: open | close " ,
1 , " status " , kStatusSrId , 0 , 0 , kInDsvFl | kUIntDsvFl , " MIDI status " ,
1 , " d0 " , kD0SrId , 0 , 0 , kInDsvFl | kUIntDsvFl , " MIDI d0 " ,
1 , " d1 " , kD1SrId , 0 , 0 , kInDsvFl | kUIntDsvFl , " MIDI d1 " ,
1 , " sec " , kSecSrId , 0 , 0 , kInDsvFl | kUIntDsvFl , " MIDI Timestamp Seconds " ,
1 , " nsec " , kNSecSrId , 0 , 0 , kInDsvFl | kUIntDsvFl , " MIDI Timestamp Nanoseconds " ,
2 , " ain " , kAinBaseSrId , 0 , 1 , kInDsvFl | kAudioBufDsvFl , " Audio Input " ,
0 ) ;
p - > chCnt = 2 ;
p - > openSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " open " ) ;
p - > closeSymId = cmSymTblRegisterStaticSymbol ( ctx - > stH , " close " ) ;
cmDspSetDefaultUInt ( ctx , & p - > inst , kBitsSrId , 0 , 16 ) ;
return & p - > inst ;
}
cmDspRC_t _cmDspSyncRecdFree ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspSyncRecd_t * p = ( cmDspSyncRecd_t * ) inst ;
cmMemPtrFree ( & p - > aFn ) ;
cmMemPtrFree ( & p - > srFn ) ;
cmSyncRecdFinal ( & p - > srH ) ;
return rc ;
}
cmDspRC_t _cmDspSyncRecdReset ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspApplyAllDefaults ( ctx , inst ) ;
return rc ;
}
cmDspRC_t _cmDspSyncRecdExec ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspSyncRecd_t * p = ( cmDspSyncRecd_t * ) inst ;
const cmSample_t * x [ p - > chCnt ] ;
unsigned n = 0 ;
unsigned i ;
//const cmTimeSpec_t* ts = &ctx->ctx->oTimeStamp;
//printf("SR: %ld %ld\n",ts->tv_sec,ts->tv_nsec);
p - > ats = ctx - > ctx - > iTimeStamp ;
for ( i = 0 ; i < p - > chCnt ; + + i )
{
if ( i = = 0 )
n = cmDspAudioBufSmpCount ( ctx , inst , kAinBaseSrId + i , 0 ) ;
else
{ assert ( n = = cmDspAudioBufSmpCount ( ctx , inst , kAinBaseSrId + i , 0 ) ) ; }
x [ i ] = cmDspAudioBuf ( ctx , inst , kAinBaseSrId + i , 0 ) ;
}
if ( n > 0 & & cmSyncRecdIsValid ( p - > srH ) )
if ( cmSyncRecdAudioWrite ( p - > srH , & ctx - > ctx - > iTimeStamp , p - > smpIdx , x , p - > chCnt , n ) ! = kOkSrRC )
return cmDspInstErr ( ctx , & p - > inst , kSubSysFailDspRC , " Sync-recd audio update failed. " ) ;
2013-12-17 13:55:44 +00:00
p - > smpIdx + = n ;
2013-12-15 23:53:16 +00:00
return rc ;
}
cmDspRC_t _cmDspSyncRecdRecv ( cmDspCtx_t * ctx , cmDspInst_t * inst , const cmDspEvt_t * evt )
{
cmDspRC_t rc = kOkDspRC ;
cmDspSyncRecd_t * p = ( cmDspSyncRecd_t * ) inst ;
cmDspSetEvent ( ctx , inst , evt ) ;
switch ( evt - > dstVarId )
{
case kStatusSrId :
2013-12-17 13:55:44 +00:00
if ( cmMidiIsChStatus ( cmDspUInt ( inst , kStatusSrId ) ) )
2013-12-15 23:53:16 +00:00
{
cmTimeSpec_t ts ;
ts . tv_sec = cmDspUInt ( inst , kSecSrId ) ;
ts . tv_nsec = cmDspUInt ( inst , kNSecSrId ) ;
//printf("%i %i\n",cmDspUInt(inst,kD1SrId),cmTimeElapsedMicros(&ts,&p->ats));
if ( cmSyncRecdIsValid ( p - > srH ) )
if ( cmSyncRecdMidiWrite ( p - > srH , & ts , cmDspUInt ( inst , kStatusSrId ) , cmDspUInt ( inst , kD0SrId ) , cmDspUInt ( inst , kD1SrId ) ) ! = kOkSrRC )
return cmDspInstErr ( ctx , & p - > inst , kSubSysFailDspRC , " Sync-recd MIDI update failed. " ) ;
}
break ;
case kCmdSrId :
{
unsigned cmdId = cmDspSymbol ( inst , kCmdSrId ) ;
if ( cmdId = = p - > openSymId )
rc = _cmDspSyncRecdCreateFile ( ctx , inst ) ;
else
2013-12-17 13:55:44 +00:00
if ( cmdId = = p - > closeSymId & & cmSyncRecdIsValid ( p - > srH ) )
{
2013-12-15 23:53:16 +00:00
cmSyncRecdFinal ( & p - > srH ) ;
2013-12-17 13:55:44 +00:00
//cmSyncRecdTest(ctx->cmCtx);
}
2013-12-15 23:53:16 +00:00
}
break ;
}
return rc ;
}
struct cmDspClass_str * cmSyncRecdClassCons ( cmDspCtx_t * ctx )
{
cmDspClassSetup ( & _cmSyncRecdDC , ctx , " SyncRecd " ,
NULL ,
_cmDspSyncRecdAlloc ,
_cmDspSyncRecdFree ,
_cmDspSyncRecdReset ,
_cmDspSyncRecdExec ,
_cmDspSyncRecdRecv ,
NULL ,
NULL ,
" Synchronized Audio and MIDI recorder. " ) ;
return & _cmSyncRecdDC ;
}