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

svfilter.cpp

Committer:
shorie
Date:
2017-02-04
Revision:
21:dcfbe6d2a6d3
Parent:
20:53021b2c424d
Child:
22:dc2cbe8db9d9

File content as of revision 21:dcfbe6d2a6d3:

#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;
    
    if ( blockSize == 0 )
        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 );
}