Changes to phasor and wavetable DSP objects to correct problem with phase use in the wavetable.

The phasor value must be limited to a max value - the size of the wave table
otherwise the resolution of the phasor object phase counter eventually
diminishes due to the increasing value of the integer part of the
floating point value.  This will result in distortion in the wave table
output because the phase value will not increment reliably.
This commit is contained in:
kevin 2012-12-17 12:58:05 -08:00
parent 0fcfebb1cd
commit 64831fef9f
2 changed files with 75 additions and 27 deletions

View File

@ -732,8 +732,8 @@ cmDspInst_t* _cmDspPhasorAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigne
cmDspPhasor_t* p = cmDspInstAlloc(cmDspPhasor_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
// assign default values to any of the the optional arg's which may not have been set from vl.
cmDspSetDefaultDouble(ctx, &p->inst, kMaxPhId, 0.0, DBL_MAX);
cmDspSetDefaultDouble(ctx, &p->inst, kMultPhId, 0.0, 1.0);
cmDspSetDefaultSample(ctx, &p->inst, kMaxPhId, 0.0, cmSample_MAX);
cmDspSetDefaultSample(ctx, &p->inst, kMultPhId, 0.0, 1.0);
cmDspSetDefaultDouble(ctx, &p->inst, kPhsPhId, 0.0, 0.0);
return &p->inst;
@ -750,23 +750,23 @@ cmDspRC_t _cmDspPhasorExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
{
cmSample_t* bp = cmDspAudioBuf(ctx,inst,kOutPhId,0);
const cmSample_t* ep = bp + cmDspAudioBufSmpCount(ctx,inst,kOutPhId,0);
double mult = cmDspDouble(inst,kMultPhId);
double max = cmDspDouble(inst,kMaxPhId);
cmSample_t mult = cmDspSample(inst,kMultPhId);
cmSample_t max = cmDspSample(inst,kMaxPhId);
double phs = cmDspDouble(inst,kPhsPhId);
double inc = mult;
cmSample_t inc = mult;
for(; bp<ep; ++bp)
{
while( phs >= max )
phs -= max;
*bp = phs;
*bp = (cmSample_t)phs;
phs += inc;
}
cmDspSetDouble(ctx,inst,kPhsPhId,phs);
cmDspSetSample(ctx,inst,kPhsPhId,phs);
return kOkDspRC;
}
@ -2773,12 +2773,13 @@ typedef struct
cmThreadH_t thH;
bool loadFileFl;
cmDspCtx_t* ctx;
double phsOffs;
double phsLast;
cmSample_t phsOffs;
cmSample_t phsLast;
unsigned onSymId;
unsigned offSymId;
unsigned doneSymId;
bool useThreadFl;
unsigned wt_oi;
} cmDspWaveTable_t;
bool _cmDspWaveTableThreadFunc( void* param);
@ -3201,6 +3202,57 @@ cmDspRC_t _cmDspWaveTableReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEv
}
cmDspRC_t _cmDspWaveTableExec1(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
{
cmDspRC_t rc = kOkDspRC;
cmDspWaveTable_t* p = (cmDspWaveTable_t*)inst;
unsigned mode = cmDspSymbol(inst,kCmdWtId);
unsigned srcId = cmDspUInt(inst,kShapeWtId);
if( mode == p->offSymId || srcId == kSilenceWtId )
{
cmDspZeroAudioBuf(ctx,inst,kOutWtId);
return kOkDspRC;
}
cmSample_t* outV = cmDspAudioBuf(ctx,inst,kOutWtId,0);
unsigned outCnt = cmDspVarRows(inst,kOutWtId);
unsigned wtSmpCnt = cmDspUInt(inst,kLenWtId);
double gain = cmDspDouble(inst,kGainWtId);
unsigned i;
// for each output sample
for(i=0; i<outCnt; ++i)
{
p->wt_oi = (p->wt_oi + 1) % wtSmpCnt;
outV[i] = gain * p->wt[p->wt_oi];
}
// if we are reading from a file ...
if( srcId == kFileWtId )
{
unsigned rdSmpCnt = 8192; // file read block sample count
p->wtn += outCnt;
// ... and there are rdSmpCnt avail locations in the wave table
if( p->wtn >= rdSmpCnt )
rc = _cmDspWaveTableReadAudioFile(ctx, p, wtSmpCnt, rdSmpCnt );
// send the current audio file index
if( p->doneFl && p->cfi < p->cfn && p->cfn <= (p->cfi + outCnt) )
cmDspSetSymbol(ctx,inst,kDoneWtId,p->doneSymId);
else
cmDspSetUInt(ctx,inst,kFIdxWtId,p->cfi);
p->cfi += outCnt;
}
return rc;
}
cmDspRC_t _cmDspWaveTableExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
{
cmDspRC_t rc = kOkDspRC;
@ -3233,7 +3285,8 @@ cmDspRC_t _cmDspWaveTableExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
for(i=0; i<outCnt; ++i)
{
// get the wave table location
unsigned x = fmod(phsV[i] - p->phsOffs,wtSmpCnt);
//unsigned x = fmodf(phsV[i] - p->phsOffs,wtSmpCnt);
unsigned x = fmodf(phsV[i],wtSmpCnt);
// if the wt loctn is passed the end of the table
/*
@ -3244,12 +3297,6 @@ cmDspRC_t _cmDspWaveTableExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt
}
*/
// read the wt into the output
// BUG BUG BUG BUG
// BUG BUG BUG BUG - THIS DIVISION BY 0.5 IS HACK
// BUG BUG BUG BUG
//outV[i] = 0.5 * p->wt[x];
outV[i] = gain * p->wt[x];
}
@ -4951,7 +4998,6 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
cmWaveTableClassCons,
cmSprintfClassCons,
cmKrClassCons,
cmAMixClassCons,
cmASplitClassCons,
cmAMeterClassCons,
@ -4998,11 +5044,13 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
cmGateToSymClassCons,
cmPortToSymClassCons,
cmRouterClassCons,
cmAvailChClassCons,
cmPresetClassCons,
cmBcastSymClassCons,
cmSegLineClassCons,
cmKrClassCons,
cmTimeLineClassCons,
cmScoreClassCons,
cmMidiFilePlayClassCons,

View File

@ -63,7 +63,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
cmCtx_t* cmCtx = cmDspSysPgmCtx(h);
cmErr_t err;
krRsrc_t r;
unsigned wtLoopCnt = 1; // play once (do not loop)
unsigned wtLoopCnt = -1; // play once (do not loop)
unsigned wtInitMode = 0; // initial wt mode is 'silence'
unsigned wtSmpCnt = floor(cmDspSysSampleRate(h)); // wt length == srate
@ -75,7 +75,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
cmDspInst_t* tlp = cmDspSysAllocInst(h,"TimeLine", "tl", 2, r.tlFn, r.audPath );
cmDspInst_t* scp = cmDspSysAllocInst(h,"Score", "sc", 1, r.scFn );
cmDspInst_t* php = cmDspSysAllocInst(h,"Phasor", NULL, 0 );
cmDspInst_t* php = cmDspSysAllocInst(h,"Phasor", NULL, 1, cmDspSysSampleRate(h) );
cmDspInst_t* wtp = cmDspSysAllocInst(h,"WaveTable", NULL, 4, wtSmpCnt, wtInitMode, NULL, wtLoopCnt );
cmDspInst_t* pts = cmDspSysAllocInst(h,"PortToSym", NULL, 2, "on", "off" );
cmDspInst_t* mfp = cmDspSysAllocInst(h,"MidiFilePlay",NULL, 0 );
@ -99,8 +99,8 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
cmDspSysConnectAudio(h, php, "out", wtp, "phs" ); // phs -> wt
cmDspSysConnectAudio(h, wtp, "out", ao0p, "in" ); // wt -> aout0
cmDspSysConnectAudio(h, wtp, "out", ao1p, "in" ); // wt -> aout1
cmDspSysInstallCb( h, wtp, "fidx",tlp, "curs", NULL);
//cmDspSysInstallCb( h, wtp, "fidx",prp, "in", NULL );
// start connections
cmDspSysInstallCb(h, onb, "sym", tlp, "reset", NULL );
@ -127,22 +127,22 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
cmDspSysInstallCb(h, tlp, "mfn", mfp, "fn", NULL );
// score to score follower - to set initial search location
cmDspSysInstallCb(h, scp, "sel", sfp, "index", NULL );
//cmDspSysInstallCb(h, scp, "sel", sfp, "index", NULL );
// MIDI file player to score-follower and score - the order of connections is the same
// as the msg transmision order from MFP
cmDspSysInstallCb(h, mfp, "smpidx", scp, "smpidx", NULL );
cmDspSysInstallCb(h, mfp, "d1", scp, "d1", NULL );
cmDspSysInstallCb(h, mfp, "d1", sfp, "d1", NULL );
//cmDspSysInstallCb(h, mfp, "d1", sfp, "d1", NULL );
cmDspSysInstallCb(h, mfp, "d0", scp, "d0", NULL );
cmDspSysInstallCb(h, mfp, "d0", sfp, "d0", NULL );
//cmDspSysInstallCb(h, mfp, "d0", sfp, "d0", NULL );
cmDspSysInstallCb(h, mfp, "status", scp, "status", NULL );
cmDspSysInstallCb(h, mfp, "status", sfp, "status", NULL );
//cmDspSysInstallCb(h, mfp, "status", sfp, "status", NULL );
// score follower to score
cmDspSysInstallCb(h, sfp, "out", scp, "loc", NULL );
//cmDspSysInstallCb(h, sfp, "out", scp, "loc", NULL );
// Printer connections
@ -156,6 +156,6 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
cmDspSysInstallCb(h, prtb, "sym", sfp, "cmd", NULL );
cmDspSysInstallCb(h, qtb, "sym", sfp, "cmd", NULL );
return rc;
}