diff --git a/cwAudioTransforms.cpp b/cwAudioTransforms.cpp
index d85a253..e2314d5 100644
--- a/cwAudioTransforms.cpp
+++ b/cwAudioTransforms.cpp
@@ -59,7 +59,7 @@ namespace cw
         return rc;
       }
       
-      rc_t test( const cw::object_t* args )
+      rc_t test()
       {
         double hann_15[] = { 0.0, 0.04951557, 0.1882551 , 0.38873953, 0.61126047, 0.8117449,  0.95048443, 1.0,        0.95048443, 0.8117449, 0.61126047, 0.38873953, 0.1882551, 0.04951557, 0.0 };
         double hann_16[] = { 0.0, 0.04322727, 0.1654347 , 0.3454915 , 0.55226423, 0.75,       0.9045085 , 0.9890738,  0.9890738,  0.9045085, 0.75,       0.55226423, 0.3454915, 0.1654347 , 0.04322727,  0.0 };
@@ -87,7 +87,7 @@ namespace cw
 
     namespace ola
     {
-      rc_t test( const cw::object_t* args )
+      rc_t test()
       {
         typedef float sample_t;
         
@@ -150,7 +150,7 @@ namespace cw
 
     namespace shift_buf
     {
-      rc_t  test( const object_t* args )
+      rc_t  test()
       {
         rc_t rc = kOkRC;
         typedef float sample_t;
@@ -223,7 +223,7 @@ namespace cw
 
     namespace pv_anl
     {
-      rc_t  test( const object_t* args )
+      rc_t  test()
       {
         rc_t            rc         = kOkRC;
         pv_anl::fobj_t* pva        = nullptr;
@@ -253,12 +253,256 @@ namespace cw
       
     }
 
-    rc_t test( const cw::object_t* args )
+    namespace wt_osc
     {
-      wnd_func::test(args);
-      ola::test(args);
-      shift_buf::test(args);
-      return kOkRC;
+      typedef float sample_t;
+      typedef float srate_t;
+
+      rc_t test()
+      {
+        rc_t     rc    = kOkRC;
+        srate_t  srate = 8;
+        sample_t aV[]  = { 7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0 };
+        
+        struct wt_str<sample_t,srate_t> wt{
+          .tid = kLoopWtTId,
+          .cyc_per_loop = 0,
+          .aV = aV,
+          .aN = 16,
+          .rms = 0,
+          .hz  = 1,
+          .srate = srate,
+          .pad_smpN = 1,
+          .posn_smp_idx = 0
+        };
+
+        struct obj_str<sample_t,srate_t> obj;
+        init(&obj,&wt);
+
+        unsigned yN = (int)(srate*2);
+        sample_t yV[yN];
+        unsigned actual = 0;
+        process(&obj, yV, yN,actual);
+        
+        vop::print( yV, yN, "%f");
+          
+        return rc;
+      }
+      
+    }
+
+    namespace wt_seq_osc
+    {
+      typedef float sample_t;
+      typedef float srate_t;
+
+      rc_t test()
+      {
+        rc_t     rc    = kOkRC;
+        srate_t  srate = 8;
+        sample_t aV[]  = { 7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0 };
+        
+        struct wt_osc::wt_str<sample_t,srate_t> wt{
+          .tid = wt_osc::kOneShotWtTId,
+          .cyc_per_loop = 0,
+          .aV = aV,
+          .aN = 16,
+          .rms = 0,
+          .hz  = 1,
+          .srate = srate,
+          .pad_smpN = 1,
+          .posn_smp_idx = 0
+        };
+
+        struct wt_osc::wt_str<sample_t,srate_t> wt0 = wt;
+        struct wt_osc::wt_str<sample_t,srate_t> wt1 = wt;
+        struct wt_osc::wt_str<sample_t,srate_t> wt2 = wt;
+
+
+        wt1.tid = wt_osc::kLoopWtTId;
+        wt1.posn_smp_idx = 16;
+        wt2.tid = wt_osc::kLoopWtTId;
+        wt2.posn_smp_idx = 32;
+        
+        struct wt_osc::wt_str<sample_t,srate_t> wtA[] = {
+          wt0,
+          wt1,
+          wt2
+        };
+
+        struct wt_seq_osc::wt_seq_str<sample_t,srate_t> wt_seq{
+          .wtA = wtA,
+          .wtN = 3
+        };
+
+        struct wt_seq_osc::obj_str<sample_t,srate_t> obj;
+        init(&obj,&wt_seq);
+
+        unsigned yN = (int)(srate*10);
+        sample_t yV[yN];
+        unsigned actual = 0;
+        unsigned yi = 0;
+        unsigned yDspSmpCnt = 8;
+        while( yi < yN && is_init(&obj) )
+        {
+          unsigned frmSmpN = std::min(yN-yi,yDspSmpCnt);          
+          process(&obj, yV+yi, frmSmpN, actual);
+          assert( actual == frmSmpN );
+          yi += actual;
+        }
+        
+        vop::print( yV, yi, "%5.3f",nullptr,8);
+          
+        return rc;
+      }
+      
+    }
+
+    namespace multi_ch_wt_seq_osc
+    {
+      typedef float sample_t;
+      typedef float srate_t;
+
+      rc_t test()
+      {
+        rc_t     rc    = kOkRC;
+        unsigned chN   = 2;
+        srate_t  srate = 8;
+        sample_t a0V[]  = { 7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0 };
+        sample_t a1V[]  = { 17,10,11,12,13,14,15,16,17,10,11,12,13,14,15,16,17,10 };
+        sample_t a2V[]  = { 27,20,21,22,23,24,25,26,27,20,21,22,23,24,25,26,27,20 };
+        
+        struct wt_osc::wt_str<sample_t,srate_t> wt{
+          .tid = wt_osc::kOneShotWtTId,
+          .cyc_per_loop = 0,
+          .aV = a0V,
+          .aN = 16,
+          .rms = 0,
+          .hz  = 1,
+          .srate = srate,
+          .pad_smpN = 1,
+          .posn_smp_idx = 0
+        };
+
+        struct wt_osc::wt_str<sample_t,srate_t> wt0 = wt;
+        struct wt_osc::wt_str<sample_t,srate_t> wt1 = wt;
+        struct wt_osc::wt_str<sample_t,srate_t> wt2 = wt;
+
+
+        wt1.tid = wt_osc::kLoopWtTId;
+        wt1.posn_smp_idx = 16;
+        wt1.aV = a1V;
+        
+        wt2.tid = wt_osc::kLoopWtTId;
+        wt2.posn_smp_idx = 32;
+        wt2.aV = a2V;
+        
+        struct wt_osc::wt_str<sample_t,srate_t> wtA[] = {
+          wt0,
+          wt1,
+          wt2
+        };
+
+        struct wt_seq_osc::wt_seq_str<sample_t,srate_t> wt_seq{
+          .wtA = wtA,
+          .wtN = 3
+        };
+
+        
+        struct wt_seq_osc::wt_seq_str<sample_t,srate_t> chA[] = {
+          wt_seq,
+          wt_seq
+        };
+
+        struct multi_ch_wt_seq_str<sample_t,srate_t> mcs = {
+          .chA = chA,
+          .chN = chN
+        };
+        
+        
+        struct obj_str<sample_t,srate_t> obj;
+        
+        if((rc = create(&obj,chN)) != kOkRC )
+          goto errLabel;
+
+        if((rc = setup(&obj,&mcs)) != kOkRC )
+          goto errLabel;
+        else
+        {
+          unsigned yN = (int)(srate*10);
+          unsigned actual = 0;
+          unsigned yi = 0;
+          unsigned yDspSmpCnt = 8;
+
+        
+          while( yi < yN && !is_done(&obj) )
+          {
+            unsigned frmSmpN = std::min(yN-yi,yDspSmpCnt);
+            sample_t yV[frmSmpN*chN];
+          
+            if((rc = process(&obj, yV, chN, frmSmpN, actual)) != kOkRC )
+              goto errLabel;
+
+            assert( actual == frmSmpN );
+                    
+            vop::print( yV, frmSmpN*chN, "%5.3f",nullptr,8);
+                    
+            yi += actual;
+          }
+        }
+        
+      errLabel:
+        destroy(&obj);
+        
+        return rc;
+      }
+      
+    } 
+    
+    
+    rc_t test( const test::test_args_t& args )
+    {
+      rc_t rc = kOkRC;
+      
+      if( textIsEqual(args.test_label,"wnd_func") )
+      {
+        rc = wnd_func::test();
+        goto errLabel;
+      }
+
+      if( textIsEqual(args.test_label,"ola") )
+      {
+        rc = ola::test();
+        goto errLabel;
+      }
+      
+      if( textIsEqual(args.test_label,"shift_buf") )
+      {
+        rc = shift_buf::test();
+        goto errLabel;
+      }
+
+      if( textIsEqual(args.test_label,"wt_osc") )
+      {
+        rc = wt_osc::test();
+        goto errLabel;
+      }
+
+      if( textIsEqual(args.test_label,"wt_seq_osc") )
+      {
+        rc = wt_seq_osc::test();
+        goto errLabel;
+      }
+
+      if( textIsEqual(args.test_label,"multi_ch_wt_seq_osc") )
+      {
+        rc = multi_ch_wt_seq_osc::test();
+        goto errLabel;
+      }
+      
+      rc = cwLogError(kInvalidArgRC,"Unknown test case module:%s test:%s.",args.module_label,args.test_label);
+    errLabel:
+      return rc;
     }
   }
 
diff --git a/cwAudioTransforms.h b/cwAudioTransforms.h
index b3d2614..52c78ee 100644
--- a/cwAudioTransforms.h
+++ b/cwAudioTransforms.h
@@ -779,9 +779,9 @@ namespace cw
   
         ifft::exec_polar( p->ft, magV, phsV );
 
-	// convert double to float
-	T0 v[ p->ft->outN ];
-	vop::copy( v, p->ft->outV, p->ft->outN );
+        // convert double to float
+        T0 v[ p->ft->outN ];
+        vop::copy( v, p->ft->outV, p->ft->outN );
   
         ola::exec( p->ola, v, p->ft->outN ); 
 
@@ -1233,8 +1233,447 @@ namespace cw
       
     }
 
+
+    //---------------------------------------------------------------------------------------------------------------------------------
+    // wt_osc
+    //
     
-    rc_t test( const cw::object_t* args );
+    namespace wt_osc
+    {
+
+      typedef enum {
+        kInvalidWtTId,
+        kOneShotWtTId,
+        kLoopWtTId
+      } wt_tid_t;
+
+      template< typename sample_t, typename srate_t >
+      struct wt_str
+      {
+        wt_tid_t        tid;
+        unsigned        cyc_per_loop; // count of cycles in the loop
+        sample_t*       aV;       // aV[ padN + aN + padN ]
+        unsigned        aN;       // Count of unique samples
+        double          rms;
+        double          hz;
+        srate_t         srate;
+        unsigned        pad_smpN;
+        unsigned        posn_smp_idx; // The location of this sample in the original audio file. 
+      };
+
+
+      template< typename sample_t >
+      sample_t table_read_2( const sample_t* tab, double frac )
+      {
+
+        unsigned i0 = floor(frac);
+        unsigned i1 = i0 + 1;
+        double   f  = frac - int(frac);
+
+        sample_t r = (sample_t)(tab[i0] + (tab[i1] - tab[i0]) * f);
+
+        //intf("r:%f frac:%f i0:%i f:%f\n",r,frac,i0,f);
+        return r;
+      }
+
+      template< typename sample_t >
+      sample_t hann_read( double x, double N )
+      {
+        while( x > N)
+          x -= N;
+
+        x = x - (N/2) ;
+
+        return (sample_t)(0.5 + 0.5 * cos(2*M_PI * x / N));
+      }
+      
+      template< typename sample_t, typename srate_t >
+      struct obj_str
+      {
+        const wt_str<sample_t,srate_t>* wt;
+        
+        double    phs;          // current fractional phase into wt->aV[]
+        double    fsmp_per_wt;  // 
+        
+      };
+
+      template< typename sample_t, typename srate_t >
+      bool is_init(const struct obj_str<sample_t,srate_t>* p)
+      { return p->wt != nullptr;  }
+      
+      template< typename sample_t, typename srate_t >
+      void init(struct obj_str<sample_t,srate_t>* p, struct wt_str<sample_t,srate_t>* wt)
+      {
+        if( wt == nullptr )
+          p->wt = nullptr;
+        else
+        {
+          double fsmp_per_cyc = wt->srate/wt->hz;
+          p->fsmp_per_wt  = fsmp_per_cyc * 2;  // each wavetable contains 2
+          
+          p->wt     = wt;
+          p->phs   = 0;
+        }        
+      }
+
+      template< typename sample_t, typename srate_t >
+      void _process_loop(struct obj_str<sample_t,srate_t>* p, sample_t* aV, unsigned aN, unsigned& actual_Ref)
+      {
+        double   phs0       = p->phs;
+        double   phs1       = phs0 + p->fsmp_per_wt/2;
+        unsigned smp_per_wt = (int)floor(p->fsmp_per_wt); // 
+
+        while(phs1 >= smp_per_wt)
+          phs1 -= smp_per_wt;
+        
+        for(unsigned i=0; i<aN; ++i)
+        {
+          sample_t s0 = table_read_2( p->wt->aV+p->wt->pad_smpN, phs0 );
+          sample_t s1 = table_read_2( p->wt->aV+p->wt->pad_smpN, phs1 );
+
+          sample_t e0 = hann_read<sample_t>(phs0,p->fsmp_per_wt);
+          sample_t e1 = hann_read<sample_t>(phs1,p->fsmp_per_wt);
+
+          aV[ i ] = e0*s0 + e1*s1;
+
+          // advance the phases of the oscillators
+          phs0 += 1;
+          while(phs0 >= smp_per_wt)
+            phs0 -= smp_per_wt;
+
+          phs1 += 1;
+          while(phs1 >= smp_per_wt)
+            phs1 -= smp_per_wt;
+
+        }
+        
+        p->phs     = phs0;
+        actual_Ref = aN;
+      }
+
+      template< typename sample_t, typename srate_t >
+      void _process_one_shot(struct obj_str<sample_t,srate_t>* p, sample_t* aV, unsigned aN, unsigned& actual_Ref)
+      {        
+        unsigned phs = (unsigned)p->phs;
+        unsigned i;
+        for(i=0; i<aN && phs<p->wt->aN; ++i,++phs)
+          aV[i] = p->wt->aV[ p->wt->pad_smpN + phs ];
+
+        p->phs     = phs;
+        actual_Ref = i;
+        
+      }
+      
+      template< typename sample_t, typename srate_t >
+      void process(struct obj_str<sample_t,srate_t>* p, sample_t* aV, unsigned aN, unsigned& actual_Ref)
+      {
+        actual_Ref = 0;
+        switch( p->wt->tid )
+        {
+          case wt_osc::kLoopWtTId:
+            _process_loop(p,aV,aN,actual_Ref);
+            break;
+            
+          case wt_osc::kOneShotWtTId:
+            _process_one_shot(p,aV,aN,actual_Ref);
+            break;
+            
+          default:
+            assert(0);
+        }
+        
+      }
+      
+      rc_t test();
+     
+    } // wt_osc     
+      
+      
+    namespace wt_seq_osc
+    {
+
+      template< typename sample_t, typename srate_t >
+      struct wt_seq_str
+      {
+        struct wt_osc::wt_str<sample_t,srate_t>* wtA;
+        unsigned                                 wtN;
+      };
+      
+      template< typename sample_t, typename srate_t >
+      struct obj_str
+      {
+        struct wt_seq_osc::wt_seq_str<sample_t,srate_t>* wt_seq;
+        struct wt_osc::obj_str<sample_t,srate_t>         osc0;
+        struct wt_osc::obj_str<sample_t,srate_t>         osc1;
+        
+        unsigned wt_idx; // index of wt0 in wt_seq->wtA[]
+
+        
+        unsigned mix_interval_smp; // osc0/osc1 crossfade interval in samples
+        unsigned mix_phs;          // current crossfade phase (0 <= mix_phs <= mix_interval_smp)
+      };
+
+      template< typename sample_t, typename srate_t >
+      rc_t _update_wt( struct obj_str<sample_t,srate_t>* p, unsigned wt_idx )
+      {
+        rc_t rc = kOkRC;        
+        struct wt_osc::wt_str<sample_t,srate_t>* wt0 = nullptr;
+        struct wt_osc::wt_str<sample_t,srate_t>* wt1 = nullptr;
+
+        p->mix_interval_smp = 0;
+        
+        if( wt_idx < p->wt_seq->wtN )
+          wt0 = p->wt_seq->wtA + wt_idx;
+        
+        if( (wt_idx+1) < p->wt_seq->wtN )
+        {
+          wt1 = p->wt_seq->wtA + (wt_idx+1);
+          
+          unsigned posn0_smp_idx = wt0->posn_smp_idx;
+          unsigned posn1_smp_idx = wt1->posn_smp_idx;
+
+          if( posn1_smp_idx < posn0_smp_idx )
+          {
+            rc = cwLogError(kInvalidStateRC,"The position of the wavetable at wt. seq index:%i must be greater than the position of the previous wt.",wt_idx+1);
+            
+            goto errLabel;
+          }
+          
+          p->mix_interval_smp = posn1_smp_idx - posn0_smp_idx;
+        }
+
+        wt_osc::init(&p->osc0,wt0);
+        wt_osc::init(&p->osc1,wt1);
+        
+        p->wt_idx = wt_idx;
+        p->mix_phs = 0;
+
+      errLabel:
+        return rc;
+      }
+
+
+      template< typename sample_t, typename srate_t >
+      bool is_init( const struct obj_str<sample_t,srate_t>* p )
+      {
+        return is_init(&p->osc0);
+      }
+      
+      template< typename sample_t, typename srate_t >
+      rc_t init(struct obj_str<sample_t,srate_t>* p, struct wt_seq_osc::wt_seq_str<sample_t,srate_t>* wt_seq)
+      {
+        rc_t rc = kOkRC;
+        p->wt_seq = wt_seq;
+        p->wt_idx = 0;
+
+        if((rc = _update_wt(p,0)) != kOkRC )
+          goto errLabel;
+
+      errLabel:
+        return rc;
+      }
+
+      
+      template< typename sample_t, typename srate_t >
+      rc_t process(struct obj_str<sample_t,srate_t>* p, sample_t* aV, unsigned aN, unsigned& actual_Ref)
+      {
+        actual_Ref = 0;
+        
+        rc_t rc = kOkRC;
+        unsigned actual;
+        bool atk_fl = p->wt_idx==0 && p->osc0.wt->tid == wt_osc::kOneShotWtTId;
+
+        // if the osc is in the attack phase
+        if( atk_fl )
+        {
+          // update aV[aN] from osc0
+          wt_osc::process(&p->osc0,aV,aN,actual);
+
+          actual_Ref = actual;
+
+          // if all requested samples were generated we are done ...
+          if( actual >= aN )
+            return rc;
+
+          // otherwise all requested samples were not generated
+          // fill the rest of aV[] from the next one or two wave tables.
+          aN -= actual;
+          aV += actual;
+
+          // initialize osc0 and osc1
+          if((rc = _update_wt(p, 1)) != kOkRC )
+            goto errLabel;          
+        }
+
+        wt_osc::process(&p->osc0,aV,aN,actual);
+
+        // if the second oscillator is initialized
+        if( wt_osc::is_init(&p->osc1) )
+        {
+          unsigned actual1 = 0;
+          sample_t tV[ aN ];
+          // generate aN samples into tV[aN]
+          wt_osc::process(&p->osc1,tV,aN,actual1);
+
+          assert( actual1 == actual );
+
+          
+          sample_t g = (sample_t)std::min(1.0,(double)p->mix_phs / p->mix_interval_smp);
+
+          // mix the output of the second oscillator into the output signal
+          vop::scale_add(aV,aV,(1.0f-g),tV,g,actual1);
+
+          p->mix_phs += actual;
+
+          // if the osc0/osc1 xfade is complete ...
+          if( p->mix_phs >= p->mix_interval_smp )
+          {
+            // ... then advance to the next set of wavetables
+            if((rc = _update_wt(p, p->wt_idx+1)) != kOkRC )
+              goto errLabel;
+          }
+          
+        }
+         
+        actual_Ref += actual;          
+       
+      errLabel:
+        return rc;
+      }
+      
+      rc_t test();
+      
+    } // wt_seq_osc
+
+    namespace multi_ch_wt_seq_osc
+    {
+      template< typename sample_t, typename srate_t >
+      struct multi_ch_wt_seq_str
+      {
+        struct wt_seq_osc::wt_seq_str<sample_t,srate_t>* chA;
+        unsigned                                         chN;
+      };
+
+      template< typename sample_t, typename srate_t >
+      struct obj_str
+      {
+        const struct multi_ch_wt_seq_str<sample_t,srate_t>* mcs      = nullptr;
+        struct wt_seq_osc::obj_str<sample_t,srate_t>*       chA      = nullptr;
+        unsigned                                            chAllocN = 0;
+        unsigned                                            chN      = 0;
+        bool                                                done_fl  = true;
+      };
+
+
+      template< typename sample_t, typename srate_t >
+      rc_t create(struct obj_str<sample_t,srate_t>* p, unsigned maxChN, const struct multi_ch_wt_seq_str<sample_t,srate_t>* mcs=nullptr )
+      {
+        rc_t rc = kOkRC;
+
+        destroy(p);
+
+        p->chA = mem::allocZ< struct wt_seq_osc::obj_str<sample_t,srate_t> >(maxChN);
+        p->chAllocN = maxChN;
+        p->chN = 0;
+        p->done_fl = true;
+
+        if( mcs != nullptr )
+          setup(p,mcs);
+        
+        return rc;
+      }
+
+      template< typename sample_t, typename srate_t >
+      rc_t destroy(struct obj_str<sample_t,srate_t>* p )
+      {
+        rc_t rc = kOkRC;
+
+        mem::release(p->chA);
+        p->chAllocN = 0;
+        p->chN = 0;
+        p->done_fl = true;
+        return rc;
+      }
+
+      template< typename sample_t, typename srate_t >
+      rc_t setup( struct obj_str<sample_t,srate_t>* p, const struct multi_ch_wt_seq_str<sample_t,srate_t>* mcs )
+      {
+        rc_t rc = kOkRC;
+        
+        if( mcs->chN > p->chAllocN )
+        {
+          rc = cwLogError(kInvalidArgRC,"Invalid multi-ch-wt-osc channel count. (%i > %i)",mcs->chN,p->chAllocN);
+          goto errLabel;
+        }
+
+        
+        p->mcs = mcs;
+        p->done_fl = false;
+        p->chN = mcs->chN;
+        for(unsigned i=0; i<mcs->chN; ++i)
+          if((rc = wt_seq_osc::init(p->chA+i,mcs->chA + i)) != kOkRC )
+            goto errLabel;
+
+      errLabel:
+        if( rc != kOkRC )
+          rc = cwLogError(rc,"multi-ch-wt-osc setup failed.");
+        
+        return rc;
+      }
+
+      template< typename sample_t, typename srate_t >
+      rc_t is_done( struct obj_str<sample_t,srate_t>* p )
+      { return p->done_fl; }
+      
+      template< typename sample_t, typename srate_t >
+      rc_t process( struct obj_str<sample_t,srate_t>* p, sample_t* aM, unsigned chN, unsigned frmN, unsigned& actual_Ref )
+      {
+        rc_t     rc     = kOkRC;
+        unsigned actual = 0;
+        unsigned doneN  = 0;
+        
+        for(unsigned i=0; i<p->chN; ++i)
+        {
+          unsigned actual0 = 0;
+          sample_t* aV = aM + (i*frmN);
+          
+          if( !wt_seq_osc::is_init(p->chA + i) )
+          {
+            vop::zero(aV,frmN);
+            actual0 = frmN;
+            doneN += 1;
+          }
+          else
+          {
+            if((rc = wt_seq_osc::process(p->chA + i, aV, frmN, actual0 )) != kOkRC )
+              goto errLabel;
+          }
+          
+          if( i!=0 && actual0 != actual )
+          {
+            rc = cwLogError(kInvalidStateRC,"An inconsistent sample count was generated across channels (%i != !i).",actual0,actual);
+            goto errLabel;
+          }
+
+          actual = actual0;
+        }
+
+        actual_Ref = actual;
+        p->done_fl = doneN == p->chN;
+        
+      errLabel:
+        if( rc != kOkRC )
+          rc = cwLogError(rc,"multi-ch-wt-osc process failed.");
+        
+        return rc;
+      }
+
+      rc_t test();
+      
+    } //multi_ch_wt_seq_osc
+
+    
+    rc_t test( const test::test_args_t& args );
     
   } // dsp
 } // cw