Преглед на файлове

Added the cmRecdPlay proc object.

master
kpl преди 11 години
родител
ревизия
d64f92ac03
променени са 2 файла, в които са добавени 292 реда и са изтрити 0 реда
  1. 247
    0
      cmProc4.c
  2. 45
    0
      cmProc4.h

+ 247
- 0
cmProc4.c Целия файл

@@ -4132,3 +4132,250 @@ cmRC_t  cmScModulatorDump(  cmScModulator* p )
4132 4132
   
4133 4133
   return rc;
4134 4134
 }
4135
+
4136
+//=======================================================================================================================
4137
+cmRecdPlay*    cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs  )
4138
+{
4139
+  cmRecdPlay* op = cmObjAlloc(cmRecdPlay,c,p);
4140
+
4141
+  if( cmRecdPlayInit(op,srate,fragCnt,chCnt,initFragSecs) != cmOkRC )
4142
+    cmRecdPlayFree(&op);
4143
+
4144
+  return op;
4145
+}
4146
+
4147
+cmRC_t         cmRecdPlayFree(  cmRecdPlay** pp )
4148
+{
4149
+  cmRC_t rc = cmOkRC;
4150
+  if( pp==NULL || *pp==NULL )
4151
+    return rc;
4152
+
4153
+  cmRecdPlay* p = *pp;
4154
+  if((rc = cmRecdPlayFinal(p)) != cmOkRC )
4155
+    return rc;
4156
+
4157
+  cmObjFree(pp);
4158
+  return rc;
4159
+
4160
+}
4161
+
4162
+cmRC_t         cmRecdPlayInit(  cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs  )
4163
+{
4164
+  
4165
+  cmRC_t rc;
4166
+
4167
+  if((rc = cmRecdPlayFinal(p)) != cmOkRC )
4168
+    return rc;
4169
+
4170
+  p->frags        = cmMemAllocZ(cmRecdPlayFrag,fragCnt);
4171
+  p->fragCnt      = fragCnt;
4172
+  p->srate        = srate;
4173
+  p->chCnt        = chCnt;
4174
+  p->initFragSecs = initFragSecs;
4175
+
4176
+  return rc;
4177
+}
4178
+
4179
+cmRC_t         cmRecdPlayFinal( cmRecdPlay* p )
4180
+{ 
4181
+  unsigned i,j;
4182
+  for(i=0; i<p->fragCnt; ++i)
4183
+  {
4184
+    for(j=0; j<p->chCnt; ++j)
4185
+      cmMemFree(p->frags[i].chArray[j]);
4186
+
4187
+    cmMemFree(p->frags[i].chArray);
4188
+  }
4189
+  cmMemFree(p->frags);
4190
+  p->fragCnt=0;
4191
+  p->chCnt=0;
4192
+  return cmOkRC;
4193
+}
4194
+
4195
+cmRC_t         cmRecdPlayRegisterFrag( cmRecdPlay* p,  unsigned fragIdx, unsigned labelSymId )
4196
+{
4197
+  assert( fragIdx < p->fragCnt );
4198
+
4199
+  unsigned i;
4200
+
4201
+  p->frags[ fragIdx ].labelSymId = labelSymId;
4202
+
4203
+  p->frags[ fragIdx ].chArray = cmMemResizeZ(cmSample_t*,p->frags[fragIdx].chArray,p->chCnt);
4204
+
4205
+  for(i=0; i<p->chCnt; ++i)
4206
+  {
4207
+    
4208
+    p->frags[ fragIdx ].allocCnt = floor(p->initFragSecs * p->srate);
4209
+    p->frags[ fragIdx ].chArray[i] = cmMemResizeZ(cmSample_t,p->frags[ fragIdx ].chArray[i],p->frags[fragIdx].allocCnt);
4210
+  }
4211
+
4212
+  return cmOkRC;
4213
+}
4214
+
4215
+cmRC_t         cmRecdPlayRewind( cmRecdPlay* p )
4216
+{
4217
+  unsigned i;
4218
+
4219
+  while( p->plist != NULL )
4220
+    cmRecdPlayEndPlay(p,p->plist->labelSymId);
4221
+  
4222
+  while( p->rlist != NULL )
4223
+    cmRecdPlayEndRecord(p,p->plist->labelSymId);
4224
+
4225
+  for(i=0; i<p->fragCnt; ++i)
4226
+    p->frags[i].playIdx = 0;
4227
+
4228
+  return cmOkRC;
4229
+}
4230
+
4231
+cmRC_t         cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId )
4232
+{
4233
+  unsigned i;
4234
+
4235
+  for(i=0; i<p->fragCnt; ++i)
4236
+    if( p->frags[i].labelSymId == labelSymId )
4237
+    {
4238
+      // if the frag is not already on the recd list
4239
+      if( p->frags[i].rlink == NULL )
4240
+      {
4241
+        p->frags[i].recdIdx = 0;
4242
+        p->frags[i].playIdx = 0;
4243
+        p->frags[i].rlink   = p->rlist;
4244
+        p->rlist            = p->frags + i;
4245
+      }
4246
+      
4247
+      return cmOkRC;
4248
+    }
4249
+
4250
+  return  cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'begin record'.",labelSymId);    
4251
+}
4252
+
4253
+cmRC_t         cmRecdPlayEndRecord(   cmRecdPlay* p, unsigned labelSymId )
4254
+{
4255
+  cmRecdPlayFrag* fp = p->rlist;
4256
+  cmRecdPlayFrag* pp = NULL;
4257
+
4258
+  for(; fp != NULL; fp=fp->rlink )
4259
+  {
4260
+    if( fp->labelSymId == labelSymId )
4261
+    {
4262
+      if( pp == NULL )
4263
+        p->rlist = fp->rlink;
4264
+      else
4265
+        pp->rlink = fp->rlink;
4266
+
4267
+      fp->rlink = NULL;
4268
+
4269
+      return cmOkRC;
4270
+    }
4271
+
4272
+    pp = fp;
4273
+  }
4274
+
4275
+  return  cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'end record'.",labelSymId);      
4276
+}
4277
+
4278
+cmRC_t         cmRecdPlayBeginPlay(   cmRecdPlay* p, unsigned labelSymId )
4279
+{
4280
+  unsigned i;
4281
+
4282
+  for(i=0; i<p->fragCnt; ++i)
4283
+    if( p->frags[i].labelSymId == labelSymId )
4284
+    {
4285
+      // if the frag is not already on the play list
4286
+      if( p->frags[i].plink == NULL )
4287
+      {
4288
+        p->frags[i].playIdx      = 0;
4289
+        p->frags[i].fadeSmpIdx   = 0;
4290
+        p->frags[i].fadeDbPerSec = 0.0;
4291
+        p->frags[i].plink        = p->plist;
4292
+        p->plist                 = p->frags + i;
4293
+      }
4294
+
4295
+      return cmOkRC;
4296
+    }
4297
+
4298
+  return  cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'begin play'.",labelSymId);    
4299
+
4300
+}
4301
+
4302
+cmRC_t         cmRecdPlayEndPlay(     cmRecdPlay* p, unsigned labelSymId )
4303
+{
4304
+  cmRecdPlayFrag* fp = p->plist;
4305
+  cmRecdPlayFrag* pp = NULL;
4306
+
4307
+  for(; fp != NULL; fp=fp->plink )
4308
+  {
4309
+    if( fp->labelSymId == labelSymId )
4310
+    {
4311
+      if( pp == NULL )
4312
+        p->plist = fp->plink;
4313
+      else
4314
+        pp->plink = fp->plink;
4315
+
4316
+      fp->plink = NULL;
4317
+
4318
+      return cmOkRC;
4319
+    }
4320
+
4321
+    pp = fp;
4322
+  }
4323
+
4324
+  return  cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'end play'.",labelSymId);    
4325
+}
4326
+
4327
+cmRC_t cmRecdPlayBeginFade(   cmRecdPlay* p, unsigned labelSymId, double fadeDbPerSec )
4328
+{
4329
+  cmRecdPlayFrag* fp = p->plist;
4330
+
4331
+  for(; fp != NULL; fp=fp->plink )
4332
+    if( fp->labelSymId == labelSymId )
4333
+    {
4334
+      fp->fadeDbPerSec = -fabs(fadeDbPerSec);
4335
+      return cmOkRC;
4336
+    }
4337
+  
4338
+  return  cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'fade begin'.",labelSymId);      
4339
+}
4340
+
4341
+
4342
+cmRC_t         cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt )
4343
+{
4344
+  chCnt = cmMin(chCnt, p->chCnt);
4345
+
4346
+  cmRecdPlayFrag* fp = p->rlist;
4347
+
4348
+  for(; fp!=NULL; fp=fp->rlink)
4349
+  {
4350
+    assert( fp->recdIdx <= fp->allocCnt);
4351
+    unsigned n = cmMin(fp->allocCnt - fp->recdIdx,smpCnt);
4352
+    unsigned i;
4353
+    for(i=0; i<p->chCnt; ++i)
4354
+    {
4355
+      cmVOS_Copy(fp->chArray[i] + fp->recdIdx, n, iChs[i] );
4356
+      fp->recdIdx += n;
4357
+    }
4358
+  }  
4359
+
4360
+  fp = p->plist;
4361
+  for(; fp!=NULL; fp=fp->rlink)
4362
+  {
4363
+    assert( fp->playIdx <= fp->recdIdx);
4364
+
4365
+    double   gain = pow(10.0,((fp->fadeSmpIdx / p->srate) * fp->fadeDbPerSec)/20.0);
4366
+    unsigned n    = cmMin(fp->recdIdx - fp->playIdx,smpCnt);
4367
+    unsigned i;
4368
+
4369
+    for(i=0; i<p->chCnt; ++i)
4370
+    {
4371
+      cmVOS_MultVVS(oChs[i],n,fp->chArray[i] + fp->playIdx,gain);
4372
+      fp->playIdx += n;
4373
+    }
4374
+
4375
+    // if a fade rate has been set then advance the fade phase
4376
+    if(fp->fadeDbPerSec!=0.0)
4377
+      fp->fadeSmpIdx += smpCnt;
4378
+  }  
4379
+
4380
+  return cmOkRC;
4381
+}

+ 45
- 0
cmProc4.h Целия файл

@@ -626,6 +626,51 @@ extern "C" {
626 626
   cmRC_t         cmScModulatorExec(  cmScModulator* p, unsigned scLocIdx );
627 627
   cmRC_t         cmScModulatorDump(  cmScModulator* p );
628 628
 
629
+  //=======================================================================================================================
630
+ 
631
+  typedef struct cmRecdPlayFrag_str
632
+  {
633
+    unsigned                   labelSymId; // this fragments label
634
+    cmSample_t**               chArray;    // record buffer chArray[cmRecdPlay.chCnt][allocCnt]
635
+    unsigned                   allocCnt;   // count of samples allocated to each channel
636
+    unsigned                   playIdx;    // index of next sample to play
637
+    unsigned                   recdIdx;    // index of next sample to receieve audio (count of full samples)
638
+    double                     fadeDbPerSec; // fade rate in dB per second
639
+    unsigned                   fadeSmpIdx; 
640
+    struct cmRecdPlayFrag_str* rlink;      // cmRecdPlay.rlist link
641
+    struct cmRecdPlayFrag_str* plink;      // cmRecdPlay.plist link
642
+  } cmRecdPlayFrag;
643
+
644
+  typedef struct
645
+  {
646
+    cmObj            obj;
647
+    cmRecdPlayFrag*  frags;         // frags[fragCnt] fragment array
648
+    unsigned         fragCnt;       // count of fragments 
649
+    double           srate;         // system sample rate
650
+    unsigned         chCnt;         // count of input and output audio channels
651
+    double           initFragSecs;  // size initial memory allocated to each frag in seconds
652
+    cmRecdPlayFrag*  plist;         // currently playing frags
653
+    cmRecdPlayFrag*  rlist;         // currently recording frags
654
+  } cmRecdPlay;
655
+
656
+
657
+  cmRecdPlay*    cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs  );
658
+  cmRC_t         cmRecdPlayFree(  cmRecdPlay** pp );
659
+  cmRC_t         cmRecdPlayInit(  cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs  );
660
+  cmRC_t         cmRecdPlayFinal( cmRecdPlay* p );
661
+
662
+  cmRC_t         cmRecdPlayRegisterFrag( cmRecdPlay* p, unsigned fragIdx, unsigned labelSymId );
663
+
664
+  cmRC_t         cmRecdPlayRewind(      cmRecdPlay* p );
665
+  cmRC_t         cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId );
666
+  cmRC_t         cmRecdPlayEndRecord(   cmRecdPlay* p, unsigned labelSymId );
667
+  cmRC_t         cmRecdPlayBeginPlay(   cmRecdPlay* p, unsigned labelSymId );
668
+  cmRC_t         cmRecdPlayEndPlay(     cmRecdPlay* p, unsigned labelSymId );
669
+
670
+  cmRC_t         cmRecdPlayBeginFade(   cmRecdPlay* p, unsigned labelSymId, double fadeDbPerSec );
671
+
672
+  cmRC_t         cmRecdPlayExec(        cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt );
673
+
629 674
 #ifdef __cplusplus
630 675
 }
631 676
 #endif

Loading…
Отказ
Запис