|
@@ -31,7 +31,6 @@
|
31
|
31
|
#include "cmDspNet.h"
|
32
|
32
|
|
33
|
33
|
#include "cmAudioFile.h"
|
34
|
|
-#include "cmOp.h"
|
35
|
34
|
#include "cmThread.h" // used for threaded loading in wave table file mode
|
36
|
35
|
|
37
|
36
|
|
|
@@ -1055,7 +1054,7 @@ cmDspRC_t _cmDspAudioInExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t
|
1055
|
1054
|
|
1056
|
1055
|
// if this channel is disabled then iChArray[chIdx] will be NULL
|
1057
|
1056
|
if( ctx->ctx->iChArray[chIdx]!=NULL )
|
1058
|
|
- vs_MultVVS(dp,ctx->ctx->iChArray[chIdx],n,gain);
|
|
1057
|
+ cmVOS_MultVVS(dp,n,ctx->ctx->iChArray[chIdx],(cmSample_t)gain);
|
1059
|
1058
|
|
1060
|
1059
|
return kOkDspRC;
|
1061
|
1060
|
}
|
|
@@ -1170,7 +1169,7 @@ cmDspRC_t _cmDspAudioOutExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
1170
|
1169
|
|
1171
|
1170
|
// if this channel is disabled or set to pass-through then chArray[chIdx] will be NULL
|
1172
|
1171
|
if( ctx->ctx->oChArray[chIdx] != NULL )
|
1173
|
|
- vs_MultVVS(ctx->ctx->oChArray[chIdx],sp,n,gain);
|
|
1172
|
+ cmVOS_MultVVS(ctx->ctx->oChArray[chIdx],n,sp,(cmSample_t)gain);
|
1174
|
1173
|
|
1175
|
1174
|
return kOkDspRC;
|
1176
|
1175
|
}
|
|
@@ -1329,7 +1328,7 @@ cmDspRC_t _cmDspAudioFileOutExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDsp
|
1329
|
1328
|
const cmSample_t* sp = i==0 ? cmDspAudioBuf(ctx,inst,kIn0AofId,0) : cmDspAudioBuf(ctx,inst,kIn1AofId,0);
|
1330
|
1329
|
cmSample_t gain = i==0 ? cmDspDouble(inst,kGain0AofId) : cmDspDouble(inst,kGain1AofId);
|
1331
|
1330
|
|
1332
|
|
- cmVOS_MultVVS(chArray[i], n, sp, gain);
|
|
1331
|
+ cmVOS_MultVVS(chArray[i], n, sp, (cmSample_t)gain);
|
1333
|
1332
|
|
1334
|
1333
|
}
|
1335
|
1334
|
|
|
@@ -2732,7 +2731,9 @@ enum
|
2732
|
2731
|
kGainWtId,
|
2733
|
2732
|
kPhsWtId,
|
2734
|
2733
|
kOutWtId,
|
2735
|
|
- kCntWtId
|
|
2734
|
+ kCntWtId,
|
|
2735
|
+ kFIdxWtId,
|
|
2736
|
+ kDoneWtId
|
2736
|
2737
|
};
|
2737
|
2738
|
|
2738
|
2739
|
enum
|
|
@@ -2762,6 +2763,8 @@ typedef struct
|
2762
|
2763
|
unsigned wtn; // count of empty samples (avail for writing over) in the wavetable.
|
2763
|
2764
|
unsigned fi; // absolute index into the file of the next sample to read
|
2764
|
2765
|
unsigned fn; // length of the file in samples
|
|
2766
|
+ unsigned cfi; // absolute index into the file of the beginning of the current audio vector
|
|
2767
|
+ unsigned cfn; // when cfi >= cfn and doneFl is set then the 'done' msg is sent
|
2765
|
2768
|
unsigned loopCnt; // current loop count
|
2766
|
2769
|
bool doneFl; // the wave table source is exhausted
|
2767
|
2770
|
cmAudioFileH_t afH; // current audio file handle
|
|
@@ -2774,6 +2777,7 @@ typedef struct
|
2774
|
2777
|
double phsLast;
|
2775
|
2778
|
unsigned onSymId;
|
2776
|
2779
|
unsigned offSymId;
|
|
2780
|
+ unsigned doneSymId;
|
2777
|
2781
|
} cmDspWaveTable_t;
|
2778
|
2782
|
|
2779
|
2783
|
bool _cmDspWaveTableThreadFunc( void* param);
|
|
@@ -2785,7 +2789,7 @@ cmDspInst_t* _cmDspWaveTableAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsi
|
2785
|
2789
|
{ "len", kLenWtId, 0, 0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "Wave table length in samples" },
|
2786
|
2790
|
{ "shape", kShapeWtId, 0, 0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "Wave shape 0=silent 1=file 2=sine 3=white" },
|
2787
|
2791
|
{ "fn", kFnWtId, 0, 0, kInDsvFl | kStrzDsvFl | kOptArgDsvFl, "Optional audio file name" },
|
2788
|
|
- { "loop", kLoopWtId, 0, 0, kInDsvFl | kIntDsvFl | kOptArgDsvFl, "-1=loop forever >0=loop count"},
|
|
2792
|
+ { "loop", kLoopWtId, 0, 0, kInDsvFl | kIntDsvFl | kOptArgDsvFl, "-1=loop forever >0=loop count (dflt:-1)"},
|
2789
|
2793
|
{ "beg", kBegWtId, 0, 0, kInDsvFl | kIntDsvFl | kOptArgDsvFl, "File begin sample index" },
|
2790
|
2794
|
{ "end", kEndWtId, 0, 0, kInDsvFl | kIntDsvFl | kOptArgDsvFl, "File end sample index (-1=play all)" },
|
2791
|
2795
|
{ "cmd", kCmdWtId, 0, 0, kInDsvFl | kSymDsvFl | kOptArgDsvFl, "Command: on off"},
|
|
@@ -2794,6 +2798,8 @@ cmDspInst_t* _cmDspWaveTableAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsi
|
2794
|
2798
|
{ "phs", kPhsWtId, 0, 0, kInDsvFl | kAudioBufDsvFl, "Driving phase" },
|
2795
|
2799
|
{ "out", kOutWtId, 0, 1, kOutDsvFl | kAudioBufDsvFl, "Audio output" },
|
2796
|
2800
|
{ "cnt", kCntWtId, 0, 0, kOutDsvFl | kIntDsvFl, "Loop count event."},
|
|
2801
|
+ { "fidx", kFIdxWtId, 0, 0, kOutDsvFl | kUIntDsvFl, "Current audio file index."},
|
|
2802
|
+ { "done", kDoneWtId, 0, 0, kOutDsvFl | kSymDsvFl, "'done' sent after last loop."},
|
2797
|
2803
|
{ NULL, 0, 0, 0, 0 }
|
2798
|
2804
|
};
|
2799
|
2805
|
|
|
@@ -2804,6 +2810,7 @@ cmDspInst_t* _cmDspWaveTableAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsi
|
2804
|
2810
|
|
2805
|
2811
|
p->offSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"off");
|
2806
|
2812
|
p->onSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"on");
|
|
2813
|
+ p->doneSymId= cmSymTblRegisterStaticSymbol(ctx->stH,"done");
|
2807
|
2814
|
|
2808
|
2815
|
cmDspSetDefaultUInt( ctx, &p->inst, kLenWtId, 0, cmDspSampleRate(ctx));
|
2809
|
2816
|
cmDspSetDefaultUInt( ctx, &p->inst, kShapeWtId, 0, kSilenceWtId );
|
|
@@ -2814,6 +2821,7 @@ cmDspInst_t* _cmDspWaveTableAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsi
|
2814
|
2821
|
cmDspSetDefaultSymbol(ctx, &p->inst, kCmdWtId, p->onSymId );
|
2815
|
2822
|
cmDspSetDefaultUInt( ctx, &p->inst, kOtWtId, 0, 5 );
|
2816
|
2823
|
cmDspSetDefaultDouble(ctx, &p->inst, kGainWtId, 0, 1.0 );
|
|
2824
|
+ cmDspSetDefaultUInt( ctx, &p->inst, kFIdxWtId, 0, 0 );
|
2817
|
2825
|
|
2818
|
2826
|
return &p->inst;
|
2819
|
2827
|
}
|
|
@@ -2889,7 +2897,11 @@ cmDspRC_t _cmDspWaveTableReadBlock( cmDspCtx_t* ctx, cmDspWaveTable_t* p, cmSamp
|
2889
|
2897
|
if( maxLoopCnt != -1 && p->loopCnt >= maxLoopCnt )
|
2890
|
2898
|
{
|
2891
|
2899
|
p->doneFl = true;
|
2892
|
|
- vs_Zero(wt,n1); // zero to the end of the buffer
|
|
2900
|
+ cmVOS_Zero(wt,n1); // zero to the end of the buffer
|
|
2901
|
+
|
|
2902
|
+ p->cfn = p->cfi + cmDspUInt((cmDspInst_t*)p,kLenWtId) - p->wtn - n0;
|
|
2903
|
+ assert( p->cfn >= p->cfi );
|
|
2904
|
+
|
2893
|
2905
|
}
|
2894
|
2906
|
else
|
2895
|
2907
|
{
|
|
@@ -2904,7 +2916,8 @@ cmDspRC_t _cmDspWaveTableReadBlock( cmDspCtx_t* ctx, cmDspWaveTable_t* p, cmSamp
|
2904
|
2916
|
assert( actFrmCnt == n1 );
|
2905
|
2917
|
|
2906
|
2918
|
// reset the file index tracker
|
2907
|
|
- p->fi = begSmpIdx + n1;
|
|
2919
|
+ p->fi = begSmpIdx + n1;
|
|
2920
|
+ p->cfi = begSmpIdx;
|
2908
|
2921
|
}
|
2909
|
2922
|
}
|
2910
|
2923
|
|
|
@@ -2931,33 +2944,31 @@ cmDspRC_t _cmDspWaveTableReadAudioFile( cmDspCtx_t* ctx, cmDspWaveTable_t* p, un
|
2931
|
2944
|
|
2932
|
2945
|
assert(n1<wtSmpCnt);
|
2933
|
2946
|
|
2934
|
|
- // if the EOF was encountered on a previous read
|
|
2947
|
+ // the first read always starts at p->wt + p->wti
|
2935
|
2948
|
if( p->doneFl )
|
2936
|
|
- {
|
2937
|
|
- vs_Zero(p->wt + p->wti,n0);
|
2938
|
|
- vs_Zero(p->wt,n1);
|
2939
|
|
- }
|
|
2949
|
+ cmVOS_Zero(p->wt + p->wti,n0);
|
2940
|
2950
|
else
|
2941
|
|
- {
|
2942
|
|
-
|
2943
|
|
- // the first read always starts at p->wt + p->wti
|
2944
|
2951
|
if( _cmDspWaveTableReadBlock(ctx, p, p->wt+p->wti, n0,begSmpIdx,endSmpIdx,maxLoopCnt ) != kOkDspRC )
|
2945
|
2952
|
return cmDspInstErr(ctx,&p->inst,kVarNotValidDspRC,"An error occured while reading the wave table file.");
|
2946
|
2953
|
|
2947
|
|
- p->wti += n0;
|
|
2954
|
+ p->wtn -= n0; // decrease the count of available samples
|
|
2955
|
+ p->wti += n0;
|
2948
|
2956
|
|
2949
|
|
- if( n1 > 0 )
|
2950
|
|
- {
|
2951
|
|
- // the second read always starts at the beginning of the wave table
|
|
2957
|
+ if( n1 > 0 )
|
|
2958
|
+ {
|
|
2959
|
+ // the second read always starts at the beginning of the wave table
|
|
2960
|
+ if( p->doneFl )
|
|
2961
|
+ cmVOS_Zero(p->wt,n1);
|
|
2962
|
+ else
|
2952
|
2963
|
if( _cmDspWaveTableReadBlock(ctx, p, p->wt, n1,begSmpIdx,endSmpIdx,maxLoopCnt ) != kOkDspRC )
|
2953
|
2964
|
return cmDspInstErr(ctx,&p->inst,kVarNotValidDspRC,"An error occured while reading the wave table file.");
|
2954
|
2965
|
|
2955
|
|
- p->wti = n1;
|
2956
|
|
- }
|
2957
|
|
-
|
|
2966
|
+ p->wtn -= n1; // decrease the count of available samples
|
|
2967
|
+ p->wti = n1;
|
2958
|
2968
|
}
|
|
2969
|
+
|
2959
|
2970
|
|
2960
|
|
- p->wtn -= rdSmpCnt; // decrease the count of availabe sample
|
|
2971
|
+ //p->wtn -= rdSmpCnt; // decrease the count of available samples
|
2961
|
2972
|
|
2962
|
2973
|
return kOkDspRC;
|
2963
|
2974
|
}
|
|
@@ -3003,6 +3014,7 @@ cmDspRC_t _cmDspWaveTableInitAudioFile( cmDspCtx_t* ctx, cmDspWaveTable_t* p )
|
3003
|
3014
|
|
3004
|
3015
|
p->afH = afH;
|
3005
|
3016
|
p->fi = begSmpIdx;
|
|
3017
|
+ p->cfi = begSmpIdx;
|
3006
|
3018
|
p->fn = afInfo.frameCnt;
|
3007
|
3019
|
p->wti = 0;
|
3008
|
3020
|
p->wtn = wtSmpCnt;
|
|
@@ -3060,12 +3072,11 @@ cmDspRC_t _cmDspWaveTableStartFileLoadThread( cmDspCtx_t* ctx, cmDspWaveTable_t*
|
3060
|
3072
|
if(cmThreadIsValid(p->thH) == false)
|
3061
|
3073
|
cmThreadCreate(&p->thH,_cmDspWaveTableThreadFunc,p,ctx->rpt);
|
3062
|
3074
|
|
3063
|
|
-
|
3064
|
3075
|
if( cmThreadIsValid(p->thH) == false )
|
3065
|
3076
|
return cmDspInstErr(ctx,&p->inst,kInvalidStateDspRC,"The audio file '%s' was not loaded because the audio load thread is invalid.",cmStringNullGuard(fn));
|
3066
|
3077
|
|
3067
|
3078
|
p->loadFileFl = true;
|
3068
|
|
- p->ctx = ctx;
|
|
3079
|
+ p->ctx = ctx;
|
3069
|
3080
|
cmDspSetUInt(ctx,&p->inst,kShapeWtId,kSilenceWtId);
|
3070
|
3081
|
cmDspSetStrcz(ctx,&p->inst,kFnWtId,fn);
|
3071
|
3082
|
|
|
@@ -3104,7 +3115,7 @@ cmDspRC_t _cmDspWaveTableCreateTable( cmDspCtx_t* ctx, cmDspWaveTable_t* p )
|
3104
|
3115
|
if( p->wt == NULL )
|
3105
|
3116
|
p->wt = cmLhResizeNZ(ctx->lhH,cmSample_t,p->wt,wtSmpCnt);
|
3106
|
3117
|
else
|
3107
|
|
- vs_Zero(p->wt,wtSmpCnt);
|
|
3118
|
+ cmVOS_Zero(p->wt,wtSmpCnt);
|
3108
|
3119
|
|
3109
|
3120
|
p->wtn = wtSmpCnt; // all samples in the wt are avail for filling
|
3110
|
3121
|
p->wti = 0; // beginning with the first sample
|
|
@@ -3122,16 +3133,6 @@ cmDspRC_t _cmDspWaveTableCreateTable( cmDspCtx_t* ctx, cmDspWaveTable_t* p )
|
3122
|
3133
|
printf("Loading:%i %i %s\n",p->nxtBegSmpIdx,p->nxtEndSmpIdx,cmDspStrcz(&p->inst,kFnWtId));
|
3123
|
3134
|
rc = _cmDspWaveTableStartFileLoadThread(ctx,p,cmDspStrcz(&p->inst,kFnWtId));
|
3124
|
3135
|
break;
|
3125
|
|
- /*
|
3126
|
|
- case kWhiteWtId:
|
3127
|
|
- vs_Rand(p->wt,wtSmpCnt,-1.0,1.0);
|
3128
|
|
- break;
|
3129
|
|
-
|
3130
|
|
- case kSineWtId:
|
3131
|
|
- //vs_Sine(p->wt, wtSmpCnt, 1000.0*2*M_PI/wtSmpCnt, 0 );
|
3132
|
|
- cmVOS_SynthSine(p->wt,wtSmpCnt,0,cmDspSampleRate(ctx),1.0);
|
3133
|
|
- break;
|
3134
|
|
- */
|
3135
|
3136
|
|
3136
|
3137
|
case kWhiteWtId:
|
3137
|
3138
|
cmVOS_Random(p->wt,wtSmpCnt,-gain,gain);
|
|
@@ -3152,7 +3153,6 @@ cmDspRC_t _cmDspWaveTableCreateTable( cmDspCtx_t* ctx, cmDspWaveTable_t* p )
|
3152
|
3153
|
cmVOS_MultVS(p->wt,wtSmpCnt,gain);
|
3153
|
3154
|
break;
|
3154
|
3155
|
|
3155
|
|
-
|
3156
|
3156
|
case kSawWtId:
|
3157
|
3157
|
cmVOS_SynthSawtooth(p->wt,wtSmpCnt,0,sr,hz,otCnt);
|
3158
|
3158
|
cmVOS_MultVS(p->wt,wtSmpCnt,gain);
|
|
@@ -3262,6 +3262,15 @@ cmDspRC_t _cmDspWaveTableExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
|
3262
|
3262
|
// ... and there are rdSmpCnt avail locations in the wave table
|
3263
|
3263
|
if( p->wtn >= rdSmpCnt )
|
3264
|
3264
|
rc = _cmDspWaveTableReadAudioFile(ctx, p, wtSmpCnt, rdSmpCnt );
|
|
3265
|
+
|
|
3266
|
+ // send the current audio file index
|
|
3267
|
+ if( p->doneFl && p->cfi < p->cfn && p->cfn <= (p->cfi + outCnt) )
|
|
3268
|
+ cmDspSetSymbol(ctx,inst,kDoneWtId,p->doneSymId);
|
|
3269
|
+ else
|
|
3270
|
+ cmDspSetUInt(ctx,inst,kFIdxWtId,p->cfi);
|
|
3271
|
+
|
|
3272
|
+ p->cfi += outCnt;
|
|
3273
|
+
|
3265
|
3274
|
}
|
3266
|
3275
|
|
3267
|
3276
|
return rc;
|
|
@@ -3321,7 +3330,9 @@ cmDspRC_t _cmDspWaveTableRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
|
3321
|
3330
|
{
|
3322
|
3331
|
if( cmDspSymbol(inst,kCmdWtId) == p->onSymId )
|
3323
|
3332
|
{
|
3324
|
|
- rc = _cmDspWaveTableReset(ctx,inst, evt );
|
|
3333
|
+ //rc = _cmDspWaveTableReset(ctx,inst, evt );
|
|
3334
|
+ rc = _cmDspWaveTableCreateTable(ctx,p);
|
|
3335
|
+
|
3325
|
3336
|
cmDspSetSymbol(ctx,inst,kCmdWtId,p->onSymId);
|
3326
|
3337
|
p->phsOffs = 0;
|
3327
|
3338
|
p->phsLast = 0;
|
|
@@ -3858,7 +3869,7 @@ cmDspRC_t _cmDspAMixExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* e
|
3858
|
3869
|
if( sp != NULL )
|
3859
|
3870
|
{
|
3860
|
3871
|
double gain = cmDspDouble(inst,p->baseGainId+i);
|
3861
|
|
- vs_SumMultVVS(dp,sp,n,gain);
|
|
3872
|
+ cmVOS_MultSumVVS(dp,n,sp,(cmSample_t)gain);
|
3862
|
3873
|
}
|
3863
|
3874
|
}
|
3864
|
3875
|
|
|
@@ -4015,7 +4026,7 @@ cmDspRC_t _cmDspASplitExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
4015
|
4026
|
{
|
4016
|
4027
|
cmSample_t* dp = cmDspAudioBuf(ctx,inst,kBaseOutAsId+i,0);
|
4017
|
4028
|
double gain = cmDspDouble(inst,p->baseGainId+i);
|
4018
|
|
- vs_MultVVS(dp,sp,n,gain);
|
|
4029
|
+ cmVOS_MultVVS(dp,n,sp,(cmSample_t)gain);
|
4019
|
4030
|
}
|
4020
|
4031
|
|
4021
|
4032
|
return kOkDspRC;
|
|
@@ -4128,7 +4139,7 @@ cmDspRC_t _cmDspAMeterExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
4128
|
4139
|
return kOkDspRC;
|
4129
|
4140
|
}
|
4130
|
4141
|
|
4131
|
|
- p->sum += vs_SquaredSum(sp,n);
|
|
4142
|
+ p->sum += cmVOS_SquaredSum(sp,n);
|
4132
|
4143
|
++p->idx;
|
4133
|
4144
|
|
4134
|
4145
|
if( p->idx == p->bufN )
|
|
@@ -4991,6 +5002,7 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
|
4991
|
5002
|
cmSegLineClassCons,
|
4992
|
5003
|
|
4993
|
5004
|
cmTimeLineClassCons,
|
|
5005
|
+ cmScoreClassCons,
|
4994
|
5006
|
cmMidiFilePlayClassCons,
|
4995
|
5007
|
cmScFolClassCons,
|
4996
|
5008
|
|