Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: amakusa mbed-dsp mbed shimabara ukifune unzen_nucleo_f746
Fork of skeleton_unzen_nucleo_f746 by
Revision 26:e99f71165e19, committed 2017-02-10
- Comitter:
- shorie
- Date:
- Fri Feb 10 21:31:17 2017 +0000
- Parent:
- 25:d15dd7b9101c
- Child:
- 27:fcb1f1da2ad7
- Commit message:
- fulfill change
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/eg.cpp Fri Feb 10 21:31:17 2017 +0000
@@ -0,0 +1,69 @@
+#include "signal_processing.h"
+
+EG::EG ( int32_t block_size )
+{
+ this->block_size = block_size;
+
+ this->state = release;
+ this->set_sustain( 0.0f );
+ this->current_level = 0.0f;
+ this->set_attack( 0.999 );
+ this->set_decay( 0.999 );
+ this->set_release( 0.999 );
+
+}
+
+void EG::run( float32_t *pEnvelope )
+{
+ if ( this->state == release )
+ for ( int i= 0; i< this->block_size; i++ )
+ pEnvelope[i] = this->current_level =
+ this->current_level * this->release_time_constant;
+ else if ( this->state == decay )
+ for ( int i= 0; i< this->block_size; i++ )
+ pEnvelope[i] = this->current_level =
+ ( this->current_level - this->sustain_level ) * this->decay_time_constant
+ + this->sustain_level;
+ else // attack
+ {
+ for ( int i= 0; i< this->block_size; i++ )
+ pEnvelope[i] = this->current_level =
+ 1.5f -
+ ( 1.5f - this->current_level ) * this->attack_time_constant;
+ if ( this->current_level >= 1.0f )
+ this->state = decay;
+ }
+
+}
+
+void EG::on(void)
+{
+ this->state = attack;
+}
+
+void EG::off(void)
+{
+ this->state = release;
+}
+
+void EG::set_sustain( float32_t sustain )
+{
+ this->sustain_level = sustain;
+}
+
+void EG::set_attack( float32_t attack )
+{
+ this->attack_time_constant = 1.0f - attack * 0.01f;
+}
+
+void EG::set_decay( float32_t decay )
+{
+ this->decay_time_constant = 1.0f - decay * 0.01f;
+}
+
+void EG::set_release( float32_t release )
+{
+ this->release_time_constant = 1.0f - release * 0.01f;
+}
+
+
--- a/main.cpp Fri Feb 10 13:28:41 2017 +0000
+++ b/main.cpp Fri Feb 10 21:31:17 2017 +0000
@@ -77,6 +77,10 @@
process->set_vfo_duty_cycle( ukifune::get_volume(1) );
process->set_filter_f_factor( ukifune::get_volume(2) );
process->set_filter_Q( ukifune::get_volume(3) );
+ process->set_eg_attack( ukifune::get_volume(4) ); // A
+ process->set_eg_decay( ukifune::get_volume(5) ); // D
+ process->set_eg_sustain( ukifune::get_volume(6) ); // S
+ process->set_eg_release( ukifune::get_volume(7) ); // R
// sample usage of button switch detection
ukifune::get_button_state( pushing, releasing, holding);
@@ -130,6 +134,11 @@
}
+ if ( pushing & ( 1 << ukifune::swk1 ) )
+ process->eg_on();
+ else if ( releasing & ( 1 << ukifune::swk1 ) )
+ process->eg_off();
+
// you have to call tick() every 20mS-50mS if you need get_volume()
wait(0.05);
--- a/monophonic.cpp Fri Feb 10 13:28:41 2017 +0000
+++ b/monophonic.cpp Fri Feb 10 21:31:17 2017 +0000
@@ -5,12 +5,15 @@
Monophonic::Monophonic( unsigned int block_size )
{
// initializing the subm-odules.
- this->vfo = new VFO(); // allocate VFO
+ this->vfo = new VFO(block_size); // allocate VFO
this->dc_blocker = new DCBlocker( block_size );
this->sv_filter = new SVFilter( block_size );
+// this->eg = new EG( block_size );
work_buf_a = new float32_t[block_size];
work_buf_b = new float32_t[block_size];
+
+ this->block_size = block_size;
} // End of constructor()
Monophonic::~Monophonic( void )
@@ -19,6 +22,7 @@
delete this->vfo;
delete this->dc_blocker;
delete this->sv_filter;
+// delete this->eg;
delete[] work_buf_a;
delete[] work_buf_b;
@@ -28,12 +32,11 @@
// Run all signal processing.
void Monophonic::run(
- float out_buffer[], // place to write the right output samples
- unsigned int block_size // block size [sample]
+ float out_buffer[] // place to write the right output samples
)
{
// place the signal processing coce here
- this->vfo->run( work_buf_a, block_size );
+ this->vfo->run( work_buf_a );
// blocking DC.
this->dc_blocker->run( work_buf_a, work_buf_b );
@@ -41,6 +44,13 @@
// applying filter.
this->sv_filter->run( work_buf_b, out_buffer );
+ // generate envelope
+// this->eg->run( work_buf_a );
+
+ // apply envelope
+// for ( int i= 0; i< this->block_size; i++ )
+// out_buffer[ i ] *= work_buf_a[ i ];
+
} // End of run()
@@ -82,8 +92,40 @@
this->sv_filter->set_Q( Q );
}
- // Set the f_factor value.
+ // Set the f_factor value.
void Monophonic::set_filter_f_factor( float f_factor )
{
this->sv_filter->set_f_factor( f_factor );
}
+
+ // Turn note on
+void Monophonic::eg_on(void)
+{
+// this->eg->on();
+}
+
+ // Turn note off
+void Monophonic::eg_off(void)
+{
+// this->eg->off();
+}
+
+void Monophonic::set_eg_attack( float32_t attack )
+{
+// this->eg->set_attack( attack );
+}
+void Monophonic::set_eg_decay( float32_t decay )
+{
+// this->eg->set_decay( decay );
+}
+
+void Monophonic::set_eg_sustain( float32_t sustain )
+{
+// this->eg->set_sustain( sustain );
+}
+
+void Monophonic::set_eg_release ( float32_t release )
+{
+// this->eg->set_release( release );
+}
+
--- a/signal_processing.cpp Fri Feb 10 13:28:41 2017 +0000
+++ b/signal_processing.cpp Fri Feb 10 21:31:17 2017 +0000
@@ -25,7 +25,7 @@
// place the signal processing coce here
// VFO
- this->note->run( tx_left_buffer, block_size);
+ this->note->run( tx_left_buffer);
// apply gain and copy to right ch.
for ( int i= 0; i< block_size; i++ )
@@ -111,6 +111,51 @@
this->leave_critical_section(); // now, ok to accept interrupt.
}
+void SignalProcessing::eg_on(void)
+{
+ this->enter_critical_section(); // forbidden interrrupt.
+ this->note->eg_on();
+ this->leave_critical_section(); // now, ok to accept interrupt.
+}
+
+void SignalProcessing::eg_off(void)
+{
+ this->enter_critical_section(); // forbidden interrrupt.
+ this->note->eg_off();
+ this->leave_critical_section(); // now, ok to accept interrupt.
+}
+
+void SignalProcessing::set_eg_attack( float32_t attack )
+{
+ this->enter_critical_section(); // forbidden interrrupt.
+ this->note->set_eg_attack( attack );
+ this->leave_critical_section(); // now, ok to accept interrupt.
+}
+
+void SignalProcessing::set_eg_decay( float32_t decay )
+{
+ this->enter_critical_section(); // forbidden interrrupt.
+ this->note->set_eg_decay( decay );
+ this->leave_critical_section(); // now, ok to accept interrupt.
+}
+
+void SignalProcessing::set_eg_sustain( float32_t sustain ) // [0,1.0]
+{
+ this->enter_critical_section(); // forbidden interrrupt.
+ this->note->set_eg_sustain( sustain );
+ this->leave_critical_section(); // now, ok to accept interrupt.
+}
+
+void SignalProcessing::set_eg_release ( float32_t release ) // [0,1.0]
+{
+ this->enter_critical_section(); // forbidden interrrupt.
+ this->note->set_eg_release( release );
+ this->leave_critical_section(); // now, ok to accept interrupt.
+}
+
+
+
+
/************************** skeleton dependent methond. ***********************/
// essential members. Do not touch.
void SignalProcessing::enter_critical_section(void)
--- a/signal_processing.h Fri Feb 10 13:28:41 2017 +0000
+++ b/signal_processing.h Fri Feb 10 21:31:17 2017 +0000
@@ -7,15 +7,15 @@
enum wave_form { triangle, square };
enum svf_mode { lpf, hpf, bpf };
+enum eg_state { release, attack, decay };
// Variable Frequency Oscillator. Only square and triangle
class VFO {
public:
- VFO( void );
- virtual ~VFO(void);
+ VFO( int32_t block_size );
+ virtual ~VFO();
void run(
- float out_buffer[], // place to write the right output samples
- unsigned int block_size // block size [sample]
+ float out_buffer[] // place to write the right output samples
);
// parameter settings
@@ -24,6 +24,7 @@
void set_duty_cycle( float duty ); // 0 ... 0.5
void set_wave_form( wave_form form );
private:
+ int32_t block_size;
// control variables.
int frequency; // VFO frequency [Hz]
@@ -72,14 +73,30 @@
void update_parameters( void );
};
+class EG {
+public:
+ EG ( int32_t block_size );
+ virtual void run( float32_t *pEnvelope );
+ void on(void);
+ void off(void);
+ void set_attack( float32_t attack ); // [0,1.0]
+ void set_decay( float32_t attack ); // [0,1.0]
+ void set_sustain( float32_t sustain ); // [0,1.0]
+ void set_release ( float32_t attack ); // [0,1.0]
+private:
+ float32_t current_level, sustain_level;
+ float32_t attack_time_constant, decay_time_constant, release_time_constant;
+ eg_state state;
+ int32_t block_size;
+};
+
// 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 = 0 // block size [sample]
+ float out_buffer[] // place to write the right output samples
);
void set_Fs( int Fs ); // unit is Hz.
void set_vfo_frequency( int freq ); // unit is Hz.
@@ -88,11 +105,19 @@
void set_filter_mode( svf_mode mode );
void set_filter_Q( float Q ); // 0.5 .. inf
void set_filter_f_factor( float f_factor ); // 0.0..1.0
+ void eg_on(void);
+ void eg_off(void);
+ void set_eg_attack( float32_t attack ); // [0,1.0]
+ void set_eg_decay( float32_t decay ); // [0,1.0]
+ void set_eg_sustain( float32_t sustain ); // [0,1.0]
+ void set_eg_release ( float32_t release ); // [0,1.0]
private:
VFO *vfo;
DCBlocker *dc_blocker;
SVFilter *sv_filter;
+ EG *eg;
float32_t *work_buf_a, *work_buf_b;
+ int32_t block_size;
};
@@ -118,6 +143,12 @@
void set_filter_mode( svf_mode mode );
void set_filter_Q( float Q ); // 0.0..1.0
void set_filter_f_factor( float f_factor ); // 0.0..1.0
+ void eg_on(void);
+ void eg_off(void);
+ void set_eg_attack( float32_t attack ); // [0,1.0]
+ void set_eg_decay( float32_t decay ); // [0,1.0]
+ void set_eg_sustain( float32_t sustain ); // [0,1.0]
+ void set_eg_release ( float32_t release ); // [0,1.0]
private:
// essential members. Do not touch.
void enter_critical_section(void);
--- a/vfo.cpp Fri Feb 10 13:28:41 2017 +0000
+++ b/vfo.cpp Fri Feb 10 21:31:17 2017 +0000
@@ -1,9 +1,11 @@
#include "signal_processing.h"
-VFO::VFO( void )
+VFO::VFO( int32_t block_size )
{
// initial parameter setting.
+ this->block_size = block_size;
+
this->form = triangle;
this->Fs = 48000;
this->frequency = 440;
@@ -20,13 +22,12 @@
void VFO::run(
- float out_buffer[], // vfo output buffer
- unsigned int block_size // block size [sample]
+ float out_buffer[] // vfo output buffer
)
{
// place the signal processing coce here
- for ( int i= 0; i< block_size; i++ )
+ for ( int i= 0; i< this->block_size; i++ )
{
// 1 : if phase < half_way; 0 : others.
if ( this->form == square )
