From 64831fef9ff895dea07e14978fe6110f554072eb Mon Sep 17 00:00:00 2001 From: kevin Date: Mon, 17 Dec 2012 12:58:05 -0800 Subject: [PATCH] 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. --- dsp/cmDspBuiltIn.c | 84 ++++++++++++++++++++++++++++++++++++---------- dsp/cmDspPgmKr.c | 18 +++++----- 2 files changed, 75 insertions(+), 27 deletions(-) diff --git a/dsp/cmDspBuiltIn.c b/dsp/cmDspBuiltIn.c index 65f3f37..43d2641 100644 --- a/dsp/cmDspBuiltIn.c +++ b/dsp/cmDspBuiltIn.c @@ -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= 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; iwt_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; iphsOffs,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, diff --git a/dsp/cmDspPgmKr.c b/dsp/cmDspPgmKr.c index c88b854..753b16f 100644 --- a/dsp/cmDspPgmKr.c +++ b/dsp/cmDspPgmKr.c @@ -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; }