|
@@ -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
|
+}
|