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空挺団の「シンセサイザー」カテゴリーを参照してください。初回は「ドッグフードを食べる」です。

Committer:
shorie
Date:
Sat Feb 04 15:03:41 2017 +0000
Revision:
20:53021b2c424d
Child:
21:dcfbe6d2a6d3
Added SV Filter

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shorie 20:53021b2c424d 1 #include "signal_processing.h"
shorie 20:53021b2c424d 2
shorie 20:53021b2c424d 3 //---------------------------------------------------------------------------
shorie 20:53021b2c424d 4 // Reference
shorie 20:53021b2c424d 5 // stanford edu "CCRMA Digital State Variable Filters"
shorie 20:53021b2c424d 6 // https://ccrma.stanford.edu/~jos/svf/
shorie 20:53021b2c424d 7 // musicdsp "State Variable"
shorie 20:53021b2c424d 8 // http://musicdsp.org/archive.php?classid=3#23
shorie 20:53021b2c424d 9 //---------------------------------------------------------------------------
shorie 20:53021b2c424d 10
shorie 20:53021b2c424d 11 // State Variable Filter
shorie 20:53021b2c424d 12 // The f * f_factor must be < Fs/6.
shorie 20:53021b2c424d 13 SVFilter::SVFilter( uint32_t blockSize ) : amakusa::AbstractFilter ( blockSize )
shorie 20:53021b2c424d 14 {
shorie 20:53021b2c424d 15 this->fc = 440;
shorie 20:53021b2c424d 16 this->f_factor = 1.0f;
shorie 20:53021b2c424d 17 this->set_Fs( SAMPLING_FREQUENCY );
shorie 20:53021b2c424d 18 this->set_Q( 1.414f );
shorie 20:53021b2c424d 19 this->set_mode( lpf );
shorie 20:53021b2c424d 20
shorie 20:53021b2c424d 21 this->d1 = 0.0f;
shorie 20:53021b2c424d 22 this->d2 = 0.0f;
shorie 20:53021b2c424d 23 }
shorie 20:53021b2c424d 24
shorie 20:53021b2c424d 25 /************************************************************************
shorie 20:53021b2c424d 26 * +--------------------------------------> hp
shorie 20:53021b2c424d 27 * |
shorie 20:53021b2c424d 28 * | +--------------------> bp
shorie 20:53021b2c424d 29 * | f D1 | f
shorie 20:53021b2c424d 30 * x(n)->(+)-+-|>-(+)->[z^-1]->+-|>->(+)--------+---> lp
shorie 20:53021b2c424d 31 * A | | | |
shorie 20:53021b2c424d 32 * | +<----------+ +<-[z^-1]-+
shorie 20:53021b2c424d 33 * | -q | D2 |
shorie 20:53021b2c424d 34 * (+)<------<|----------+ |
shorie 20:53021b2c424d 35 * | -1 |
shorie 20:53021b2c424d 36 * +<-----------------<|-----------------+
shorie 20:53021b2c424d 37 *
shorie 20:53021b2c424d 38 * bp = D1
shorie 20:53021b2c424d 39 * lp = D1 * f + D2
shorie 20:53021b2c424d 40 * hp = x - q * bp - lp
shorie 20:53021b2c424d 41 *
shorie 20:53021b2c424d 42 * D1 = hp * f + D1
shorie 20:53021b2c424d 43 * D2 = lp
shorie 20:53021b2c424d 44 *
shorie 20:53021b2c424d 45 ************************************************************************/
shorie 20:53021b2c424d 46 void SVFilter::run( float32_t *pSrc, float32_t *pDst, uint32_t blockSize )
shorie 20:53021b2c424d 47 {
shorie 20:53021b2c424d 48 float32_t bp, lp, hp;
shorie 20:53021b2c424d 49
shorie 20:53021b2c424d 50 blockSize = blockSize ? blockSize : this->blockSize;
shorie 20:53021b2c424d 51
shorie 20:53021b2c424d 52 for ( int i= 0; i<blockSize; i++ )
shorie 20:53021b2c424d 53 {
shorie 20:53021b2c424d 54 bp = this->d1;
shorie 20:53021b2c424d 55 lp = bp * this->f + this->d2;
shorie 20:53021b2c424d 56 hp = pSrc[i] - this->q * bp - lp;
shorie 20:53021b2c424d 57
shorie 20:53021b2c424d 58 this->d1 += hp * this->f;
shorie 20:53021b2c424d 59 this->d2 = lp;
shorie 20:53021b2c424d 60 }
shorie 20:53021b2c424d 61 }
shorie 20:53021b2c424d 62
shorie 20:53021b2c424d 63
shorie 20:53021b2c424d 64 void SVFilter::set_Q( float32_t Q )
shorie 20:53021b2c424d 65 {
shorie 20:53021b2c424d 66 if ( Q < 0.1f )
shorie 20:53021b2c424d 67 Q = 0.1f;
shorie 20:53021b2c424d 68
shorie 20:53021b2c424d 69 this->q = 1.0f/Q;
shorie 20:53021b2c424d 70 }
shorie 20:53021b2c424d 71
shorie 20:53021b2c424d 72
shorie 20:53021b2c424d 73 void SVFilter::set_Fs( int new_Fs ) // Hz
shorie 20:53021b2c424d 74 {
shorie 20:53021b2c424d 75 this->Fs = new_Fs;
shorie 20:53021b2c424d 76 this->update_parameters();
shorie 20:53021b2c424d 77 }
shorie 20:53021b2c424d 78
shorie 20:53021b2c424d 79 void SVFilter::set_fc( int new_fc ) // Hz
shorie 20:53021b2c424d 80 {
shorie 20:53021b2c424d 81 this->fc = new_fc;
shorie 20:53021b2c424d 82 this->f = 2.0f * sin( 3.141592f * this->fc / this->Fs );
shorie 20:53021b2c424d 83 }
shorie 20:53021b2c424d 84
shorie 20:53021b2c424d 85
shorie 20:53021b2c424d 86 void SVFilter::set_f_factor( float32_t new_f_factor )
shorie 20:53021b2c424d 87 {
shorie 20:53021b2c424d 88 this->f_factor = new_f_factor;
shorie 20:53021b2c424d 89 this->f = 2.0f * sin( 3.141592f * this->fc / this->Fs );
shorie 20:53021b2c424d 90 }
shorie 20:53021b2c424d 91
shorie 20:53021b2c424d 92 void SVFilter::set_mode( svf_mode new_mode )
shorie 20:53021b2c424d 93 {
shorie 20:53021b2c424d 94 this->mode = new_mode;
shorie 20:53021b2c424d 95 }
shorie 20:53021b2c424d 96
shorie 20:53021b2c424d 97
shorie 20:53021b2c424d 98 void SVFilter::update_parameters( void )
shorie 20:53021b2c424d 99 {
shorie 20:53021b2c424d 100 this->f = 2.0f * sin( 3.141592f * this->fc * this->f_factor / this->Fs );
shorie 20:53021b2c424d 101 }