|
@@ -18,6 +18,7 @@
|
18
|
18
|
#include "cmThread.h"
|
19
|
19
|
#include "cmUdpPort.h"
|
20
|
20
|
#include "cmUdpNet.h"
|
|
21
|
+#include "cmTime.h"
|
21
|
22
|
#include "cmAudioSys.h"
|
22
|
23
|
#include "cmDspCtx.h"
|
23
|
24
|
#include "cmDspClass.h"
|
|
@@ -41,6 +42,7 @@
|
41
|
42
|
#include "cmTimeLine.h"
|
42
|
43
|
#include "cmScore.h"
|
43
|
44
|
#include "cmProc4.h"
|
|
45
|
+#include "cmSyncRecd.h"
|
44
|
46
|
|
45
|
47
|
enum
|
46
|
48
|
{
|
|
@@ -2911,3 +2913,198 @@ struct cmDspClass_str* cmGoertzelClassCons( cmDspCtx_t* ctx )
|
2911
|
2913
|
|
2912
|
2914
|
return &_cmGoertzelDC;
|
2913
|
2915
|
}
|
|
2916
|
+
|
|
2917
|
+//==========================================================================================================================================
|
|
2918
|
+enum
|
|
2919
|
+{
|
|
2920
|
+ kRecdDirSrId,
|
|
2921
|
+ kSrFnSrId,
|
|
2922
|
+ kAfSrId,
|
|
2923
|
+ kBitsSrId,
|
|
2924
|
+ kCmdSrId,
|
|
2925
|
+ kStatusSrId,
|
|
2926
|
+ kD0SrId,
|
|
2927
|
+ kD1SrId,
|
|
2928
|
+ kSecSrId,
|
|
2929
|
+ kNSecSrId,
|
|
2930
|
+ kAinBaseSrId
|
|
2931
|
+};
|
|
2932
|
+
|
|
2933
|
+cmDspClass_t _cmSyncRecdDC;
|
|
2934
|
+
|
|
2935
|
+typedef struct
|
|
2936
|
+{
|
|
2937
|
+ cmDspInst_t inst;
|
|
2938
|
+ unsigned chCnt;
|
|
2939
|
+ cmTimeSpec_t ats;
|
|
2940
|
+ cmSyncRecdH_t srH;
|
|
2941
|
+ unsigned openSymId;
|
|
2942
|
+ unsigned closeSymId;
|
|
2943
|
+ const cmChar_t* aFn;
|
|
2944
|
+ const cmChar_t* srFn;
|
|
2945
|
+ unsigned smpIdx;
|
|
2946
|
+} cmDspSyncRecd_t;
|
|
2947
|
+
|
|
2948
|
+cmDspRC_t _cmDspSyncRecdCreateFile( cmDspCtx_t* ctx, cmDspInst_t* inst )
|
|
2949
|
+{
|
|
2950
|
+ cmDspSyncRecd_t* p = (cmDspSyncRecd_t*)inst;
|
|
2951
|
+
|
|
2952
|
+ const cmChar_t* aFn = cmDspStrcz(inst,kAfSrId);
|
|
2953
|
+ const cmChar_t* srFn = cmDspStrcz(inst,kSrFnSrId);
|
|
2954
|
+ const cmChar_t* dir = cmDspStrcz(inst,kRecdDirSrId);
|
|
2955
|
+
|
|
2956
|
+ if( !cmFsIsDir(dir) )
|
|
2957
|
+ return cmDspInstErr(ctx,&p->inst,kInvalidArgDspRC,"'%s' is not a valid directory.",cmStringNullGuard(dir));
|
|
2958
|
+
|
|
2959
|
+ cmMemPtrFree(&p->aFn);
|
|
2960
|
+ if( cmFsGenFn(dir,aFn,"aiff",&p->aFn) != kOkFsRC )
|
|
2961
|
+ return cmDspInstErr(ctx,&p->inst,kFileSysFailDspRC,"Audio file name generation failed for dir='%s' and prefix='%s'.",cmStringNullGuard(dir),cmStringNullGuard(aFn));
|
|
2962
|
+
|
|
2963
|
+ cmMemPtrFree(&p->srFn);
|
|
2964
|
+ if( cmFsGenFn(dir,srFn,"sr",&p->srFn) != kOkFsRC )
|
|
2965
|
+ return cmDspInstErr(ctx,&p->inst,kFileSysFailDspRC,"Sync-recd file name generation failed for dir='%s' and prefix='%s'.",cmStringNullGuard(dir),cmStringNullGuard(srFn));
|
|
2966
|
+
|
|
2967
|
+ unsigned bits = cmDspUInt(inst,kBitsSrId);
|
|
2968
|
+ if( cmSyncRecdCreate( ctx->cmCtx, &p->srH, p->srFn, p->aFn, cmDspSampleRate(ctx), p->chCnt, bits ) != kOkSrRC )
|
|
2969
|
+ return cmDspInstErr(ctx,&p->inst,kSubSysFailDspRC,"Sync-recd file create failed for '%s'.",p->srFn);
|
|
2970
|
+
|
|
2971
|
+ p->smpIdx = 0;
|
|
2972
|
+
|
|
2973
|
+ return kOkDspRC;
|
|
2974
|
+}
|
|
2975
|
+
|
|
2976
|
+cmDspInst_t* _cmDspSyncRecdAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
|
|
2977
|
+{
|
|
2978
|
+ cmDspSyncRecd_t* p = cmDspInstAllocV(cmDspSyncRecd_t,ctx,classPtr,instSymId,id,storeSymId,va_cnt,vl,
|
|
2979
|
+ 1, "dir", kRecdDirSrId, 0,0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "Recording directory.",
|
|
2980
|
+ 1, "srfn", kSrFnSrId, 0,0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "SyncRecd file prefix.",
|
|
2981
|
+ 1, "afn", kAfSrId, 0,0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "Audio file prefix.",
|
|
2982
|
+ 1, "bits", kBitsSrId, 0,0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "Audio file bits per sample.",
|
|
2983
|
+ 1, "cmd", kCmdSrId, 0,0, kInDsvFl | kSymDsvFl, "Command: open | close",
|
|
2984
|
+ 1, "status", kStatusSrId, 0,0, kInDsvFl | kUIntDsvFl, "MIDI status",
|
|
2985
|
+ 1, "d0", kD0SrId, 0,0, kInDsvFl | kUIntDsvFl, "MIDI d0",
|
|
2986
|
+ 1, "d1", kD1SrId, 0,0, kInDsvFl | kUIntDsvFl, "MIDI d1",
|
|
2987
|
+ 1, "sec", kSecSrId, 0,0, kInDsvFl | kUIntDsvFl, "MIDI Timestamp Seconds",
|
|
2988
|
+ 1, "nsec", kNSecSrId, 0,0, kInDsvFl | kUIntDsvFl, "MIDI Timestamp Nanoseconds",
|
|
2989
|
+ 2, "ain", kAinBaseSrId, 0,1, kInDsvFl | kAudioBufDsvFl, "Audio Input",
|
|
2990
|
+ 0 );
|
|
2991
|
+
|
|
2992
|
+ p->chCnt = 2;
|
|
2993
|
+
|
|
2994
|
+ p->openSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"open");
|
|
2995
|
+ p->closeSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"close");
|
|
2996
|
+
|
|
2997
|
+ cmDspSetDefaultUInt(ctx,&p->inst,kBitsSrId,0,16);
|
|
2998
|
+
|
|
2999
|
+ return &p->inst;
|
|
3000
|
+}
|
|
3001
|
+
|
|
3002
|
+
|
|
3003
|
+cmDspRC_t _cmDspSyncRecdFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
|
3004
|
+{
|
|
3005
|
+ cmDspRC_t rc = kOkDspRC;
|
|
3006
|
+ cmDspSyncRecd_t* p = (cmDspSyncRecd_t*)inst;
|
|
3007
|
+
|
|
3008
|
+ cmMemPtrFree(&p->aFn);
|
|
3009
|
+ cmMemPtrFree(&p->srFn);
|
|
3010
|
+ cmSyncRecdFinal(&p->srH);
|
|
3011
|
+
|
|
3012
|
+ return rc;
|
|
3013
|
+}
|
|
3014
|
+
|
|
3015
|
+cmDspRC_t _cmDspSyncRecdReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
|
3016
|
+{
|
|
3017
|
+ cmDspRC_t rc = kOkDspRC;
|
|
3018
|
+
|
|
3019
|
+ cmDspApplyAllDefaults(ctx,inst);
|
|
3020
|
+
|
|
3021
|
+ return rc;
|
|
3022
|
+}
|
|
3023
|
+
|
|
3024
|
+cmDspRC_t _cmDspSyncRecdExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
|
3025
|
+{
|
|
3026
|
+
|
|
3027
|
+ cmDspRC_t rc = kOkDspRC;
|
|
3028
|
+
|
|
3029
|
+ cmDspSyncRecd_t* p = (cmDspSyncRecd_t*)inst;
|
|
3030
|
+
|
|
3031
|
+ const cmSample_t* x[ p->chCnt ];
|
|
3032
|
+ unsigned n = 0;
|
|
3033
|
+ unsigned i;
|
|
3034
|
+
|
|
3035
|
+ //const cmTimeSpec_t* ts = &ctx->ctx->oTimeStamp;
|
|
3036
|
+ //printf("SR: %ld %ld\n",ts->tv_sec,ts->tv_nsec);
|
|
3037
|
+ p->ats = ctx->ctx->iTimeStamp;
|
|
3038
|
+
|
|
3039
|
+ for(i=0; i<p->chCnt; ++i)
|
|
3040
|
+ {
|
|
3041
|
+ if( i==0 )
|
|
3042
|
+ n = cmDspAudioBufSmpCount(ctx,inst,kAinBaseSrId+i,0);
|
|
3043
|
+ else
|
|
3044
|
+ { assert( n == cmDspAudioBufSmpCount(ctx,inst,kAinBaseSrId+i,0)); }
|
|
3045
|
+
|
|
3046
|
+ x[i] = cmDspAudioBuf(ctx,inst,kAinBaseSrId+i,0);
|
|
3047
|
+ }
|
|
3048
|
+
|
|
3049
|
+ if( n>0 && cmSyncRecdIsValid(p->srH ) )
|
|
3050
|
+ if( cmSyncRecdAudioWrite( p->srH, &ctx->ctx->iTimeStamp, p->smpIdx, x, p->chCnt, n ) != kOkSrRC )
|
|
3051
|
+ return cmDspInstErr(ctx,&p->inst,kSubSysFailDspRC,"Sync-recd audio update failed.");
|
|
3052
|
+
|
|
3053
|
+ return rc;
|
|
3054
|
+}
|
|
3055
|
+
|
|
3056
|
+cmDspRC_t _cmDspSyncRecdRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
|
3057
|
+{
|
|
3058
|
+ cmDspRC_t rc = kOkDspRC;
|
|
3059
|
+ cmDspSyncRecd_t* p = (cmDspSyncRecd_t*)inst;
|
|
3060
|
+
|
|
3061
|
+ cmDspSetEvent(ctx,inst,evt);
|
|
3062
|
+
|
|
3063
|
+ switch( evt->dstVarId )
|
|
3064
|
+ {
|
|
3065
|
+ case kStatusSrId:
|
|
3066
|
+ if(cmMidiIsChStatus( evt->dstVarId ) )
|
|
3067
|
+ {
|
|
3068
|
+ cmTimeSpec_t ts;
|
|
3069
|
+ ts.tv_sec = cmDspUInt(inst,kSecSrId);
|
|
3070
|
+ ts.tv_nsec = cmDspUInt(inst,kNSecSrId);
|
|
3071
|
+
|
|
3072
|
+ //printf("%i %i\n",cmDspUInt(inst,kD1SrId),cmTimeElapsedMicros(&ts,&p->ats));
|
|
3073
|
+
|
|
3074
|
+ if( cmSyncRecdIsValid(p->srH ) )
|
|
3075
|
+ if( cmSyncRecdMidiWrite(p->srH, &ts, cmDspUInt(inst,kStatusSrId), cmDspUInt(inst,kD0SrId), cmDspUInt(inst,kD1SrId) ) != kOkSrRC )
|
|
3076
|
+ return cmDspInstErr(ctx,&p->inst,kSubSysFailDspRC,"Sync-recd MIDI update failed.");
|
|
3077
|
+ }
|
|
3078
|
+ break;
|
|
3079
|
+
|
|
3080
|
+ case kCmdSrId:
|
|
3081
|
+ {
|
|
3082
|
+ unsigned cmdId = cmDspSymbol(inst,kCmdSrId);
|
|
3083
|
+ if( cmdId == p->openSymId )
|
|
3084
|
+ rc = _cmDspSyncRecdCreateFile(ctx,inst);
|
|
3085
|
+ else
|
|
3086
|
+ if( cmdId == p->closeSymId )
|
|
3087
|
+ cmSyncRecdFinal(&p->srH);
|
|
3088
|
+
|
|
3089
|
+ }
|
|
3090
|
+ break;
|
|
3091
|
+ }
|
|
3092
|
+
|
|
3093
|
+ return rc;
|
|
3094
|
+}
|
|
3095
|
+
|
|
3096
|
+struct cmDspClass_str* cmSyncRecdClassCons( cmDspCtx_t* ctx )
|
|
3097
|
+{
|
|
3098
|
+ cmDspClassSetup(&_cmSyncRecdDC,ctx,"SyncRecd",
|
|
3099
|
+ NULL,
|
|
3100
|
+ _cmDspSyncRecdAlloc,
|
|
3101
|
+ _cmDspSyncRecdFree,
|
|
3102
|
+ _cmDspSyncRecdReset,
|
|
3103
|
+ _cmDspSyncRecdExec,
|
|
3104
|
+ _cmDspSyncRecdRecv,
|
|
3105
|
+ NULL,
|
|
3106
|
+ NULL,
|
|
3107
|
+ "Synchronized Audio and MIDI recorder.");
|
|
3108
|
+
|
|
3109
|
+ return &_cmSyncRecdDC;
|
|
3110
|
+}
|