|
@@ -51,6 +51,9 @@ typedef struct
|
51
|
51
|
kRtCmdId_t cmdId; // written by app thread, read by rt thread
|
52
|
52
|
unsigned cbEnableFl; // written by rt thread, read by app thread
|
53
|
53
|
|
|
54
|
+ bool noBlockEnaFl; //
|
|
55
|
+ unsigned noBlockSleepMs;
|
|
56
|
+
|
54
|
57
|
double* iMeterArray; //
|
55
|
58
|
double* oMeterArray; //
|
56
|
59
|
|
|
@@ -295,8 +298,9 @@ void _cmRtDspExecCallback( _cmRtCfg_t* cp )
|
295
|
298
|
// 1) Buffers associated with disabled input/output channels will be set to NULL in iChArray[]/oChArray[].
|
296
|
299
|
// 2) Buffers associated with channels marked for pass-through will be set to NULL in oChArray[].
|
297
|
300
|
// 3) All samples returned in oChArray[] buffers will be set to zero.
|
298
|
|
- cmApBufGetIO(cp->ss.args.inDevIdx, cp->ctx.iChArray, cp->ctx.iChCnt, &cp->ctx.iTimeStamp,
|
299
|
|
- cp->ss.args.outDevIdx, cp->ctx.oChArray, cp->ctx.oChCnt, &cp->ctx.oTimeStamp );
|
|
301
|
+ if( cp->noBlockEnaFl == false )
|
|
302
|
+ cmApBufGetIO(cp->ss.args.inDevIdx, cp->ctx.iChArray, cp->ctx.iChCnt, &cp->ctx.iTimeStamp,
|
|
303
|
+ cp->ss.args.outDevIdx, cp->ctx.oChArray, cp->ctx.oChCnt, &cp->ctx.oTimeStamp );
|
300
|
304
|
|
301
|
305
|
|
302
|
306
|
// calling this function results in callbacks to _cmRtSysNetRecv()
|
|
@@ -344,8 +348,11 @@ void _cmRtDspExecCallback( _cmRtCfg_t* cp )
|
344
|
348
|
}
|
345
|
349
|
|
346
|
350
|
// advance the audio buffer
|
347
|
|
- cmApBufAdvance( cp->ss.args.outDevIdx, kOutApFl );
|
348
|
|
- cmApBufAdvance( cp->ss.args.inDevIdx, kInApFl );
|
|
351
|
+ if( cp->noBlockEnaFl == false )
|
|
352
|
+ {
|
|
353
|
+ cmApBufAdvance( cp->ss.args.outDevIdx, kOutApFl );
|
|
354
|
+ cmApBufAdvance( cp->ss.args.inDevIdx, kInApFl );
|
|
355
|
+ }
|
349
|
356
|
|
350
|
357
|
// handle periodic status messages to the host
|
351
|
358
|
if( (cp->statusUpdateSmpIdx += cp->ss.args.dspFramesPerCycle) >= cp->statusUpdateSmpCnt )
|
|
@@ -390,6 +397,7 @@ bool _cmRtThreadCallback(void* arg)
|
390
|
397
|
{
|
391
|
398
|
cmRtRC_t rc;
|
392
|
399
|
_cmRtCfg_t* cp = (_cmRtCfg_t*)arg;
|
|
400
|
+ bool noBlockFl = false;
|
393
|
401
|
|
394
|
402
|
// lock the cmRtSys mutex
|
395
|
403
|
if((rc = cmThreadMutexLock(cp->engMutexH)) != kOkRtRC )
|
|
@@ -401,16 +409,22 @@ bool _cmRtThreadCallback(void* arg)
|
401
|
409
|
// runFl is always set except during finalization
|
402
|
410
|
while( cp->runFl )
|
403
|
411
|
{
|
|
412
|
+
|
404
|
413
|
|
405
|
414
|
// if the buffer is NOT ready or the cmRtSys is disabled
|
406
|
415
|
if(_cmRtBufIsReady(cp) == false || cp->cbEnableFl==false )
|
407
|
416
|
{
|
408
|
417
|
// block on the cond var and unlock the mutex
|
409
|
|
- if( cmThreadMutexWaitOnCondVar(cp->engMutexH,false) != kOkRtRC )
|
|
418
|
+ if( noBlockFl )
|
|
419
|
+ cmSleepMs(cp->noBlockSleepMs);
|
|
420
|
+ else
|
410
|
421
|
{
|
411
|
|
- cmThreadMutexUnlock(cp->engMutexH);
|
412
|
|
- _cmRtError(cp->p,rc,"The cmRtSys cond. var. wait failed.");
|
413
|
|
- return false;
|
|
422
|
+ if( cmThreadMutexWaitOnCondVar(cp->engMutexH,false) != kOkRtRC )
|
|
423
|
+ {
|
|
424
|
+ cmThreadMutexUnlock(cp->engMutexH);
|
|
425
|
+ _cmRtError(cp->p,rc,"The cmRtSys cond. var. wait failed.");
|
|
426
|
+ return false;
|
|
427
|
+ }
|
414
|
428
|
}
|
415
|
429
|
|
416
|
430
|
//
|
|
@@ -418,13 +432,14 @@ bool _cmRtThreadCallback(void* arg)
|
418
|
432
|
//
|
419
|
433
|
++cp->status.wakeupCnt;
|
420
|
434
|
}
|
|
435
|
+
|
|
436
|
+ noBlockFl = cp->noBlockEnaFl;
|
421
|
437
|
|
422
|
438
|
// be sure we are still enabled and the buffer is still ready
|
423
|
439
|
while( cp->runFl && _cmRtBufIsReady(cp) )
|
424
|
440
|
{
|
425
|
441
|
++cp->status.audioCbCnt;
|
426
|
442
|
|
427
|
|
-
|
428
|
443
|
// make the cmRtSys callback
|
429
|
444
|
_cmRtDspExecCallback( cp );
|
430
|
445
|
|
|
@@ -495,7 +510,6 @@ void _cmRtSysAudioUpdate( cmApAudioPacket_t* inPktArray, unsigned inPktCnt, cm
|
495
|
510
|
|
496
|
511
|
// transfer incoming/outgoing samples from/to the audio device
|
497
|
512
|
cmApBufUpdate(inPktArray,inPktCnt,outPktArray,outPktCnt);
|
498
|
|
-
|
499
|
513
|
|
500
|
514
|
// generate a test signal
|
501
|
515
|
//_cmRtGenSignal( cmApAudioPacket_t* outPktArray, unsigned outPktCnt, bool sineFl );
|
|
@@ -513,6 +527,17 @@ void _cmRtSysAudioUpdate( cmApAudioPacket_t* inPktArray, unsigned inPktCnt, cm
|
513
|
527
|
_cmRtError(cp->p,kMutexErrRtRC,"CmRtSys signal cond. var. failed.");
|
514
|
528
|
|
515
|
529
|
}
|
|
530
|
+
|
|
531
|
+ if( cp->noBlockEnaFl )
|
|
532
|
+ {
|
|
533
|
+ cmApBufGetIO(cp->ss.args.inDevIdx, cp->ctx.iChArray, cp->ctx.iChCnt, &cp->ctx.iTimeStamp,
|
|
534
|
+ cp->ss.args.outDevIdx, cp->ctx.oChArray, cp->ctx.oChCnt, &cp->ctx.oTimeStamp );
|
|
535
|
+
|
|
536
|
+ cmApBufAdvance( cp->ss.args.outDevIdx, kOutApFl );
|
|
537
|
+ cmApBufAdvance( cp->ss.args.inDevIdx, kInApFl );
|
|
538
|
+
|
|
539
|
+ }
|
|
540
|
+
|
516
|
541
|
}
|
517
|
542
|
|
518
|
543
|
}
|
|
@@ -895,14 +920,14 @@ cmRtRC_t cmRtSysCfg( cmRtSysH_t h, const cmRtSysSubSys_t* ss, unsigned rtSubIdx
|
895
|
920
|
cp->syncInputFl = true;
|
896
|
921
|
|
897
|
922
|
// setup the status record
|
898
|
|
- cp->status.hdr.rtSubIdx = cp->ctx.rtSubIdx;
|
899
|
|
- cp->status.iDevIdx = ss->args.inDevIdx;
|
900
|
|
- cp->status.oDevIdx = ss->args.outDevIdx;
|
901
|
|
- cp->status.iMeterCnt = cp->ctx.iChCnt;
|
902
|
|
- cp->status.oMeterCnt = cp->ctx.oChCnt;
|
903
|
|
- cp->iMeterArray = cmMemAllocZ( double, cp->status.iMeterCnt );
|
904
|
|
- cp->oMeterArray = cmMemAllocZ( double, cp->status.oMeterCnt );
|
905
|
|
- //cp->udpH = cfg->udpH;
|
|
923
|
+ cp->status.hdr.rtSubIdx = cp->ctx.rtSubIdx;
|
|
924
|
+ cp->status.iDevIdx = ss->args.inDevIdx;
|
|
925
|
+ cp->status.oDevIdx = ss->args.outDevIdx;
|
|
926
|
+ cp->status.iMeterCnt = cp->ctx.iChCnt;
|
|
927
|
+ cp->status.oMeterCnt = cp->ctx.oChCnt;
|
|
928
|
+ cp->iMeterArray = cmMemAllocZ( double, cp->status.iMeterCnt );
|
|
929
|
+ cp->oMeterArray = cmMemAllocZ( double, cp->status.oMeterCnt );
|
|
930
|
+ cp->noBlockEnaFl = false;
|
906
|
931
|
|
907
|
932
|
// create the real-time system thread
|
908
|
933
|
if((rc = cmThreadCreate( &cp->threadH, _cmRtThreadCallback, cp, ss->args.rpt )) != kOkThRC )
|
|
@@ -1237,6 +1262,25 @@ cmRtSysCtx_t* cmRtSysContext( cmRtSysH_t h, unsigned rtSubIdx )
|
1237
|
1262
|
return &p->ssArray[rtSubIdx].ctx;
|
1238
|
1263
|
}
|
1239
|
1264
|
|
|
1265
|
+cmRtRC_t cmRtSysEnableNoBlockMode( cmRtSysH_t h, unsigned rtSubIdx, bool enaFl, unsigned noBlockSleepMs )
|
|
1266
|
+{
|
|
1267
|
+ cmRt_t* p = _cmRtHandleToPtr(h);
|
|
1268
|
+ cmRtRC_t rc = kOkRtRC;
|
|
1269
|
+
|
|
1270
|
+ if((rc = _cmRtSysVerifyInit(p,true)) != kOkRtRC )
|
|
1271
|
+ return rc;
|
|
1272
|
+
|
|
1273
|
+ if( rtSubIdx >= p->ssCnt )
|
|
1274
|
+ return cmErrMsg(&p->err,kInvalidArgRtRC,"Invalid 'rtSubIdx'. Enable non-block mode failed.");
|
|
1275
|
+
|
|
1276
|
+
|
|
1277
|
+ p->ssArray[rtSubIdx].noBlockSleepMs = noBlockSleepMs;
|
|
1278
|
+ p->ssArray[rtSubIdx].noBlockEnaFl = enaFl;
|
|
1279
|
+
|
|
1280
|
+ return kOkRtRC;
|
|
1281
|
+}
|
|
1282
|
+
|
|
1283
|
+
|
1240
|
1284
|
unsigned cmRtSysSubSystemCount( cmRtSysH_t h )
|
1241
|
1285
|
{
|
1242
|
1286
|
cmRt_t* p = _cmRtHandleToPtr(h);
|