cmProc4.h/c, cmDspKr.c : Added look-ahead buffer to cmRecdPlay object.
This commit is contained in:
parent
ebef000a27
commit
57d2a86a42
116
cmProc4.c
116
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);
|
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);
|
cmRecdPlayFree(&op);
|
||||||
|
|
||||||
return op;
|
return op;
|
||||||
@ -4159,19 +4159,32 @@ 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;
|
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 )
|
if((rc = cmRecdPlayFinal(p)) != cmOkRC )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
if( chCnt == 0 )
|
||||||
|
return cmOkRC;
|
||||||
|
|
||||||
p->frags = cmMemAllocZ(cmRecdPlayFrag,fragCnt);
|
p->frags = cmMemAllocZ(cmRecdPlayFrag,fragCnt);
|
||||||
p->fragCnt = fragCnt;
|
p->fragCnt = fragCnt;
|
||||||
p->srate = srate;
|
p->srate = srate;
|
||||||
p->chCnt = chCnt;
|
p->chCnt = chCnt;
|
||||||
p->initFragSecs = initFragSecs;
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -4179,6 +4192,7 @@ cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned fragCnt, u
|
|||||||
cmRC_t cmRecdPlayFinal( cmRecdPlay* p )
|
cmRC_t cmRecdPlayFinal( cmRecdPlay* p )
|
||||||
{
|
{
|
||||||
unsigned i,j;
|
unsigned i,j;
|
||||||
|
// free the fragments
|
||||||
for(i=0; i<p->fragCnt; ++i)
|
for(i=0; i<p->fragCnt; ++i)
|
||||||
{
|
{
|
||||||
for(j=0; j<p->chCnt; ++j)
|
for(j=0; j<p->chCnt; ++j)
|
||||||
@ -4186,9 +4200,17 @@ cmRC_t cmRecdPlayFinal( cmRecdPlay* p )
|
|||||||
|
|
||||||
cmMemFree(p->frags[i].chArray);
|
cmMemFree(p->frags[i].chArray);
|
||||||
}
|
}
|
||||||
cmMemFree(p->frags);
|
|
||||||
|
// 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->fragCnt = 0;
|
||||||
p->chCnt = 0;
|
p->chCnt = 0;
|
||||||
|
p->rlist = NULL;
|
||||||
|
p->plist = NULL;
|
||||||
return cmOkRC;
|
return cmOkRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4216,6 +4238,8 @@ cmRC_t cmRecdPlayRewind( cmRecdPlay* p )
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
|
p->laSmpIdx = 0;
|
||||||
|
|
||||||
while( p->plist != NULL )
|
while( p->plist != NULL )
|
||||||
cmRecdPlayEndPlay(p,p->plist->labelSymId);
|
cmRecdPlayEndPlay(p,p->plist->labelSymId);
|
||||||
|
|
||||||
@ -4228,6 +4252,7 @@ cmRC_t cmRecdPlayRewind( cmRecdPlay* p )
|
|||||||
return cmOkRC;
|
return cmOkRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId )
|
cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId )
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@ -4242,6 +4267,39 @@ cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId )
|
|||||||
p->frags[i].playIdx = 0;
|
p->frags[i].playIdx = 0;
|
||||||
p->frags[i].rlink = p->rlist;
|
p->frags[i].rlink = p->rlist;
|
||||||
p->rlist = p->frags + i;
|
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;
|
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 )
|
cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt )
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
chCnt = cmMin(chCnt, p->chCnt);
|
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;
|
cmRecdPlayFrag* fp = p->rlist;
|
||||||
|
|
||||||
for(; fp!=NULL; fp=fp->rlink)
|
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;
|
fp = p->plist;
|
||||||
for(; fp!=NULL; fp=fp->rlink)
|
for(; fp!=NULL; fp=fp->rlink)
|
||||||
{
|
{
|
||||||
|
@ -649,14 +649,18 @@ extern "C" {
|
|||||||
double srate; // system sample rate
|
double srate; // system sample rate
|
||||||
unsigned chCnt; // count of input and output audio channels
|
unsigned chCnt; // count of input and output audio channels
|
||||||
double initFragSecs; // size initial memory allocated to each frag in seconds
|
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* plist; // currently playing frags
|
||||||
cmRecdPlayFrag* rlist; // currently recording frags
|
cmRecdPlayFrag* rlist; // currently recording frags
|
||||||
} cmRecdPlay;
|
} 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 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 cmRecdPlayFinal( cmRecdPlay* p );
|
||||||
|
|
||||||
cmRC_t cmRecdPlayRegisterFrag( cmRecdPlay* p, unsigned fragIdx, unsigned labelSymId );
|
cmRC_t cmRecdPlayRegisterFrag( cmRecdPlay* p, unsigned fragIdx, unsigned labelSymId );
|
||||||
|
@ -2271,6 +2271,8 @@ enum
|
|||||||
kChCntPrId,
|
kChCntPrId,
|
||||||
kFnPrId,
|
kFnPrId,
|
||||||
kSecsPrId,
|
kSecsPrId,
|
||||||
|
kMaxLaSecsPrId,
|
||||||
|
kCurLaSecsPrId,
|
||||||
kFadeRatePrId,
|
kFadeRatePrId,
|
||||||
kScLocIdxPrId,
|
kScLocIdxPrId,
|
||||||
kCmdPrId,
|
kCmdPrId,
|
||||||
@ -2311,8 +2313,11 @@ cmDspRC_t _cmDspRecdPlayOpenScore( cmDspCtx_t* ctx, cmDspInst_t* inst )
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned markerCnt = cmScoreMarkerLabelCount(p->scH);
|
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.");
|
return cmErrMsg(&inst->classPtr->err,kSubSysFailDspRC,"Unable to create the internal recorder-player object.");
|
||||||
|
|
||||||
for(i=0; i<markerCnt; ++i)
|
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, "chs", kChCntPrId, 0,0, kUIntDsvFl | kReqArgDsvFl, "channel count.",
|
||||||
1, "fn", kFnPrId, 0,0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "Score file." ,
|
1, "fn", kFnPrId, 0,0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "Score file." ,
|
||||||
1, "secs", kSecsPrId, 0,0, kInDsvFl | kDoubleDsvFl | kReqArgDsvFl, "Initial fragment allocation in seconds.",
|
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, "frate", kFadeRatePrId, 0,0, kInDsvFl | kDoubleDsvFl, "Fade rate in dB per second.",
|
||||||
1, "index", kScLocIdxPrId, 0,0, kInDsvFl | kUIntDsvFl, "Score follower location index.",
|
1, "index", kScLocIdxPrId, 0,0, kInDsvFl | kUIntDsvFl, "Score follower location index.",
|
||||||
1, "cmd", kCmdPrId, 0,0, kInDsvFl | kSymDsvFl, "on=reset off=stop.",
|
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;
|
p->scLocIdx = 0;
|
||||||
|
|
||||||
cmDspSetDefaultDouble(ctx,&p->inst, kSecsPrId, 0, 10.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);
|
cmDspSetDefaultDouble(ctx,&p->inst, kFadeRatePrId, 0, 1.0);
|
||||||
|
|
||||||
return &p->inst;
|
return &p->inst;
|
||||||
@ -2446,6 +2455,9 @@ cmDspRC_t _cmDspRecdPlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case kCurLaSecsPrId:
|
||||||
|
break;
|
||||||
|
|
||||||
case kScLocIdxPrId:
|
case kScLocIdxPrId:
|
||||||
{
|
{
|
||||||
unsigned endScLocIdx = cmDspUInt(inst,kScLocIdxPrId) ;
|
unsigned endScLocIdx = cmDspUInt(inst,kScLocIdxPrId) ;
|
||||||
@ -2474,7 +2486,7 @@ cmDspRC_t _cmDspRecdPlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case kPlayEndScMId:
|
case kPlayEndScMId:
|
||||||
printf("recd-end\n");
|
printf("play-end\n");
|
||||||
cmRecdPlayEndPlay(p->rcdply, mp->labelSymId );
|
cmRecdPlayEndPlay(p->rcdply, mp->labelSymId );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user