Experimental implementation of the adaptive filter of "Interface" magazine in 2016-2017
Dependencies: amakusa mbed-dsp mbed shimabara ukifune unzen_nucleo_f746
Fork of skeleton_unzen_nucleo_f746 by
ハードウェアおよびソフトウェアはskelton_unzen_nucleo_f746を基本にしています。
Revision 20:699e209fd19a, committed 2017-02-03
- Comitter:
- shorie
- Date:
- Fri Feb 03 14:41:40 2017 +0000
- Parent:
- 19:f5e785fe50b1
- Commit message:
- Rewind the faulty commit.
Changed in this revision
--- a/dcblocker.cpp Fri Feb 03 14:35:46 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -#include "signal_processing.h" - -/* -* Related Link -* https://www.dsprelated.com/freebooks/filters/DC_Blocker.html -* https://ccrma.stanford.edu/~jos/fp/DC_Blocker.html -*/ - -DCBlocker::DCBlocker( uint32_t blockSize ) : amakusa::AbstractFilter ( blockSize ) -{ - this->x_last = 0; - this->y_last = 0; -} - -void DCBlocker::run( float32_t *pSrc, float32_t *pDst, uint32_t blockSize ) -{ - // if the parameter is non-zero, take it. If the parameter is zero, use default. - if ( blockSize == 0 ) - blockSize = this->blockSize; - - for ( int i = 0; i < blockSize; i++ ) - { - // y = x - x * z^-1 + 0.995 * y * z^-1 - pDst[ i ] = pSrc[ i ] - this->x_last + 0.995f * this->y_last; - this->x_last = pSrc[ i ]; - this->y_last = pDst[ i ]; - } - -}
--- a/main.cpp Fri Feb 03 14:35:46 2017 +0000 +++ b/main.cpp Fri Feb 03 14:41:40 2017 +0000 @@ -42,47 +42,33 @@ int main() { uint32_t pushing, releasing, holding; - - // VFO form - wave_form form = triangle; // start audio. Do not touch initialize_system(); - - process->set_vfo_frequency( 440 ); - process->set_vfo_wave_form( form ); - ukifune::turn_led_off( ukifune::led1_1 ); - ukifune::turn_led_on( ukifune::led1_2 ); // main loop. Signal processing is done in background. while(1) { // place your foreground program here. // get volume from UI panel, then apply it to signal processing. - process->set_volume( ukifune::get_volume(0) ); - process->set_vfo_duty_cycle( ukifune::get_volume(1) ); + process->set_volume( ukifune::get_volume(0) ); // sample usage of button switch detection ukifune::get_button_state( pushing, releasing, holding); // pushing detection demo if ( pushing & (1 << ukifune::swm1 ) ) // is SWM1 switch pusshing down? - if ( form == triangle ) - { - form = square; - process->set_vfo_wave_form( form ); - ukifune::turn_led_on( ukifune::led1_1 ); - ukifune::turn_led_off( ukifune::led1_2 ); - } - else - { - form = triangle; - process->set_vfo_wave_form( form ); - ukifune::turn_led_off( ukifune::led1_1 ); - ukifune::turn_led_on( ukifune::led1_2 ); - } - + ukifune::toggle_led( ukifune::led1_1 ); // then, toggle LED1_1 + // releasing detection demo + if ( releasing & (1 << ukifune::swm2 ) ) // is SWM2 switch releasing? + ukifune::toggle_led( ukifune::led2_1 ); // then toggle LED2_1 + + // holding detection demo + if ( holding & (1 << ukifune::swm3 ) ) // is SWM3 switch holding? + ukifune::turn_led_on( ukifune::led3_1 ); // then turn LED3_1 on + else + ukifune::turn_led_off( ukifune::led3_1 ); // else off // you have to call tick() every 20mS-50mS if you need get_volume()
--- a/monophonic.cpp Fri Feb 03 14:35:46 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -#include "signal_processing.h" - - - // constructor. -Monophonic::Monophonic( unsigned int block_size ) -{ - // initializing the subm-odules. - this->vfo = new VFO(); // allocate VFO -} // End of constructor() - -Monophonic::~Monophonic( void ) -{ - // initializing the subm-odules. - delete this->vfo; -} // End of constructor() - - - - // Run all signal processing. -void Monophonic::run( - float out_buffer[], // place to write the right output samples - unsigned int block_size // block size [sample] - ) -{ - // place the signal processing coce here - - // VFO - this->vfo->run( out_buffer, block_size); - -} // End of run() - - - // Sampling Frequency -void Monophonic::set_Fs( int Fs ) -{ - this->vfo->set_Fs( Fs ); -} - - // Oscillation Frequency -void Monophonic::set_vfo_frequency( int freq ) -{ - this->vfo->set_frequency( freq ); -} - - // Duty Cycle of VFO -void Monophonic::set_vfo_duty_cycle( float duty ) -{ - this->vfo->set_duty_cycle( duty ); -} - - // VFO wave form -void Monophonic::set_vfo_wave_form( wave_form form ) -{ - this->vfo->set_wave_form( form ); -}
--- a/signal_processing.cpp Fri Feb 03 14:35:46 2017 +0000 +++ b/signal_processing.cpp Fri Feb 03 14:41:40 2017 +0000 @@ -6,10 +6,6 @@ { // place the signal processing initializing code here. this->volume_level = 0.0; // sample initializaiton - this->note = new Monophonic(block_size); // allocate VFO - note->set_Fs( SAMPLING_FREQUENCY ); - note->set_vfo_frequency( 440 ); - note->set_vfo_wave_form( triangle ); } // End of constructor() @@ -23,52 +19,15 @@ ) { // place the signal processing coce here - - // VFO - this->note->run( tx_left_buffer, block_size); - - // apply gain and copy to right ch. for ( int i= 0; i< block_size; i++ ) { - tx_right_buffer[i] = tx_left_buffer[i] *= this->volume_level; + tx_left_buffer[i] = rx_left_buffer[i] * this->volume_level; + tx_right_buffer[i] = rx_right_buffer[i] * this->volume_level; } } // End of run() - - // Sampling Frequency -void SignalProcessing::set_Fs( int Fs ) -{ - this->enter_critical_section(); // forbidden interrrupt. - this->note->set_Fs( Fs ); - this->leave_critical_section(); // now, ok to accept interrupt. -} - - // Oscillation Frequency -void SignalProcessing::set_vfo_frequency( int freq ) -{ - this->enter_critical_section(); // forbidden interrrupt. - this->note->set_vfo_frequency( freq ); - this->leave_critical_section(); // now, ok to accept interrupt. -} - - // Duty Cycle of VFO -void SignalProcessing::set_vfo_duty_cycle( float duty ) -{ - this->enter_critical_section(); // forbidden interrrupt. - this->note->set_vfo_duty_cycle( duty ); - this->leave_critical_section(); // now, ok to accept interrupt. -} - - // VFO wave form -void SignalProcessing::set_vfo_wave_form( wave_form form ) -{ - this->enter_critical_section(); // forbidden interrrupt. - this->note->set_vfo_wave_form( form ); - this->leave_critical_section(); // now, ok to accept interrupt. -} - - // Set the volume level to the object. + // Sample method. Set the volume level to the object. void SignalProcessing::set_volume( float vol ) { this->enter_critical_section(); // forbidden interrrupt.
--- a/signal_processing.h Fri Feb 03 14:35:46 2017 +0000 +++ b/signal_processing.h Fri Feb 03 14:41:40 2017 +0000 @@ -3,70 +3,6 @@ #include "amakusa.h" -#define SAMPLING_FREQUENCY 48000 - -enum wave_form { triangle, square }; - - // Variable Frequency Oscillator. Only square and triangle -class VFO { -public: - VFO( void ); - virtual ~VFO(void); - void run( - float out_buffer[], // place to write the right output samples - unsigned int block_size // block size [sample] - ); - - // parameter settings - void set_frequency( int freq ); // unit is Hz. - void set_Fs( int Fs ); // unit is Hz. - void set_duty_cycle( float duty ); // 0 ... 0.5 - void set_wave_form( wave_form form ); -private: - - // control variables. - int frequency; // VFO frequency [Hz] - int Fs; // sampling Frequency [Hz] - float duty_cycle; // VFO duty cycle. 0 ... 0.5 - wave_form form; // form of the wave form. - - // internal variable. - int current_phase; // internal variable of VFO. - int half_way; // change point by duty cycle. ( period * duty_cycle ). - float rising_rate; - float falling_rate; - - void update_parameters(void); // call one of the parameter is changed. -}; - - // Blocking DC -class DCBlocker : public amakusa::AbstractFilter { -public: - DCBlocker( uint32_t blockSize ); - virtual void run( float32_t *pSrc, float32_t *pDst, uint32_t blockSize = 0 ); -private: - float x_last; - float y_last; -}; - - // Monophonic synthsizer class -class Monophonic { -public: - Monophonic( unsigned int block_size ); - virtual ~Monophonic(void); - void run( - float out_buffer[], // place to write the right output samples - unsigned int block_size // block size [sample] - ); - void set_Fs( int Fs ); // unit is Hz. - void set_vfo_frequency( int freq ); // unit is Hz. - void set_vfo_duty_cycle( float duty ); // 0 ... 0.5 - void set_vfo_wave_form( wave_form form ); -private: - VFO *vfo; -}; - - // User Signal processing Class class SignalProcessing { public: @@ -82,18 +18,13 @@ // project depenedent members. void set_volume( float vol ); - void set_Fs( int Fs ); // unit is Hz. - void set_vfo_frequency( int freq ); // unit is Hz. - void set_vfo_duty_cycle( float duty ); // 0 ... 0.5 - void set_vfo_wave_form( wave_form form ); private: // essential members. Do not touch. void enter_critical_section(void); void leave_critical_section(void); // project dependent members. - float volume_level; // 0 ... 1.0 - Monophonic * note; + float volume_level; }; #endif
--- a/vfo.cpp Fri Feb 03 14:35:46 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -#include "signal_processing.h" - - -VFO::VFO( void ) -{ - // initial parameter setting. - 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 - unsigned int block_size // block size [sample] - ) -{ - // place the signal processing coce here - for ( int i= 0; i< 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( int 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; - - // forbid to be zero. - if ( this-> half_way < this->frequency ) - 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 ); -} -