cmProc4.h/c, cmDspKr.c : Added look-ahead buffer to cmRecdPlay object.
This commit is contained in:
parent
ebef000a27
commit
57d2a86a42
120
cmProc4.c
120
cmProc4.c
@ -4134,11 +4134,11 @@ cmRC_t cmScModulatorDump( cmScModulator* p )
|
||||
}
|
||||
|
||||
//=======================================================================================================================
|
||||
cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs )
|
||||
cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs )
|
||||
{
|
||||
cmRecdPlay* op = cmObjAlloc(cmRecdPlay,c,p);
|
||||
|
||||
if( cmRecdPlayInit(op,srate,fragCnt,chCnt,initFragSecs) != cmOkRC )
|
||||
if( cmRecdPlayInit(op,srate,fragCnt,chCnt,initFragSecs,maxLaSecs,curLaSecs) != cmOkRC )
|
||||
cmRecdPlayFree(&op);
|
||||
|
||||
return op;
|
||||
@ -4159,26 +4159,40 @@ cmRC_t cmRecdPlayFree( cmRecdPlay** pp )
|
||||
|
||||
}
|
||||
|
||||
cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs )
|
||||
cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs )
|
||||
{
|
||||
|
||||
cmRC_t rc;
|
||||
unsigned i;
|
||||
|
||||
if( curLaSecs > maxLaSecs )
|
||||
return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The initial look-ahead time %f is greater than the maximum look-ahead time %f.",curLaSecs,maxLaSecs);
|
||||
|
||||
if((rc = cmRecdPlayFinal(p)) != cmOkRC )
|
||||
return rc;
|
||||
|
||||
if( chCnt == 0 )
|
||||
return cmOkRC;
|
||||
|
||||
p->frags = cmMemAllocZ(cmRecdPlayFrag,fragCnt);
|
||||
p->fragCnt = fragCnt;
|
||||
p->srate = srate;
|
||||
p->chCnt = chCnt;
|
||||
p->initFragSecs = initFragSecs;
|
||||
p->maxLaSmpCnt = floor(maxLaSecs*srate);
|
||||
p->curLaSmpCnt = floor(curLaSecs*srate);
|
||||
p->laChs = cmMemAllocZ(cmSample_t*,chCnt);
|
||||
p->laSmpIdx = 0;
|
||||
|
||||
for(i=0; i<chCnt; ++i)
|
||||
p->laChs[i] = cmMemAllocZ(cmSample_t,p->maxLaSmpCnt);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
cmRC_t cmRecdPlayFinal( cmRecdPlay* p )
|
||||
{
|
||||
unsigned i,j;
|
||||
// free the fragments
|
||||
for(i=0; i<p->fragCnt; ++i)
|
||||
{
|
||||
for(j=0; j<p->chCnt; ++j)
|
||||
@ -4186,9 +4200,17 @@ cmRC_t cmRecdPlayFinal( cmRecdPlay* p )
|
||||
|
||||
cmMemFree(p->frags[i].chArray);
|
||||
}
|
||||
cmMemFree(p->frags);
|
||||
p->fragCnt=0;
|
||||
p->chCnt=0;
|
||||
|
||||
// free the look-ahead buffers
|
||||
for(i=0; i<p->chCnt; ++i)
|
||||
cmMemFree(p->laChs[i]);
|
||||
|
||||
cmMemPtrFree(&p->laChs);
|
||||
cmMemPtrFree(&p->frags);
|
||||
p->fragCnt = 0;
|
||||
p->chCnt = 0;
|
||||
p->rlist = NULL;
|
||||
p->plist = NULL;
|
||||
return cmOkRC;
|
||||
}
|
||||
|
||||
@ -4216,6 +4238,8 @@ cmRC_t cmRecdPlayRewind( cmRecdPlay* p )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
p->laSmpIdx = 0;
|
||||
|
||||
while( p->plist != NULL )
|
||||
cmRecdPlayEndPlay(p,p->plist->labelSymId);
|
||||
|
||||
@ -4228,6 +4252,7 @@ cmRC_t cmRecdPlayRewind( cmRecdPlay* p )
|
||||
return cmOkRC;
|
||||
}
|
||||
|
||||
|
||||
cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId )
|
||||
{
|
||||
unsigned i;
|
||||
@ -4242,6 +4267,39 @@ cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId )
|
||||
p->frags[i].playIdx = 0;
|
||||
p->frags[i].rlink = p->rlist;
|
||||
p->rlist = p->frags + i;
|
||||
|
||||
// handle LA buf longer than frag buf.
|
||||
int cpyCnt = cmMin(p->curLaSmpCnt,p->frags[i].allocCnt);
|
||||
|
||||
// go backwards in LA buf from newest sample to find init src offset
|
||||
int srcOffs = p->laSmpIdx - cpyCnt;
|
||||
|
||||
// if the src is before the first sample in the LA buf then wrap to end of buf
|
||||
if( srcOffs < 0 )
|
||||
srcOffs += p->maxLaSmpCnt;
|
||||
|
||||
assert( 0 <= srcOffs && srcOffs < p->maxLaSmpCnt );
|
||||
|
||||
// cnt of samples to copy from LA buf (limited by end of LA buf)
|
||||
int n0 = cmMin(cpyCnt,p->maxLaSmpCnt - srcOffs);
|
||||
|
||||
// if necessary wrap to begin of LA buf for remaining samples
|
||||
int n1 = cpyCnt>n0 ? n1 = cpyCnt-n0 : 0;
|
||||
int j;
|
||||
|
||||
assert(n0+n1 == cpyCnt );
|
||||
|
||||
for(j=0; j<p->chCnt; ++j)
|
||||
cmVOS_Copy(p->frags[i].chArray[j],n0,p->laChs[j]+srcOffs);
|
||||
|
||||
if( n1 > 0 )
|
||||
{
|
||||
for(j=0; j<p->chCnt; ++j)
|
||||
cmVOS_Copy(p->frags[i].chArray[j]+n0,n1,p->laChs[j]);
|
||||
}
|
||||
|
||||
p->frags[i].recdIdx = cpyCnt;
|
||||
|
||||
}
|
||||
|
||||
return cmOkRC;
|
||||
@ -4341,8 +4399,53 @@ cmRC_t cmRecdPlayBeginFade( cmRecdPlay* p, unsigned labelSymId, double fadeDbP
|
||||
|
||||
cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
chCnt = cmMin(chCnt, p->chCnt);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// copy incoming audio into the look-head buffers
|
||||
//
|
||||
|
||||
// if the number of incoming samples is longer than the look-head buffer
|
||||
// then copy exactly maxLaSmpCnt samples from the end of the incoming sample
|
||||
// buffer to the look-ahead buffer.
|
||||
unsigned srcOffs = 0;
|
||||
unsigned srcSmpCnt = smpCnt;
|
||||
if( srcSmpCnt > p->maxLaSmpCnt )
|
||||
{
|
||||
// advance incoming sample buffer so that there are maxLaSmpCnt samples remaining
|
||||
srcOffs = smpCnt-p->maxLaSmpCnt;
|
||||
srcSmpCnt = p->maxLaSmpCnt; // decrease the total samples to copy
|
||||
}
|
||||
|
||||
// count of samples from cur posn to end of the LA buffer.
|
||||
unsigned n0 = cmMin(srcSmpCnt, p->maxLaSmpCnt - p->laSmpIdx );
|
||||
|
||||
// count of samples past the end of the LA buffer to be wrapped into begin of buffer
|
||||
unsigned n1 = srcSmpCnt>n0 ? srcSmpCnt-n0 : 0;
|
||||
|
||||
assert(n0+n1 == srcSmpCnt);
|
||||
|
||||
// copy first block to end of LA buffer
|
||||
for(i=0; i<chCnt; ++i)
|
||||
cmVOS_Copy(p->laChs[i]+p->laSmpIdx,n0,iChs[i] + srcOffs);
|
||||
|
||||
p->laSmpIdx += n0;
|
||||
|
||||
if( n1!=0)
|
||||
{
|
||||
// copy second block to begin of LA buffer
|
||||
for(i=0; i<chCnt; ++i)
|
||||
cmVOS_Copy(p->laChs[i],n1,iChs[i] + srcOffs + n0);
|
||||
|
||||
p->laSmpIdx = n1;
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// copy incoming audio into the active record buffers
|
||||
//
|
||||
cmRecdPlayFrag* fp = p->rlist;
|
||||
|
||||
for(; fp!=NULL; fp=fp->rlink)
|
||||
@ -4357,6 +4460,9 @@ cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// copy outgoing audio out of the active play buffers
|
||||
//
|
||||
fp = p->plist;
|
||||
for(; fp!=NULL; fp=fp->rlink)
|
||||
{
|
||||
|
@ -649,14 +649,18 @@ extern "C" {
|
||||
double srate; // system sample rate
|
||||
unsigned chCnt; // count of input and output audio channels
|
||||
double initFragSecs; // size initial memory allocated to each frag in seconds
|
||||
unsigned maxLaSmpCnt; // samples allocated to each channel of the look-ahead buffers.
|
||||
unsigned curLaSmpCnt; // current look-ahead time in samples (curLaSmpCnt<=maxLaSmpCnt)
|
||||
cmSample_t** laChs; // laChs[chCnt][maxLaSmpCnt] - look-ahead buffers
|
||||
int laSmpIdx; // next look-ahead buffer index to receive a sample
|
||||
cmRecdPlayFrag* plist; // currently playing frags
|
||||
cmRecdPlayFrag* rlist; // currently recording frags
|
||||
} cmRecdPlay;
|
||||
|
||||
|
||||
cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs );
|
||||
cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs );
|
||||
cmRC_t cmRecdPlayFree( cmRecdPlay** pp );
|
||||
cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs );
|
||||
cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs );
|
||||
cmRC_t cmRecdPlayFinal( cmRecdPlay* p );
|
||||
|
||||
cmRC_t cmRecdPlayRegisterFrag( cmRecdPlay* p, unsigned fragIdx, unsigned labelSymId );
|
||||
|
@ -2271,6 +2271,8 @@ enum
|
||||
kChCntPrId,
|
||||
kFnPrId,
|
||||
kSecsPrId,
|
||||
kMaxLaSecsPrId,
|
||||
kCurLaSecsPrId,
|
||||
kFadeRatePrId,
|
||||
kScLocIdxPrId,
|
||||
kCmdPrId,
|
||||
@ -2311,8 +2313,11 @@ cmDspRC_t _cmDspRecdPlayOpenScore( cmDspCtx_t* ctx, cmDspInst_t* inst )
|
||||
{
|
||||
unsigned i;
|
||||
unsigned markerCnt = cmScoreMarkerLabelCount(p->scH);
|
||||
double initFragSecs = cmDspDouble(inst,kSecsPrId);
|
||||
double maxLaSecs = cmDspDouble(inst,kMaxLaSecsPrId);
|
||||
double curLaSecs = cmDspDouble(inst,kCurLaSecsPrId);
|
||||
|
||||
if((p->rcdply = cmRecdPlayAlloc(ctx->cmProcCtx, NULL, cmDspSampleRate(ctx), markerCnt, p->chCnt, cmDspDouble(inst,kSecsPrId))) == NULL)
|
||||
if((p->rcdply = cmRecdPlayAlloc(ctx->cmProcCtx, NULL, cmDspSampleRate(ctx), markerCnt, p->chCnt, initFragSecs, maxLaSecs, curLaSecs)) == NULL)
|
||||
return cmErrMsg(&inst->classPtr->err,kSubSysFailDspRC,"Unable to create the internal recorder-player object.");
|
||||
|
||||
for(i=0; i<markerCnt; ++i)
|
||||
@ -2343,6 +2348,8 @@ cmDspInst_t* _cmDspRecdPlayAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsig
|
||||
1, "chs", kChCntPrId, 0,0, kUIntDsvFl | kReqArgDsvFl, "channel count.",
|
||||
1, "fn", kFnPrId, 0,0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "Score file." ,
|
||||
1, "secs", kSecsPrId, 0,0, kInDsvFl | kDoubleDsvFl | kReqArgDsvFl, "Initial fragment allocation in seconds.",
|
||||
1, "maxla", kMaxLaSecsPrId, 0,0, kInDsvFl | kDoubleDsvFl, "Maximum look-ahead buffer in seconds.",
|
||||
1, "curla", kCurLaSecsPrId, 0,0, kInDsvFl | kDoubleDsvFl, "Current look-head buffer in seconds.",
|
||||
1, "frate", kFadeRatePrId, 0,0, kInDsvFl | kDoubleDsvFl, "Fade rate in dB per second.",
|
||||
1, "index", kScLocIdxPrId, 0,0, kInDsvFl | kUIntDsvFl, "Score follower location index.",
|
||||
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
|
||||
p->scLocIdx = 0;
|
||||
|
||||
cmDspSetDefaultDouble(ctx,&p->inst, kSecsPrId, 0, 10.0 );
|
||||
cmDspSetDefaultDouble(ctx,&p->inst, kMaxLaSecsPrId,0, 2.0);
|
||||
cmDspSetDefaultDouble(ctx,&p->inst, kCurLaSecsPrId,0, 0.5);
|
||||
cmDspSetDefaultDouble(ctx,&p->inst, kFadeRatePrId, 0, 1.0);
|
||||
|
||||
return &p->inst;
|
||||
@ -2446,6 +2455,9 @@ cmDspRC_t _cmDspRecdPlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
||||
|
||||
break;
|
||||
|
||||
case kCurLaSecsPrId:
|
||||
break;
|
||||
|
||||
case kScLocIdxPrId:
|
||||
{
|
||||
unsigned endScLocIdx = cmDspUInt(inst,kScLocIdxPrId) ;
|
||||
@ -2474,7 +2486,7 @@ cmDspRC_t _cmDspRecdPlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
||||
break;
|
||||
|
||||
case kPlayEndScMId:
|
||||
printf("recd-end\n");
|
||||
printf("play-end\n");
|
||||
cmRecdPlayEndPlay(p->rcdply, mp->labelSymId );
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user