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