|
@@ -1298,47 +1298,44 @@ cmDspRC_t _cmDspAudioFileOutReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDs
|
1298
|
1298
|
return rc;
|
1299
|
1299
|
}
|
1300
|
1300
|
|
1301
|
|
-
|
1302
|
1301
|
cmDspRC_t _cmDspAudioFileOutExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
1303
|
1302
|
{
|
1304
|
1303
|
cmDspRC_t rc = kOkDspRC;
|
1305
|
1304
|
cmDspAudioFileOut_t* p = (cmDspAudioFileOut_t*)inst;;
|
1306
|
|
- unsigned fpc = cmDspSamplesPerCycle(ctx);
|
1307
|
|
- unsigned chCnt = cmDspUInt(inst,kChCntAofId);
|
|
1305
|
+ unsigned chCnt = cmMin(2,cmDspUInt(inst,kChCntAofId));
|
|
1306
|
+ unsigned smpCnt = 0;
|
1308
|
1307
|
cmSample_t* chArray[chCnt];
|
1309
|
|
- unsigned i;
|
1310
|
|
-
|
1311
|
|
- // Assume that both channls have the same number of samples.
|
1312
|
|
- // (cmAudioWriteFile() has the same constraint )
|
1313
|
|
- int sn = cmDspAudioBufSmpCount(ctx,inst,kIn0AofId,0);
|
1314
|
|
-
|
1315
|
|
- // This code can handle the case where the input channels contain
|
1316
|
|
- // more than or less than cmDspSamplesPerCycle().
|
|
1308
|
+ unsigned i,j;
|
1317
|
1309
|
|
1318
|
|
- while(sn>0)
|
|
1310
|
+ for(i=0,j=0; i<chCnt; ++i)
|
1319
|
1311
|
{
|
1320
|
|
- // we can process at most 'fpc' samples on one iteration
|
1321
|
|
- unsigned n = cmMin(sn,fpc);
|
1322
|
|
- sn -= n;
|
|
1312
|
+ unsigned chVarId = i == 0 ? kIn0AofId : kIn1AofId; // get audio buf var id for this ch
|
|
1313
|
+ unsigned iSmpCnt = cmDspVarRows(inst,chVarId);
|
1323
|
1314
|
|
1324
|
|
- // apply output gain
|
1325
|
|
- for(i=0; i<chCnt; ++i)
|
|
1315
|
+ if( iSmpCnt == 0 )
|
|
1316
|
+ {
|
|
1317
|
+ chArray[j] = NULL;
|
|
1318
|
+ }
|
|
1319
|
+ else
|
1326
|
1320
|
{
|
1327
|
|
- chArray[i] = p->smpBuf + i*fpc;
|
1328
|
|
- const cmSample_t* sp = i==0 ? cmDspAudioBuf(ctx,inst,kIn0AofId,0) : cmDspAudioBuf(ctx,inst,kIn1AofId,0);
|
1329
|
|
- cmSample_t gain = i==0 ? cmDspDouble(inst,kGain0AofId) : cmDspDouble(inst,kGain1AofId);
|
|
1321
|
+ cmSample_t gain = cmDspSample(inst,i==0?kGain0AofId:kGain1AofId); // get ch gain
|
|
1322
|
+
|
|
1323
|
+ chArray[j] = cmDspAudioBuf(ctx,inst,chVarId,i); // get incoming audio buf ptr
|
1330
|
1324
|
|
1331
|
|
- cmVOS_MultVVS(chArray[i], n, sp, (cmSample_t)gain);
|
|
1325
|
+ if( gain != 1.0 )
|
|
1326
|
+ cmVOS_MultVVS(chArray[j], iSmpCnt, chArray[j], gain); // apply gain
|
1332
|
1327
|
|
|
1328
|
+ ++j; // incr chArray[] index
|
|
1329
|
+ assert( smpCnt==0 || iSmpCnt==smpCnt);
|
|
1330
|
+ smpCnt = iSmpCnt; // set outgoing sample count
|
1333
|
1331
|
}
|
1334
|
1332
|
|
1335
|
|
- // write the samples
|
1336
|
|
- if( cmAudioFileWriteSample(p->afH, n, chCnt, chArray ) != kOkAfRC )
|
1337
|
|
- rc = cmDspClassErr(ctx,inst->classPtr,kFileWriteFailDspRC,"An audio output file write failed.");
|
1338
|
|
-
|
1339
|
|
-
|
1340
|
1333
|
}
|
1341
|
1334
|
|
|
1335
|
+ // write the samples
|
|
1336
|
+ if( cmAudioFileWriteSample(p->afH, smpCnt, j, chArray ) != kOkAfRC )
|
|
1337
|
+ rc = cmDspClassErr(ctx,inst->classPtr,kFileWriteFailDspRC,"An audio output file write failed.");
|
|
1338
|
+
|
1342
|
1339
|
return rc;
|
1343
|
1340
|
}
|
1344
|
1341
|
|
|
@@ -5020,6 +5017,8 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
|
5020
|
5017
|
cmMidiFilePlayClassCons,
|
5021
|
5018
|
cmScFolClassCons,
|
5022
|
5019
|
cmScModClassCons,
|
|
5020
|
+ cmGSwitchClassCons,
|
|
5021
|
+
|
5023
|
5022
|
NULL,
|
5024
|
5023
|
};
|
5025
|
5024
|
|