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:44:56 2017 +0000
Revision:
28:547f19ed6f67
Parent:
26:e99f71165e19
13 tone is ready to play

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shorie 14:cec63d8da48c 1 #include "signal_processing.h"
shorie 14:cec63d8da48c 2
shorie 18:b9b1116f8768 3
shorie 26:e99f71165e19 4 VFO::VFO( int32_t block_size )
shorie 14:cec63d8da48c 5 {
shorie 14:cec63d8da48c 6 // initial parameter setting.
shorie 26:e99f71165e19 7 this->block_size = block_size;
shorie 26:e99f71165e19 8
shorie 18:b9b1116f8768 9 this->form = triangle;
shorie 14:cec63d8da48c 10 this->Fs = 48000;
shorie 14:cec63d8da48c 11 this->frequency = 440;
shorie 14:cec63d8da48c 12 this->duty_cycle = 0.5;
shorie 16:d4ea3e6a0bce 13
shorie 16:d4ea3e6a0bce 14 this->update_parameters();
shorie 14:cec63d8da48c 15 } // End of constructor()
shorie 18:b9b1116f8768 16
shorie 18:b9b1116f8768 17 VFO::~VFO( void )
shorie 18:b9b1116f8768 18 {
shorie 18:b9b1116f8768 19 // do nothing
shorie 18:b9b1116f8768 20 }
shorie 14:cec63d8da48c 21
shorie 14:cec63d8da48c 22
shorie 18:b9b1116f8768 23
shorie 14:cec63d8da48c 24 void VFO::run(
shorie 26:e99f71165e19 25 float out_buffer[] // vfo output buffer
shorie 14:cec63d8da48c 26 )
shorie 14:cec63d8da48c 27 {
shorie 22:dc2cbe8db9d9 28
shorie 14:cec63d8da48c 29 // place the signal processing coce here
shorie 26:e99f71165e19 30 for ( int i= 0; i< this->block_size; i++ )
shorie 14:cec63d8da48c 31 {
shorie 15:de22b9d147e0 32 // 1 : if phase < half_way; 0 : others.
shorie 18:b9b1116f8768 33 if ( this->form == square )
shorie 15:de22b9d147e0 34 {
shorie 15:de22b9d147e0 35 if ( this->current_phase < this->half_way )
shorie 16:d4ea3e6a0bce 36 out_buffer[i] = 1.0;
shorie 15:de22b9d147e0 37 else
shorie 15:de22b9d147e0 38 out_buffer[i] = 0.0;
shorie 15:de22b9d147e0 39 }
shorie 18:b9b1116f8768 40 else // form == triangle
shorie 16:d4ea3e6a0bce 41 {
shorie 16:d4ea3e6a0bce 42 if ( this->current_phase < this->half_way )
shorie 16:d4ea3e6a0bce 43 out_buffer[i] = this->rising_rate * this->current_phase;
shorie 16:d4ea3e6a0bce 44 else
shorie 16:d4ea3e6a0bce 45 out_buffer[i] = 1 + this->falling_rate * ( this->current_phase - this->half_way );
shorie 16:d4ea3e6a0bce 46 }
shorie 15:de22b9d147e0 47
shorie 15:de22b9d147e0 48 // update phase
shorie 15:de22b9d147e0 49 this->current_phase += this->frequency;
shorie 15:de22b9d147e0 50 // limit the range of the phase.
shorie 15:de22b9d147e0 51 if ( this->current_phase >= this->Fs )
shorie 15:de22b9d147e0 52 this->current_phase -= this->Fs;
shorie 14:cec63d8da48c 53 }
shorie 14:cec63d8da48c 54 } // End of run()
shorie 14:cec63d8da48c 55
shorie 14:cec63d8da48c 56
shorie 14:cec63d8da48c 57 void VFO::set_Fs( int Fs )
shorie 14:cec63d8da48c 58 {
shorie 14:cec63d8da48c 59 // regulate the Fs.
shorie 14:cec63d8da48c 60 if ( Fs != 32000 && Fs != 44100 && Fs != 96000 && Fs != 48000 )
shorie 14:cec63d8da48c 61 Fs = 48000;
shorie 14:cec63d8da48c 62 this->Fs = Fs;
shorie 16:d4ea3e6a0bce 63
shorie 16:d4ea3e6a0bce 64 this->update_parameters();
shorie 14:cec63d8da48c 65 }
shorie 14:cec63d8da48c 66
shorie 28:547f19ed6f67 67 void VFO::set_frequency( float freq )
shorie 14:cec63d8da48c 68 {
shorie 14:cec63d8da48c 69 if ( freq > this->Fs / 4 )
shorie 16:d4ea3e6a0bce 70 freq = Fs / 4;
shorie 14:cec63d8da48c 71 this->frequency = freq;
shorie 16:d4ea3e6a0bce 72
shorie 16:d4ea3e6a0bce 73 this->update_parameters();
shorie 14:cec63d8da48c 74 }
shorie 14:cec63d8da48c 75
shorie 14:cec63d8da48c 76 void VFO::set_duty_cycle( float duty )
shorie 14:cec63d8da48c 77 {
shorie 14:cec63d8da48c 78 if ( duty > 0.5f ) // high limit
shorie 14:cec63d8da48c 79 duty = 0.5f;
shorie 17:728ffc633179 80 if ( duty < 0.0f ) // low limit
shorie 17:728ffc633179 81 duty = 0.0f;
shorie 14:cec63d8da48c 82 this->duty_cycle = duty;
shorie 16:d4ea3e6a0bce 83
shorie 16:d4ea3e6a0bce 84 this->update_parameters();
shorie 14:cec63d8da48c 85 }
shorie 14:cec63d8da48c 86
shorie 18:b9b1116f8768 87 void VFO::set_wave_form( wave_form form )
shorie 14:cec63d8da48c 88 {
shorie 18:b9b1116f8768 89 this->form = form;
shorie 14:cec63d8da48c 90 }
shorie 14:cec63d8da48c 91
shorie 14:cec63d8da48c 92
shorie 16:d4ea3e6a0bce 93 // update the internal parameter by given parameters
shorie 16:d4ea3e6a0bce 94 void VFO::update_parameters(void)
shorie 16:d4ea3e6a0bce 95 {
shorie 16:d4ea3e6a0bce 96 // calc the half_way;
shorie 17:728ffc633179 97 this-> half_way = this->Fs * this-> duty_cycle;
shorie 24:c77331e72374 98
shorie 24:c77331e72374 99 // make it integer multiple of frequency
shorie 28:547f19ed6f67 100 this->half_way = (int)(this->half_way/this->frequency);
shorie 24:c77331e72374 101 this->half_way *= this->frequency;
shorie 16:d4ea3e6a0bce 102
shorie 16:d4ea3e6a0bce 103 // forbid to be zero.
shorie 16:d4ea3e6a0bce 104 if ( this-> half_way < this->frequency )
shorie 24:c77331e72374 105 this->half_way = this->frequency;
shorie 16:d4ea3e6a0bce 106
shorie 16:d4ea3e6a0bce 107 // for triangle wave;
shorie 16:d4ea3e6a0bce 108 this->rising_rate = 1.0 / this->half_way;
shorie 16:d4ea3e6a0bce 109
shorie 16:d4ea3e6a0bce 110 this->falling_rate = - 1.0 / ( this->Fs - this->half_way );
shorie 16:d4ea3e6a0bce 111 }
shorie 16:d4ea3e6a0bce 112