Browse Source

cmProc4.h/c, cmDspKr.c : Added look-ahead buffer to cmRecdPlay object.

master
kevin 10 years ago
parent
commit
57d2a86a42
3 changed files with 133 additions and 11 deletions
  1. 113
    7
      cmProc4.c
  2. 6
    2
      cmProc4.h
  3. 14
    2
      dsp/cmDspKr.c

+ 113
- 7
cmProc4.c View File

@@ -4134,11 +4134,11 @@ cmRC_t  cmScModulatorDump(  cmScModulator* p )
4134 4134
 }
4135 4135
 
4136 4136
 //=======================================================================================================================
4137
-cmRecdPlay*    cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs  )
4137
+cmRecdPlay*    cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs  )
4138 4138
 {
4139 4139
   cmRecdPlay* op = cmObjAlloc(cmRecdPlay,c,p);
4140 4140
 
4141
-  if( cmRecdPlayInit(op,srate,fragCnt,chCnt,initFragSecs) != cmOkRC )
4141
+  if( cmRecdPlayInit(op,srate,fragCnt,chCnt,initFragSecs,maxLaSecs,curLaSecs) != cmOkRC )
4142 4142
     cmRecdPlayFree(&op);
4143 4143
 
4144 4144
   return op;
@@ -4159,26 +4159,40 @@ cmRC_t         cmRecdPlayFree(  cmRecdPlay** pp )
4159 4159
 
4160 4160
 }
4161 4161
 
4162
-cmRC_t         cmRecdPlayInit(  cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs  )
4162
+cmRC_t cmRecdPlayInit(  cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs  )
4163 4163
 {
4164
-  
4165 4164
   cmRC_t rc;
4165
+  unsigned i;
4166
+
4167
+  if( curLaSecs > maxLaSecs )
4168
+    return  cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The initial look-ahead time %f is greater than the maximum look-ahead time %f.",curLaSecs,maxLaSecs);    
4166 4169
 
4167 4170
   if((rc = cmRecdPlayFinal(p)) != cmOkRC )
4168 4171
     return rc;
4169 4172
 
4173
+  if( chCnt == 0 )
4174
+    return cmOkRC;
4175
+
4170 4176
   p->frags        = cmMemAllocZ(cmRecdPlayFrag,fragCnt);
4171 4177
   p->fragCnt      = fragCnt;
4172 4178
   p->srate        = srate;
4173 4179
   p->chCnt        = chCnt;
4174 4180
   p->initFragSecs = initFragSecs;
4181
+  p->maxLaSmpCnt  = floor(maxLaSecs*srate);
4182
+  p->curLaSmpCnt  = floor(curLaSecs*srate); 
4183
+  p->laChs        = cmMemAllocZ(cmSample_t*,chCnt);
4184
+  p->laSmpIdx     = 0;
4175 4185
 
4186
+  for(i=0; i<chCnt; ++i)
4187
+    p->laChs[i] = cmMemAllocZ(cmSample_t,p->maxLaSmpCnt);
4188
+  
4176 4189
   return rc;
4177 4190
 }
4178 4191
 
4179 4192
 cmRC_t         cmRecdPlayFinal( cmRecdPlay* p )
4180 4193
 { 
4181 4194
   unsigned i,j;
4195
+  // free the fragments
4182 4196
   for(i=0; i<p->fragCnt; ++i)
4183 4197
   {
4184 4198
     for(j=0; j<p->chCnt; ++j)
@@ -4186,9 +4200,17 @@ cmRC_t         cmRecdPlayFinal( cmRecdPlay* p )
4186 4200
 
4187 4201
     cmMemFree(p->frags[i].chArray);
4188 4202
   }
4189
-  cmMemFree(p->frags);
4190
-  p->fragCnt=0;
4191
-  p->chCnt=0;
4203
+
4204
+  // free the look-ahead buffers
4205
+  for(i=0; i<p->chCnt; ++i)
4206
+    cmMemFree(p->laChs[i]);
4207
+
4208
+  cmMemPtrFree(&p->laChs);
4209
+  cmMemPtrFree(&p->frags);
4210
+  p->fragCnt = 0;
4211
+  p->chCnt   = 0;
4212
+  p->rlist   = NULL;
4213
+  p->plist   = NULL;
4192 4214
   return cmOkRC;
4193 4215
 }
4194 4216
 
@@ -4216,6 +4238,8 @@ cmRC_t         cmRecdPlayRewind( cmRecdPlay* p )
4216 4238
 {
4217 4239
   unsigned i;
4218 4240
 
4241
+  p->laSmpIdx = 0;
4242
+
4219 4243
   while( p->plist != NULL )
4220 4244
     cmRecdPlayEndPlay(p,p->plist->labelSymId);
4221 4245
   
@@ -4228,6 +4252,7 @@ cmRC_t         cmRecdPlayRewind( cmRecdPlay* p )
4228 4252
   return cmOkRC;
4229 4253
 }
4230 4254
 
4255
+
4231 4256
 cmRC_t         cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId )
4232 4257
 {
4233 4258
   unsigned i;
@@ -4242,6 +4267,39 @@ cmRC_t         cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId )
4242 4267
         p->frags[i].playIdx = 0;
4243 4268
         p->frags[i].rlink   = p->rlist;
4244 4269
         p->rlist            = p->frags + i;
4270
+
4271
+        // handle LA buf longer than frag buf.
4272
+        int cpyCnt  = cmMin(p->curLaSmpCnt,p->frags[i].allocCnt); 
4273
+
4274
+         // go backwards in LA buf from newest sample to find init src offset
4275
+        int srcOffs = p->laSmpIdx - cpyCnt;
4276
+
4277
+        // if the src is before the first sample in the LA buf then wrap to end of buf
4278
+        if( srcOffs < 0 )
4279
+          srcOffs += p->maxLaSmpCnt; 
4280
+
4281
+        assert( 0 <= srcOffs && srcOffs < p->maxLaSmpCnt );
4282
+
4283
+        // cnt of samples to copy from LA buf (limited by end of LA buf)
4284
+        int n0 = cmMin(cpyCnt,p->maxLaSmpCnt - srcOffs); 
4285
+
4286
+        // if necessary wrap to begin of LA buf for remaining samples
4287
+        int n1 = cpyCnt>n0 ? n1 = cpyCnt-n0 : 0;
4288
+        int j;
4289
+
4290
+        assert(n0+n1 == cpyCnt );
4291
+
4292
+        for(j=0; j<p->chCnt; ++j)
4293
+          cmVOS_Copy(p->frags[i].chArray[j],n0,p->laChs[j]+srcOffs);
4294
+
4295
+        if( n1 > 0 )
4296
+        {
4297
+          for(j=0; j<p->chCnt; ++j)
4298
+            cmVOS_Copy(p->frags[i].chArray[j]+n0,n1,p->laChs[j]);
4299
+        }
4300
+
4301
+        p->frags[i].recdIdx = cpyCnt;
4302
+
4245 4303
       }
4246 4304
       
4247 4305
       return cmOkRC;
@@ -4341,8 +4399,53 @@ cmRC_t cmRecdPlayBeginFade(   cmRecdPlay* p, unsigned labelSymId, double fadeDbP
4341 4399
 
4342 4400
 cmRC_t         cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt )
4343 4401
 {
4402
+  unsigned i;
4403
+
4344 4404
   chCnt = cmMin(chCnt, p->chCnt);
4345 4405
 
4406
+  //-------------------------------------------------------------------
4407
+  // copy incoming audio into the look-head buffers
4408
+  //
4409
+
4410
+  // if the number of incoming samples is longer than the look-head buffer
4411
+  // then copy exactly maxLaSmpCnt samples from the end of the incoming sample
4412
+  // buffer to the look-ahead buffer.
4413
+  unsigned srcOffs   = 0;
4414
+  unsigned srcSmpCnt = smpCnt;
4415
+  if( srcSmpCnt > p->maxLaSmpCnt )
4416
+  {
4417
+    // advance incoming sample buffer so that there are maxLaSmpCnt samples remaining
4418
+    srcOffs   = smpCnt-p->maxLaSmpCnt; 
4419
+    srcSmpCnt = p->maxLaSmpCnt;        // decrease the total samples to copy  
4420
+  }
4421
+
4422
+  // count of samples from cur posn to end of the LA buffer.
4423
+  unsigned          n0  = cmMin(srcSmpCnt, p->maxLaSmpCnt - p->laSmpIdx );
4424
+
4425
+  // count of samples past the end of the LA buffer to be wrapped into begin of buffer
4426
+  unsigned          n1  = srcSmpCnt>n0 ? srcSmpCnt-n0 : 0;
4427
+
4428
+  assert(n0+n1 == srcSmpCnt);
4429
+
4430
+  // copy first block to end of LA buffer
4431
+  for(i=0; i<chCnt; ++i)
4432
+    cmVOS_Copy(p->laChs[i]+p->laSmpIdx,n0,iChs[i] + srcOffs);
4433
+
4434
+  p->laSmpIdx += n0;
4435
+
4436
+  if( n1!=0)
4437
+  {
4438
+    // copy second block to begin of LA buffer
4439
+    for(i=0; i<chCnt; ++i)
4440
+      cmVOS_Copy(p->laChs[i],n1,iChs[i] + srcOffs + n0);
4441
+
4442
+    p->laSmpIdx = n1; 
4443
+
4444
+  }
4445
+
4446
+  //-------------------------------------------------------------------
4447
+  // copy incoming audio into the active record buffers
4448
+  //
4346 4449
   cmRecdPlayFrag* fp = p->rlist;
4347 4450
 
4348 4451
   for(; fp!=NULL; fp=fp->rlink)
@@ -4357,6 +4460,9 @@ cmRC_t         cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_
4357 4460
     }
4358 4461
   }  
4359 4462
 
4463
+  //-------------------------------------------------------------------
4464
+  // copy outgoing audio out of the active play buffers
4465
+  //
4360 4466
   fp = p->plist;
4361 4467
   for(; fp!=NULL; fp=fp->rlink)
4362 4468
   {

+ 6
- 2
cmProc4.h View File

@@ -649,14 +649,18 @@ extern "C" {
649 649
     double           srate;         // system sample rate
650 650
     unsigned         chCnt;         // count of input and output audio channels
651 651
     double           initFragSecs;  // size initial memory allocated to each frag in seconds
652
+    unsigned         maxLaSmpCnt;   // samples allocated to each channel of the look-ahead buffers.
653
+    unsigned         curLaSmpCnt;   // current look-ahead time in samples (curLaSmpCnt<=maxLaSmpCnt)
654
+    cmSample_t**     laChs;         // laChs[chCnt][maxLaSmpCnt] - look-ahead buffers
655
+    int              laSmpIdx;      // next look-ahead buffer index to receive a sample
652 656
     cmRecdPlayFrag*  plist;         // currently playing frags
653 657
     cmRecdPlayFrag*  rlist;         // currently recording frags
654 658
   } cmRecdPlay;
655 659
 
656 660
 
657
-  cmRecdPlay*    cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs  );
661
+  cmRecdPlay*    cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs  );
658 662
   cmRC_t         cmRecdPlayFree(  cmRecdPlay** pp );
659
-  cmRC_t         cmRecdPlayInit(  cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs  );
663
+  cmRC_t         cmRecdPlayInit(  cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs  );
660 664
   cmRC_t         cmRecdPlayFinal( cmRecdPlay* p );
661 665
 
662 666
   cmRC_t         cmRecdPlayRegisterFrag( cmRecdPlay* p, unsigned fragIdx, unsigned labelSymId );

+ 14
- 2
dsp/cmDspKr.c View File

@@ -2271,6 +2271,8 @@ enum
2271 2271
   kChCntPrId,
2272 2272
   kFnPrId,
2273 2273
   kSecsPrId,
2274
+  kMaxLaSecsPrId,
2275
+  kCurLaSecsPrId,
2274 2276
   kFadeRatePrId,
2275 2277
   kScLocIdxPrId,
2276 2278
   kCmdPrId,
@@ -2311,8 +2313,11 @@ cmDspRC_t _cmDspRecdPlayOpenScore( cmDspCtx_t* ctx, cmDspInst_t* inst )
2311 2313
   {
2312 2314
     unsigned i;
2313 2315
     unsigned markerCnt = cmScoreMarkerLabelCount(p->scH);
2316
+    double initFragSecs = cmDspDouble(inst,kSecsPrId);
2317
+    double maxLaSecs    = cmDspDouble(inst,kMaxLaSecsPrId);
2318
+    double curLaSecs    = cmDspDouble(inst,kCurLaSecsPrId);
2314 2319
 
2315
-    if((p->rcdply = cmRecdPlayAlloc(ctx->cmProcCtx, NULL, cmDspSampleRate(ctx), markerCnt, p->chCnt, cmDspDouble(inst,kSecsPrId))) == NULL)
2320
+    if((p->rcdply = cmRecdPlayAlloc(ctx->cmProcCtx, NULL, cmDspSampleRate(ctx), markerCnt, p->chCnt, initFragSecs, maxLaSecs, curLaSecs)) == NULL)
2316 2321
       return cmErrMsg(&inst->classPtr->err,kSubSysFailDspRC,"Unable to create the internal recorder-player object.");    
2317 2322
 
2318 2323
     for(i=0; i<markerCnt; ++i)
@@ -2343,6 +2348,8 @@ cmDspInst_t*  _cmDspRecdPlayAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsig
2343 2348
     1,         "chs",    kChCntPrId,      0,0, kUIntDsvFl | kReqArgDsvFl,              "channel count.",
2344 2349
     1,         "fn",     kFnPrId,         0,0, kInDsvFl   | kStrzDsvFl | kReqArgDsvFl, "Score file." ,
2345 2350
     1,         "secs",   kSecsPrId,       0,0, kInDsvFl   | kDoubleDsvFl | kReqArgDsvFl, "Initial fragment allocation in seconds.",
2351
+    1,         "maxla",  kMaxLaSecsPrId,  0,0, kInDsvFl   | kDoubleDsvFl,              "Maximum look-ahead buffer in seconds.",
2352
+    1,         "curla",  kCurLaSecsPrId,  0,0, kInDsvFl   | kDoubleDsvFl,              "Current look-head buffer in seconds.",
2346 2353
     1,         "frate",  kFadeRatePrId,   0,0, kInDsvFl   | kDoubleDsvFl,              "Fade rate in dB per second.",
2347 2354
     1,         "index",  kScLocIdxPrId,   0,0, kInDsvFl   | kUIntDsvFl,                "Score follower location index.",
2348 2355
     1,         "cmd",    kCmdPrId,        0,0, kInDsvFl   | kSymDsvFl,                 "on=reset off=stop.",
@@ -2359,6 +2366,8 @@ cmDspInst_t*  _cmDspRecdPlayAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsig
2359 2366
   p->scLocIdx       = 0;
2360 2367
 
2361 2368
   cmDspSetDefaultDouble(ctx,&p->inst, kSecsPrId,     0, 10.0 );
2369
+  cmDspSetDefaultDouble(ctx,&p->inst, kMaxLaSecsPrId,0, 2.0);
2370
+  cmDspSetDefaultDouble(ctx,&p->inst, kCurLaSecsPrId,0, 0.5);
2362 2371
   cmDspSetDefaultDouble(ctx,&p->inst, kFadeRatePrId, 0, 1.0);
2363 2372
 
2364 2373
   return &p->inst;
@@ -2446,6 +2455,9 @@ cmDspRC_t _cmDspRecdPlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
2446 2455
 
2447 2456
       break;
2448 2457
 
2458
+    case kCurLaSecsPrId:
2459
+      break;
2460
+
2449 2461
     case kScLocIdxPrId:
2450 2462
       {
2451 2463
         unsigned endScLocIdx = cmDspUInt(inst,kScLocIdxPrId) ;
@@ -2474,7 +2486,7 @@ cmDspRC_t _cmDspRecdPlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
2474 2486
                 break;
2475 2487
 
2476 2488
               case kPlayEndScMId:
2477
-                printf("recd-end\n");
2489
+                printf("play-end\n");
2478 2490
                 cmRecdPlayEndPlay(p->rcdply, mp->labelSymId );
2479 2491
                 break;
2480 2492
 

Loading…
Cancel
Save