Просмотр исходного кода

Added output rate control to cmDspLine().

master
Kevin Larke 9 лет назад
Родитель
Сommit
1a6156f50a
1 измененных файлов: 24 добавлений и 3 удалений
  1. 24
    3
      dsp/cmDspFx.c

+ 24
- 3
dsp/cmDspFx.c Просмотреть файл

@@ -3733,6 +3733,7 @@ enum
3733 3733
   kEndLnId,
3734 3734
   kDurLnId,
3735 3735
   kCmdLnId,
3736
+  kRateLnId,
3736 3737
   kOutLnId,
3737 3738
 };
3738 3739
 
@@ -3752,6 +3753,7 @@ typedef struct
3752 3753
   unsigned    offSymId;
3753 3754
   unsigned    resetSymId;
3754 3755
   unsigned    curSmpIdx;
3756
+  double      phase;
3755 3757
   bool        onFl;
3756 3758
 } cmDspLine_t;
3757 3759
 
@@ -3762,6 +3764,7 @@ cmDspInst_t*  _cmDspLineAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
3762 3764
     1,   "end",   kEndLnId,   0, 0, kInDsvFl   | kDoubleDsvFl | kReqArgDsvFl, "End value.",
3763 3765
     1,   "dur",   kDurLnId,   0, 0, kInDsvFl   | kDoubleDsvFl | kReqArgDsvFl, "Duration (ms)",
3764 3766
     1,   "cmd",   kCmdLnId,   0, 0, kInDsvFl   | kSymDsvFl    | kOptArgDsvFl, "Command: on | off | reset",
3767
+    1,   "rate",  kRateLnId,  0, 0, kInDsvFl   | kDoubleDsvFl | kOptArgDsvFl, "Output messages per second",
3765 3768
     1,   "out",   kOutLnId,   0, 0, kOutDsvFl  | kDoubleDsvFl,                "Output",
3766 3769
     0 );
3767 3770
 
@@ -3769,10 +3772,12 @@ cmDspInst_t*  _cmDspLineAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
3769 3772
     return NULL;
3770 3773
 
3771 3774
   cmDspSetDefaultDouble( ctx, &p->inst, kOutLnId, 0.0, cmDspDefaultDouble(&p->inst,kBegLnId) );
3775
+  cmDspSetDefaultDouble(   ctx, &p->inst, kRateLnId, 0.0, 0.0 );
3772 3776
 
3773 3777
   p->onSymId    = cmSymTblRegisterStaticSymbol(ctx->stH,"on");
3774 3778
   p->offSymId   = cmSymTblRegisterStaticSymbol(ctx->stH,"off");
3775 3779
   p->resetSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"reset");
3780
+ 
3776 3781
 
3777 3782
   return &p->inst;
3778 3783
 }
@@ -3788,6 +3793,7 @@ cmDspRC_t _cmDspLineReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
3788 3793
   cmDspLine_t* p   = (cmDspLine_t*)inst;
3789 3794
   p->curSmpIdx = 0;
3790 3795
   p->onFl      = false;
3796
+  p->phase     = 0;
3791 3797
   return cmDspApplyAllDefaults(ctx,inst);
3792 3798
 }
3793 3799
 
@@ -3799,12 +3805,21 @@ cmDspRC_t _cmDspLineExec( cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
3799 3805
   if( p->onFl == false )
3800 3806
     return kOkDspRC;
3801 3807
 
3808
+  unsigned   sPc       = cmDspSamplesPerCycle(ctx);
3802 3809
   double     beg       = cmDspDouble(inst,kBegLnId);
3803 3810
   double     end       = cmDspDouble(inst,kEndLnId);
3811
+  double     rate      = cmDspDouble(inst,kRateLnId);
3804 3812
   double     ms        = cmDspDouble(inst,kDurLnId);
3805 3813
   double     durSmpCnt = floor(ms * cmDspSampleRate(ctx) / 1000);
3806 3814
   double     out       = beg + (end - beg) * p->curSmpIdx / durSmpCnt;
3807
- 
3815
+  double     phsMax    = rate==0 ? sPc : cmDspSampleRate(ctx) / rate; 
3816
+  
3817
+  // we can never output with a period shorter than 
3818
+  // the length of one audio buffer
3819
+  if( phsMax < sPc )
3820
+    phsMax = sPc;
3821
+
3822
+
3808 3823
   if( beg < end )
3809 3824
   {
3810 3825
     if( out >= end )
@@ -3822,9 +3837,15 @@ cmDspRC_t _cmDspLineExec( cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
3822 3837
     }
3823 3838
   }
3824 3839
 
3825
-  cmDspSetDouble(ctx,inst,kOutLnId,out);
3840
+  p->phase     += sPc;
3841
+
3842
+  if( p->phase >= sPc )
3843
+  {
3844
+    cmDspSetDouble(ctx,inst,kOutLnId,out);
3845
+    p->phase -= sPc;
3846
+  }
3826 3847
 
3827
-  p->curSmpIdx += cmDspSamplesPerCycle(ctx);
3848
+  p->curSmpIdx += sPc;
3828 3849
 
3829 3850
   return rc;
3830 3851
 }

Загрузка…
Отмена
Сохранить