Synthesizer based on the Unzen / Nucleo F746ZG
Dependencies: amakusa mbed-dsp mbed shimabara ukifune unzen_nucleo_f746
Fork of skeleton_unzen_nucleo_f746 by
雲仙フレームワークのテストとして作っているプロジェクトです。中身はどんどん変っていきます。 説明はDSP空挺団の「シンセサイザー」カテゴリーを参照してください。初回は「ドッグフードを食べる」です。
Diff: svfilter.cpp
- 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 ); +}