Browse Source

cmRtSys.h : Added 'no-block-mode' to run a program independent of the audio

clock. Added cmRtSysEnableNoBlockMode().
master
kpl_harpo 10 years ago
parent
commit
9f422e58e8
2 changed files with 66 additions and 18 deletions
  1. 62
    18
      cmRtSys.c
  2. 4
    0
      cmRtSys.h

+ 62
- 18
cmRtSys.c View File

@@ -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);

+ 4
- 0
cmRtSys.h View File

@@ -313,6 +313,10 @@ extern "C" {
313 313
   // Return a pointer the context record associated with a sub-system
314 314
   cmRtSysCtx_t* cmRtSysContext( cmRtSysH_t h, unsigned rtSubIdx );
315 315
 
316
+  // Enable non-block mode. In this mode audio I/O is disabled 
317
+  // and the DSP callback is made every noBlockSleepMs milliseconds.
318
+  cmRtRC_t cmRtSysEnableNoBlockMode( cmRtSysH_t h, unsigned rtSubIdx, bool enaFl, unsigned noBlockSleepMs );
319
+
316 320
   // Return the count of audio sub-systems.
317 321
   // This is the same as the count of cfg recds passed to cmRtSystemInitialize().
318 322
   unsigned cmRtSysSubSystemCount( cmRtSysH_t h );

Loading…
Cancel
Save