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

vfo.cpp

Committer:
shorie
Date:
2017-02-18
Revision:
29:8ee84bda128c
Parent:
28:547f19ed6f67

File content as of revision 29:8ee84bda128c:

#include "signal_processing.h"


VFO::VFO( int32_t block_size )
{
        // initial parameter setting.
    this->block_size = block_size;
    
    this->form = triangle;
    this->Fs = 48000;
    this->frequency = 440;
    this->duty_cycle = 0.5;
    
    this->update_parameters();
}   // End of constructor()

VFO::~VFO( void )
{
    // do nothing
}
    
    

void VFO::run(           
            float out_buffer[]         // vfo output buffer
           )
{
        
        // place the signal processing coce here
    for ( int i= 0; i< this->block_size; i++ )
    {
            // 1 : if phase < half_way; 0 : others.
        if ( this->form == square ) 
        {
            if ( this->current_phase < this->half_way )
                out_buffer[i] = 1.0;
            else
                out_buffer[i] = 0.0;
        }
        else    // form == triangle
        {
            if ( this->current_phase < this->half_way )
                out_buffer[i] = this->rising_rate * this->current_phase;
            else
                out_buffer[i] = 1 + this->falling_rate * ( this->current_phase - this->half_way );
        }
        
            // update phase
        this->current_phase += this->frequency;
            // limit the range of the phase.
        if ( this->current_phase >= this->Fs )
            this->current_phase -= this->Fs;
    }
}   // End of run()
    

void VFO::set_Fs( int Fs )
{
        // regulate the Fs.
    if ( Fs != 32000 && Fs != 44100 && Fs != 96000 && Fs != 48000 )
        Fs = 48000;
    this->Fs = Fs;
    
    this->update_parameters();
}

void VFO::set_frequency( float freq )
{
    if ( freq > this->Fs / 4 )
        freq = Fs / 4;
    this->frequency = freq;
    
    this->update_parameters();
}

void VFO::set_duty_cycle( float duty )
{
    if ( duty > 0.5f )   // high limit
        duty = 0.5f;
    if ( duty < 0.0f )  // low limit
        duty = 0.0f;
    this->duty_cycle = duty;
    
    this->update_parameters();
}

void VFO::set_wave_form( wave_form form )
{
    this->form = form;
}


    // update the internal parameter by given parameters
void VFO::update_parameters(void)
{
        // calc the half_way;
    this-> half_way = this->Fs * this-> duty_cycle;
    
        // make it integer multiple of frequency
    this->half_way = (int)(this->half_way/this->frequency);
    this->half_way *= this->frequency;

        // forbid to be zero.
    if ( this-> half_way < this->frequency )
        this->half_way = this->frequency;              
        
        // for triangle wave;
    this->rising_rate = 1.0 / this->half_way;
    
    this->falling_rate = - 1.0 / ( this->Fs - this->half_way ); 
}