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 11 07:15:21 2017 +0000
Revision:
27:fcb1f1da2ad7
Parent:
25:d15dd7b9101c
EG is integrated

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 27:fcb1f1da2ad7 13 SVFilter::SVFilter( uint32_t a_block_size ) : amakusa::AbstractFilter ( a_block_size )
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 25:d15dd7b9101c 46 void SVFilter::run( float32_t *pSrc, float32_t *pDst )
shorie 20:53021b2c424d 47 {
shorie 20:53021b2c424d 48 float32_t bp, lp, hp;
shorie 20:53021b2c424d 49
shorie 20:53021b2c424d 50
shorie 25:d15dd7b9101c 51 for ( int i= 0; i<this->block_size; i++ )
shorie 20:53021b2c424d 52 {
shorie 22:dc2cbe8db9d9 53 // calc the filter
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 22:dc2cbe8db9d9 58 // update delay
shorie 20:53021b2c424d 59 this->d1 += hp * this->f;
shorie 20:53021b2c424d 60 this->d2 = lp;
shorie 22:dc2cbe8db9d9 61
shorie 22:dc2cbe8db9d9 62 // mode dependent output
shorie 22:dc2cbe8db9d9 63 switch ( this->mode )
shorie 22:dc2cbe8db9d9 64 {
shorie 22:dc2cbe8db9d9 65 case lpf :
shorie 22:dc2cbe8db9d9 66 pDst[i] = lp;
shorie 22:dc2cbe8db9d9 67 break;
shorie 22:dc2cbe8db9d9 68 case hpf :
shorie 22:dc2cbe8db9d9 69 pDst[i] = hp;
shorie 22:dc2cbe8db9d9 70 break;
shorie 22:dc2cbe8db9d9 71 case bpf :
shorie 22:dc2cbe8db9d9 72 pDst[i] = bp;
shorie 22:dc2cbe8db9d9 73 break;
shorie 22:dc2cbe8db9d9 74 };
shorie 20:53021b2c424d 75 }
shorie 20:53021b2c424d 76 }
shorie 20:53021b2c424d 77
shorie 22:dc2cbe8db9d9 78 // Q can be [0.1,inf]
shorie 20:53021b2c424d 79 void SVFilter::set_Q( float32_t Q )
shorie 20:53021b2c424d 80 {
shorie 20:53021b2c424d 81 if ( Q < 0.1f )
shorie 20:53021b2c424d 82 Q = 0.1f;
shorie 20:53021b2c424d 83
shorie 20:53021b2c424d 84 this->q = 1.0f/Q;
shorie 20:53021b2c424d 85 }
shorie 20:53021b2c424d 86
shorie 20:53021b2c424d 87
shorie 20:53021b2c424d 88 void SVFilter::set_Fs( int new_Fs ) // Hz
shorie 20:53021b2c424d 89 {
shorie 20:53021b2c424d 90 this->Fs = new_Fs;
shorie 20:53021b2c424d 91 this->update_parameters();
shorie 20:53021b2c424d 92 }
shorie 22:dc2cbe8db9d9 93
shorie 22:dc2cbe8db9d9 94 // fc is control frequency.
shorie 20:53021b2c424d 95 void SVFilter::set_fc( int new_fc ) // Hz
shorie 20:53021b2c424d 96 {
shorie 20:53021b2c424d 97 this->fc = new_fc;
shorie 22:dc2cbe8db9d9 98 this->update_parameters();
shorie 20:53021b2c424d 99 }
shorie 20:53021b2c424d 100
shorie 22:dc2cbe8db9d9 101 // fc * f_factor must be less then Fs/6
shorie 20:53021b2c424d 102 void SVFilter::set_f_factor( float32_t new_f_factor )
shorie 20:53021b2c424d 103 {
shorie 20:53021b2c424d 104 this->f_factor = new_f_factor;
shorie 22:dc2cbe8db9d9 105 this->update_parameters();
shorie 20:53021b2c424d 106 }
shorie 20:53021b2c424d 107
shorie 20:53021b2c424d 108 void SVFilter::set_mode( svf_mode new_mode )
shorie 20:53021b2c424d 109 {
shorie 20:53021b2c424d 110 this->mode = new_mode;
shorie 20:53021b2c424d 111 }
shorie 20:53021b2c424d 112
shorie 20:53021b2c424d 113
shorie 20:53021b2c424d 114 void SVFilter::update_parameters( void )
shorie 20:53021b2c424d 115 {
shorie 20:53021b2c424d 116 this->f = 2.0f * sin( 3.141592f * this->fc * this->f_factor / this->Fs );
shorie 20:53021b2c424d 117 }