Synthesizer based on the Unzen / Nucleo F746ZG
Dependencies: amakusa mbed-dsp mbed shimabara ukifune unzen_nucleo_f746
Fork of skeleton_unzen_nucleo_f746 by
雲仙フレームワークのテストとして作っているプロジェクトです。中身はどんどん変っていきます。 説明はDSP空挺団の「シンセサイザー」カテゴリーを参照してください。初回は「ドッグフードを食べる」です。
main.cpp
- Committer:
- shorie
- Date:
- 2017-02-18
- Revision:
- 29:8ee84bda128c
- Parent:
- 28:547f19ed6f67
File content as of revision 29:8ee84bda128c:
#include "mbed.h" // Note : Do not touch the "unzen dependent" part. No need to read. // Modify the "project dependent" part. // Also, Modify the SignalProcessing class. /************************** unzen dependent constants. ************************/ #define CODEC_I2C_ADDR 0x38 // Address of the ADAU-1361A /*========================= Project Dependent Constants ======================*/ #define BLOCKSIZE 16 // number of the sample to be processed at once. #define FS shimabara::Fs_48 // Fs can be Fs_32, Fs_441, Fs_48, Fs_96 /************************** unzen dependent include. **************************/ #include "unzen.h" // audio framework include file #include "umb_adau1361a.h" // audio codec contoler include file #include "amakusa.h" // audio signal processing class library. #include "ukifune.h" // UI board support routines #include "signal_processing.h" // Implementaion of user signal processing. /************************* Unzen Dependent Global Variables *******************/ // I2C is essential to talk with ADAU1361 static I2C i2c(D14, D15); // create an audio codec contoler static shimabara::UMB_ADAU1361A codec(FS, i2c, CODEC_I2C_ADDR ); // create an audio framework by singlton pattern static unzen::Framework audio; // create a pointer to the signal processing object. static SignalProcessing * process; /************************* Unzen Dependent Function Prototype *****************/ // for system usage. Do not care. void initialize_system(void); /*========================= Main program. ====================================*/ #define KEYCTRL( SWITCH, FREQ )\ if ( pushing & ( 1 << ukifune::SWITCH ) )\ {\ process->set_vfo_frequency(FREQ);\ process->eg_on();\ }\ else if ( releasing & ( 1 << ukifune::SWITCH ) )\ process->eg_off(); int main() { uint32_t pushing, releasing, holding; // VFO form wave_form form = triangle; // filter mode svf_mode filter_mode = lpf; // start audio. Do not touch initialize_system(); // set tentative frequency process->set_vfo_frequency( 440 ); // set wave from process->set_vfo_wave_form( form ); ukifune::turn_led_on( ukifune::led1_1 ); ukifune::turn_led_off( ukifune::led1_2 ); // set filter mode process->set_filter_mode( filter_mode ); ukifune::turn_led_on( ukifune::led2_1 ); ukifune::turn_led_off( ukifune::led2_2 ); ukifune::turn_led_off( ukifune::led2_3 ); ukifune::turn_led_off( ukifune::led2_4 ); // 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_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); // pushing detection demo // waveform if ( pushing & (1 << ukifune::swm1 ) ) // is SWM1 switch pusshing down? if ( form == triangle ) { form = square; process->set_vfo_wave_form( form ); ukifune::turn_led_off( ukifune::led1_1 ); ukifune::turn_led_on( ukifune::led1_2 ); } else { form = triangle; process->set_vfo_wave_form( form ); ukifune::turn_led_on( ukifune::led1_1 ); ukifune::turn_led_off( ukifune::led1_2 ); } // filter mode if ( pushing & (1 << ukifune::swm2 ) ) // is SWM2 switch pusshing down? if ( filter_mode == lpf ) { filter_mode = bpf; process->set_filter_mode( filter_mode ); ukifune::turn_led_off( ukifune::led2_1 ); ukifune::turn_led_on( ukifune::led2_2 ); ukifune::turn_led_off( ukifune::led2_3 ); ukifune::turn_led_off( ukifune::led2_4 ); } else if ( filter_mode == bpf ) { filter_mode = hpf; process->set_filter_mode( filter_mode ); ukifune::turn_led_off( ukifune::led2_1 ); ukifune::turn_led_off( ukifune::led2_2 ); ukifune::turn_led_on( ukifune::led2_3 ); ukifune::turn_led_off( ukifune::led2_4 ); } else // hpf { filter_mode = lpf; process->set_filter_mode( filter_mode ); ukifune::turn_led_on( ukifune::led2_1 ); ukifune::turn_led_off( ukifune::led2_2 ); ukifune::turn_led_off( ukifune::led2_3 ); ukifune::turn_led_off( ukifune::led2_4 ); } // Key board control KEYCTRL( swk1, 261.626 ) KEYCTRL( swk2, 277.183 ) KEYCTRL( swk3, 293.665 ) KEYCTRL( swk4, 311.123 ) KEYCTRL( swk5, 329.628 ) KEYCTRL( swk6, 349.228 ) KEYCTRL( swk7, 369.994 ) KEYCTRL( swk8, 391.995 ) KEYCTRL( swk9, 415.305 ) KEYCTRL( swk10, 440.000 ) KEYCTRL( swk11, 466.164 ) KEYCTRL( swk12, 498.883 ) KEYCTRL( swk13, 523.251 ) // you have to call tick() every 20mS-50mS if you need get_volume() wait(0.05); ukifune::tick(); } } // End of main /************************* Unzen Dependent Callbacks **************************/ // customer signal processing initialization call back. void init_callback( unsigned int block_size // block size [sample] ) { // place initialization code here process = new SignalProcessing( block_size ); } // end of init_callback // customer signal processing call back. void process_callback( float rx_left_buffer[], // array of the left input samples float rx_right_buffer[], // array of the right input samples float tx_left_buffer[], // place to write the left output samples float tx_right_buffer[], // place to write the right output samples unsigned int block_size // block size [sample] ) { // place signal processing code here process->run( rx_left_buffer, rx_right_buffer, tx_left_buffer, tx_right_buffer, block_size ); } // End of process_callback /************************* Unzen Dependent Function implementation ************/ void initialize_system(void) { // Set I3C clock to 100kHz i2c.frequency( 100000 ); // Configure the optional block size of signal processing. By default, it is 1[Sample] audio.set_block_size(BLOCKSIZE); // Start UI module. ukifune::init( & audio ); // Start the ADAU1361. Audio codec starts to generate the I2C signals codec.start(); // Start the audio framework on ARM processor. audio.start( init_callback, process_callback); // path the initializaiton and process call back to framework // Setup initial analog gain codec.set_hp_output_gain( 0, 0 ); codec.set_line_output_gain( 0, 0 ); }