Synthesizer based on the Unzen / Nucleo F746ZG

Dependencies:   amakusa mbed-dsp mbed shimabara ukifune unzen_nucleo_f746

Fork of skeleton_unzen_nucleo_f746 by seiichi horie

雲仙フレームワークのテストとして作っているプロジェクトです。中身はどんどん変っていきます。 説明はDSP空挺団の「シンセサイザー」カテゴリーを参照してください。初回は「ドッグフードを食べる」です。

Revision:
20:53021b2c424d
Child:
21:dcfbe6d2a6d3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/svfilter.cpp	Sat Feb 04 15:03:41 2017 +0000
@@ -0,0 +1,101 @@
+#include "signal_processing.h"
+
+//---------------------------------------------------------------------------
+// Reference
+// stanford edu "CCRMA Digital State Variable Filters"
+//  https://ccrma.stanford.edu/~jos/svf/
+// musicdsp "State Variable"
+//  http://musicdsp.org/archive.php?classid=3#23
+//---------------------------------------------------------------------------
+
+    // State Variable Filter
+    // The f * f_factor must be < Fs/6.
+SVFilter::SVFilter( uint32_t blockSize ) : amakusa::AbstractFilter ( blockSize )
+{
+    this->fc = 440;
+    this->f_factor = 1.0f;
+    this->set_Fs( SAMPLING_FREQUENCY );
+    this->set_Q( 1.414f );
+    this->set_mode( lpf );
+    
+    this->d1 = 0.0f;
+    this->d2 = 0.0f;
+}
+ 
+/************************************************************************
+*           +--------------------------------------> hp
+*           |
+*           |                 +--------------------> bp
+*           |  f        D1    | f
+* x(n)->(+)-+-|>-(+)->[z^-1]->+-|>->(+)--------+---> lp
+*        A        |           |      |         |
+*        |        +<----------+      +<-[z^-1]-+
+*        |        -q          |          D2    |
+*       (+)<------<|----------+                |
+*        |                  -1                 |
+*        +<-----------------<|-----------------+
+*
+*    bp = D1
+*    lp = D1 * f + D2
+*    hp = x - q * bp - lp
+*
+*    D1 = hp * f + D1
+*    D2 = lp
+*    
+************************************************************************/    
+void SVFilter::run( float32_t *pSrc, float32_t *pDst, uint32_t blockSize  )
+{
+    float32_t bp, lp, hp;
+    
+    blockSize = blockSize ? blockSize : this->blockSize;
+    
+    for ( int i= 0; i<blockSize; i++ )
+    {
+        bp = this->d1;
+        lp = bp * this->f + this->d2;
+        hp = pSrc[i] - this->q * bp - lp;
+        
+        this->d1 += hp * this->f;
+        this->d2 = lp;
+    }
+}
+
+
+void SVFilter::set_Q( float32_t Q )
+{
+    if ( Q < 0.1f )
+        Q = 0.1f;
+        
+    this->q = 1.0f/Q;
+}
+
+
+void SVFilter::set_Fs( int new_Fs )              // Hz
+{
+    this->Fs = new_Fs;
+    this->update_parameters();
+}
+    
+void SVFilter::set_fc( int new_fc )                // Hz
+{
+    this->fc = new_fc;
+    this->f = 2.0f * sin( 3.141592f * this->fc / this->Fs );
+}
+
+
+void SVFilter::set_f_factor( float32_t new_f_factor )
+{
+    this->f_factor = new_f_factor;
+    this->f = 2.0f * sin( 3.141592f * this->fc / this->Fs );
+}
+
+void SVFilter::set_mode( svf_mode new_mode )
+{
+    this->mode = new_mode;
+}
+
+
+void SVFilter::update_parameters( void )
+{
+    this->f = 2.0f * sin( 3.141592f * this->fc * this->f_factor / this->Fs );
+}