|
@@ -1067,6 +1067,7 @@ enum
|
1067
|
1067
|
{
|
1068
|
1068
|
kChAoId,
|
1069
|
1069
|
kGainAoId,
|
|
1070
|
+ kEnableAoId,
|
1070
|
1071
|
kInAoId
|
1071
|
1072
|
};
|
1072
|
1073
|
|
|
@@ -1075,23 +1076,30 @@ cmDspClass_t _cmAudioOutDC;
|
1075
|
1076
|
typedef struct
|
1076
|
1077
|
{
|
1077
|
1078
|
cmDspInst_t inst;
|
|
1079
|
+ unsigned onSymId;
|
|
1080
|
+ unsigned offSymId;
|
1078
|
1081
|
} cmDspAudioOut_t;
|
1079
|
1082
|
|
1080
|
1083
|
cmDspInst_t* _cmDspAudioOutAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
|
1081
|
1084
|
{
|
1082
|
1085
|
cmDspVarArg_t args[] =
|
1083
|
1086
|
{
|
1084
|
|
- { "ch", kChAoId, 0, 0, kInDsvFl | kUIntDsvFl | kReqArgDsvFl, "Audio output channel index"},
|
1085
|
|
- { "gain",kGainAoId,0, 0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Output gain multiplier"},
|
1086
|
|
- { "in", kInAoId, 0, 1, kInDsvFl | kAudioBufDsvFl, "Audio input" },
|
|
1087
|
+ { "ch", kChAoId, 0, 0, kInDsvFl | kUIntDsvFl | kReqArgDsvFl, "Audio output channel index"},
|
|
1088
|
+ { "gain", kGainAoId, 0, 0, kInDsvFl | kDoubleDsvFl | kOptArgDsvFl, "Output gain multiplier"},
|
|
1089
|
+ { "enable",kEnableAoId,0, 0, kInDsvFl | kSymDsvFl | kOptArgDsvFl, "Enable: on off"},
|
|
1090
|
+ { "in", kInAoId, 0, 1, kInDsvFl | kAudioBufDsvFl, "Audio input" },
|
1087
|
1091
|
{ NULL, 0, 0, 0, 0 }
|
1088
|
1092
|
};
|
1089
|
1093
|
|
1090
|
1094
|
cmDspAudioOut_t* p = cmDspInstAlloc(cmDspAudioOut_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
|
1091
|
1095
|
|
|
1096
|
+ p->offSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"off");
|
|
1097
|
+ p->onSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"on");
|
|
1098
|
+
|
1092
|
1099
|
|
1093
|
1100
|
cmDspSetDefaultUInt( ctx, &p->inst, kChAoId, 0, 0);
|
1094
|
1101
|
cmDspSetDefaultDouble( ctx, &p->inst, kGainAoId, 0, 1.0);
|
|
1102
|
+ cmDspSetDefaultSymbol( ctx, &p->inst, kEnableAoId, p->onSymId );
|
1095
|
1103
|
|
1096
|
1104
|
return &p->inst;
|
1097
|
1105
|
}
|
|
@@ -1106,10 +1114,12 @@ cmDspRC_t _cmDspAudioOutReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
|
1106
|
1114
|
|
1107
|
1115
|
cmDspRC_t _cmDspAudioOutExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
1108
|
1116
|
{
|
1109
|
|
- cmDspRC_t rc = kOkDspRC;
|
1110
|
|
- unsigned chIdx = cmDspUInt(inst,kChAoId);
|
1111
|
|
- unsigned oChCnt = ctx->ctx->oChCnt;
|
1112
|
|
- double gain = cmDspDouble(inst,kGainAoId);
|
|
1117
|
+ cmDspRC_t rc = kOkDspRC;
|
|
1118
|
+ cmDspAudioOut_t* p = (cmDspAudioOut_t*)inst;
|
|
1119
|
+ unsigned chIdx = cmDspUInt(inst,kChAoId);
|
|
1120
|
+ bool enableFl = cmDspSymbol(inst,kEnableAoId) == p->onSymId;
|
|
1121
|
+ unsigned oChCnt = ctx->ctx->oChCnt;
|
|
1122
|
+ double gain = cmDspDouble(inst,kGainAoId);
|
1113
|
1123
|
|
1114
|
1124
|
if( chIdx >= oChCnt )
|
1115
|
1125
|
{
|
|
@@ -1118,7 +1128,7 @@ cmDspRC_t _cmDspAudioOutExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
1118
|
1128
|
return rc;
|
1119
|
1129
|
}
|
1120
|
1130
|
|
1121
|
|
- const cmSample_t* sp = cmDspAudioBuf(ctx,inst,kInAoId,0);
|
|
1131
|
+ const cmSample_t* sp = cmDspAudioBuf(ctx,inst,kInAoId,0);
|
1122
|
1132
|
|
1123
|
1133
|
if( sp == NULL )
|
1124
|
1134
|
{
|
|
@@ -1132,7 +1142,7 @@ cmDspRC_t _cmDspAudioOutExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
1132
|
1142
|
|
1133
|
1143
|
// if this channel is disabled or set to pass-through then chArray[chIdx] will be NULL
|
1134
|
1144
|
if( ctx->ctx->oChArray[chIdx] != NULL )
|
1135
|
|
- cmVOS_MultVVS(ctx->ctx->oChArray[chIdx],n,sp,(cmSample_t)gain);
|
|
1145
|
+ cmVOS_MultVVS(ctx->ctx->oChArray[chIdx],n,sp, (cmSample_t)(enableFl ? gain : 0));
|
1136
|
1146
|
|
1137
|
1147
|
return kOkDspRC;
|
1138
|
1148
|
}
|
|
@@ -1154,6 +1164,11 @@ cmDspRC_t _cmDspAudioOutRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
1154
|
1164
|
case kGainAoId:
|
1155
|
1165
|
cmDspSetEvent(ctx,inst,evt);
|
1156
|
1166
|
break;
|
|
1167
|
+
|
|
1168
|
+ case kEnableAoId:
|
|
1169
|
+ cmDspSetEvent(ctx,inst,evt);
|
|
1170
|
+ break;
|
|
1171
|
+
|
1157
|
1172
|
}
|
1158
|
1173
|
return rc;
|
1159
|
1174
|
}
|
|
@@ -2907,6 +2922,7 @@ enum
|
2907
|
2922
|
kLoopWtId,
|
2908
|
2923
|
kBegWtId,
|
2909
|
2924
|
kEndWtId,
|
|
2925
|
+ kChWtId,
|
2910
|
2926
|
kCmdWtId,
|
2911
|
2927
|
kOtWtId,
|
2912
|
2928
|
kGainWtId,
|
|
@@ -2951,6 +2967,7 @@ typedef struct
|
2951
|
2967
|
cmAudioFileH_t afH; // current audio file handle
|
2952
|
2968
|
int nxtBegSmpIdx; // the beg/end sample index to use with the next filename to arrive at port 'fn'
|
2953
|
2969
|
int nxtEndSmpIdx; //
|
|
2970
|
+ unsigned nxtChIdx;
|
2954
|
2971
|
cmThreadH_t thH;
|
2955
|
2972
|
bool loadFileFl;
|
2956
|
2973
|
cmDspCtx_t* ctx;
|
|
@@ -2976,6 +2993,7 @@ cmDspInst_t* _cmDspWaveTableAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsi
|
2976
|
2993
|
{ "loop", kLoopWtId, 0, 0, kInDsvFl | kIntDsvFl | kOptArgDsvFl, "-1=loop forever >0=loop count (dflt:-1)"},
|
2977
|
2994
|
{ "beg", kBegWtId, 0, 0, kInDsvFl | kIntDsvFl | kOptArgDsvFl, "File begin sample index" },
|
2978
|
2995
|
{ "end", kEndWtId, 0, 0, kInDsvFl | kIntDsvFl | kOptArgDsvFl, "File end sample index (-1=play all)" },
|
|
2996
|
+ { "ch", kChWtId, 0, 0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "File channel index 0=left, 1=right" },
|
2979
|
2997
|
{ "cmd", kCmdWtId, 0, 0, kInDsvFl | kSymDsvFl | kOptArgDsvFl, "Command: on off"},
|
2980
|
2998
|
{ "ot", kOtWtId, 0, 0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "Overtone count"},
|
2981
|
2999
|
{ "gain", kGainWtId, 0, 0, kInDsvFl | kDoubleDsvFl|kOptArgDsvFl, "Gain"},
|
|
@@ -3005,6 +3023,7 @@ cmDspInst_t* _cmDspWaveTableAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsi
|
3005
|
3023
|
cmDspSetDefaultInt( ctx, &p->inst, kLoopWtId, 0, -1 );
|
3006
|
3024
|
cmDspSetDefaultInt( ctx, &p->inst, kBegWtId, 0, 0 );
|
3007
|
3025
|
cmDspSetDefaultInt( ctx, &p->inst, kEndWtId, 0, -1 );
|
|
3026
|
+ cmDspSetDefaultUInt( ctx, &p->inst, kChWtId, 0, 0 );
|
3008
|
3027
|
cmDspSetDefaultSymbol(ctx, &p->inst, kCmdWtId, p->onSymId );
|
3009
|
3028
|
cmDspSetDefaultUInt( ctx, &p->inst, kOtWtId, 0, 5 );
|
3010
|
3029
|
cmDspSetDefaultDouble(ctx, &p->inst, kGainWtId, 0, 1.0 );
|
|
@@ -3038,10 +3057,9 @@ cmDspRC_t _cmDspWaveTableFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
|
3038
|
3057
|
// mode then the the function will automatically begin reading from the begining of the
|
3039
|
3058
|
// file segment. If the end of the file segment is encountered and the wave table is not
|
3040
|
3059
|
// in loop mode then the empty portion of wt[] will be set to zero.
|
3041
|
|
-cmDspRC_t _cmDspWaveTableReadBlock( cmDspCtx_t* ctx, cmDspWaveTable_t* p, cmSample_t* wt, unsigned rdSmpCnt, int begSmpIdx, int endSmpIdx, int maxLoopCnt )
|
|
3060
|
+cmDspRC_t _cmDspWaveTableReadBlock( cmDspCtx_t* ctx, cmDspWaveTable_t* p, cmSample_t* wt, unsigned rdSmpCnt, unsigned chIdx, int begSmpIdx, int endSmpIdx, int maxLoopCnt )
|
3042
|
3061
|
{
|
3043
|
3062
|
unsigned actFrmCnt = 0;
|
3044
|
|
- unsigned chIdx = 0;
|
3045
|
3063
|
unsigned chCnt = 1;
|
3046
|
3064
|
unsigned fn = endSmpIdx - p->fi + 1; // count of samples between p->fi and endSmpIdx
|
3047
|
3065
|
unsigned n0 = rdSmpCnt;
|
|
@@ -3117,9 +3135,10 @@ cmDspRC_t _cmDspWaveTableReadAudioFile( cmDspCtx_t* ctx, cmDspWaveTable_t* p, un
|
3117
|
3135
|
{
|
3118
|
3136
|
unsigned n0 = rdSmpCnt;
|
3119
|
3137
|
unsigned n1 = 0;
|
3120
|
|
- int begSmpIdx = cmDspInt(&p->inst,kBegWtId);
|
3121
|
|
- int endSmpIdx = cmDspInt(&p->inst,kEndWtId);
|
3122
|
|
- int maxLoopCnt= cmDspInt(&p->inst,kLoopWtId);
|
|
3138
|
+ int begSmpIdx = cmDspInt( &p->inst,kBegWtId);
|
|
3139
|
+ int endSmpIdx = cmDspInt( &p->inst,kEndWtId);
|
|
3140
|
+ unsigned chIdx = cmDspUInt(&p->inst,kChWtId);
|
|
3141
|
+ int maxLoopCnt= cmDspInt( &p->inst,kLoopWtId);
|
3123
|
3142
|
|
3124
|
3143
|
if( endSmpIdx < begSmpIdx )
|
3125
|
3144
|
endSmpIdx = p->fn-1;
|
|
@@ -3137,7 +3156,7 @@ cmDspRC_t _cmDspWaveTableReadAudioFile( cmDspCtx_t* ctx, cmDspWaveTable_t* p, un
|
3137
|
3156
|
if( p->doneFl )
|
3138
|
3157
|
cmVOS_Zero(p->wt + p->wti,n0);
|
3139
|
3158
|
else
|
3140
|
|
- if( _cmDspWaveTableReadBlock(ctx, p, p->wt+p->wti, n0,begSmpIdx,endSmpIdx,maxLoopCnt ) != kOkDspRC )
|
|
3159
|
+ if( _cmDspWaveTableReadBlock(ctx, p, p->wt+p->wti, n0, chIdx, begSmpIdx,endSmpIdx,maxLoopCnt ) != kOkDspRC )
|
3141
|
3160
|
return cmDspInstErr(ctx,&p->inst,kVarNotValidDspRC,"An error occured while reading the wave table file.");
|
3142
|
3161
|
|
3143
|
3162
|
p->wtn -= n0; // decrease the count of available samples
|
|
@@ -3149,7 +3168,7 @@ cmDspRC_t _cmDspWaveTableReadAudioFile( cmDspCtx_t* ctx, cmDspWaveTable_t* p, un
|
3149
|
3168
|
if( p->doneFl )
|
3150
|
3169
|
cmVOS_Zero(p->wt,n1);
|
3151
|
3170
|
else
|
3152
|
|
- if( _cmDspWaveTableReadBlock(ctx, p, p->wt, n1,begSmpIdx,endSmpIdx,maxLoopCnt ) != kOkDspRC )
|
|
3171
|
+ if( _cmDspWaveTableReadBlock(ctx, p, p->wt, n1, chIdx, begSmpIdx,endSmpIdx,maxLoopCnt ) != kOkDspRC )
|
3153
|
3172
|
return cmDspInstErr(ctx,&p->inst,kVarNotValidDspRC,"An error occured while reading the wave table file.");
|
3154
|
3173
|
|
3155
|
3174
|
p->wtn -= n1; // decrease the count of available samples
|
|
@@ -3382,6 +3401,7 @@ cmDspRC_t _cmDspWaveTableReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv
|
3382
|
3401
|
|
3383
|
3402
|
p->nxtBegSmpIdx = cmDspInt(&p->inst,kBegWtId);
|
3384
|
3403
|
p->nxtEndSmpIdx = cmDspInt(&p->inst,kEndWtId);
|
|
3404
|
+ p->nxtChIdx = cmDspUInt(&p->inst,kChWtId);
|
3385
|
3405
|
|
3386
|
3406
|
return _cmDspWaveTableCreateTable(ctx,p);
|
3387
|
3407
|
|
|
@@ -3490,6 +3510,7 @@ cmDspRC_t _cmDspWaveTableRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
|
3490
|
3510
|
cmDspSetEvent(ctx,inst,evt); // set the file name variable
|
3491
|
3511
|
cmDspSetInt(ctx,inst,kBegWtId,p->nxtBegSmpIdx); // set the beg/end smp idx var's from the stored nxtBeg/EndSmpIdx values
|
3492
|
3512
|
cmDspSetInt(ctx,inst,kEndWtId,p->nxtEndSmpIdx); //
|
|
3513
|
+ cmDspSetUInt(ctx,inst,kChWtId, p->nxtChIdx); //
|
3493
|
3514
|
cmDspSetUInt(ctx,inst,kShapeWtId,kFileWtId); // switch to file mode
|
3494
|
3515
|
rc = _cmDspWaveTableCreateTable(ctx,p); // reload the wavetable
|
3495
|
3516
|
}
|
|
@@ -3506,6 +3527,11 @@ cmDspRC_t _cmDspWaveTableRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
|
3506
|
3527
|
p->nxtEndSmpIdx = cmDsvGetInt(evt->valuePtr);
|
3507
|
3528
|
break;
|
3508
|
3529
|
|
|
3530
|
+ case kChWtId:
|
|
3531
|
+ // store for next incoming file name msg
|
|
3532
|
+ p->nxtChIdx = cmDsvGetUInt(evt->valuePtr);
|
|
3533
|
+ break;
|
|
3534
|
+
|
3509
|
3535
|
case kShapeWtId:
|
3510
|
3536
|
if( cmDsvGetUInt(evt->valuePtr) < kShapeWtCnt )
|
3511
|
3537
|
{
|
|
@@ -5546,6 +5572,7 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
|
5546
|
5572
|
cm1UpClassCons,
|
5547
|
5573
|
cmGateToSymClassCons,
|
5548
|
5574
|
cmPortToSymClassCons,
|
|
5575
|
+ cmIntToSymClassCons,
|
5549
|
5576
|
cmRouterClassCons,
|
5550
|
5577
|
cmAvailChClassCons,
|
5551
|
5578
|
|