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@29:8ee84bda128c, 2017-02-18 (annotated)
- Committer:
- shorie
- Date:
- Sat Feb 18 04:37:19 2017 +0000
- Revision:
- 29:8ee84bda128c
- Parent:
- 28:547f19ed6f67
Limiter function is confirmed. SV filter ignored bug was fixed.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
shorie | 1:98ddcbbe10ba | 1 | #include "mbed.h" |
shorie | 1:98ddcbbe10ba | 2 | |
shorie | 9:7f521a0b397c | 3 | // Note : Do not touch the "unzen dependent" part. No need to read. |
shorie | 9:7f521a0b397c | 4 | // Modify the "project dependent" part. |
shorie | 9:7f521a0b397c | 5 | // Also, Modify the SignalProcessing class. |
shorie | 6:486b1cb03e61 | 6 | |
shorie | 6:486b1cb03e61 | 7 | |
shorie | 6:486b1cb03e61 | 8 | /************************** unzen dependent constants. ************************/ |
shorie | 6:486b1cb03e61 | 9 | #define CODEC_I2C_ADDR 0x38 // Address of the ADAU-1361A |
shorie | 6:486b1cb03e61 | 10 | |
shorie | 6:486b1cb03e61 | 11 | |
shorie | 6:486b1cb03e61 | 12 | /*========================= Project Dependent Constants ======================*/ |
shorie | 6:486b1cb03e61 | 13 | #define BLOCKSIZE 16 // number of the sample to be processed at once. |
shorie | 6:486b1cb03e61 | 14 | #define FS shimabara::Fs_48 // Fs can be Fs_32, Fs_441, Fs_48, Fs_96 |
shorie | 6:486b1cb03e61 | 15 | |
shorie | 6:486b1cb03e61 | 16 | |
shorie | 6:486b1cb03e61 | 17 | /************************** unzen dependent include. **************************/ |
shorie | 0:a837eeab3ca6 | 18 | #include "unzen.h" // audio framework include file |
shorie | 1:98ddcbbe10ba | 19 | #include "umb_adau1361a.h" // audio codec contoler include file |
shorie | 3:1b420050bdda | 20 | #include "amakusa.h" // audio signal processing class library. |
shorie | 8:d8d1776e865b | 21 | #include "ukifune.h" // UI board support routines |
shorie | 8:d8d1776e865b | 22 | #include "signal_processing.h" // Implementaion of user signal processing. |
shorie | 2:d5028a37f17b | 23 | |
shorie | 3:1b420050bdda | 24 | |
shorie | 6:486b1cb03e61 | 25 | /************************* Unzen Dependent Global Variables *******************/ |
shorie | 6:486b1cb03e61 | 26 | // I2C is essential to talk with ADAU1361 |
shorie | 8:d8d1776e865b | 27 | static I2C i2c(D14, D15); |
shorie | 6:486b1cb03e61 | 28 | // create an audio codec contoler |
shorie | 8:d8d1776e865b | 29 | static shimabara::UMB_ADAU1361A codec(FS, i2c, CODEC_I2C_ADDR ); |
shorie | 6:486b1cb03e61 | 30 | // create an audio framework by singlton pattern |
shorie | 8:d8d1776e865b | 31 | static unzen::Framework audio; |
shorie | 6:486b1cb03e61 | 32 | // create a pointer to the signal processing object. |
shorie | 8:d8d1776e865b | 33 | static SignalProcessing * process; |
shorie | 6:486b1cb03e61 | 34 | |
shorie | 6:486b1cb03e61 | 35 | |
shorie | 6:486b1cb03e61 | 36 | /************************* Unzen Dependent Function Prototype *****************/ |
shorie | 6:486b1cb03e61 | 37 | // for system usage. Do not care. |
shorie | 6:486b1cb03e61 | 38 | void initialize_system(void); |
shorie | 0:a837eeab3ca6 | 39 | |
shorie | 2:d5028a37f17b | 40 | |
shorie | 7:e86c645231ff | 41 | /*========================= Main program. ====================================*/ |
shorie | 28:547f19ed6f67 | 42 | #define KEYCTRL( SWITCH, FREQ )\ |
shorie | 28:547f19ed6f67 | 43 | if ( pushing & ( 1 << ukifune::SWITCH ) )\ |
shorie | 28:547f19ed6f67 | 44 | {\ |
shorie | 28:547f19ed6f67 | 45 | process->set_vfo_frequency(FREQ);\ |
shorie | 28:547f19ed6f67 | 46 | process->eg_on();\ |
shorie | 28:547f19ed6f67 | 47 | }\ |
shorie | 28:547f19ed6f67 | 48 | else if ( releasing & ( 1 << ukifune::SWITCH ) )\ |
shorie | 28:547f19ed6f67 | 49 | process->eg_off(); |
shorie | 28:547f19ed6f67 | 50 | |
shorie | 0:a837eeab3ca6 | 51 | int main() |
shorie | 0:a837eeab3ca6 | 52 | { |
shorie | 11:7d8740437e6a | 53 | uint32_t pushing, releasing, holding; |
shorie | 17:728ffc633179 | 54 | |
shorie | 18:b9b1116f8768 | 55 | // VFO form |
shorie | 18:b9b1116f8768 | 56 | wave_form form = triangle; |
shorie | 22:dc2cbe8db9d9 | 57 | |
shorie | 22:dc2cbe8db9d9 | 58 | // filter mode |
shorie | 22:dc2cbe8db9d9 | 59 | svf_mode filter_mode = lpf; |
shorie | 11:7d8740437e6a | 60 | |
shorie | 6:486b1cb03e61 | 61 | // start audio. Do not touch |
shorie | 6:486b1cb03e61 | 62 | initialize_system(); |
shorie | 22:dc2cbe8db9d9 | 63 | |
shorie | 22:dc2cbe8db9d9 | 64 | // set tentative frequency |
shorie | 22:dc2cbe8db9d9 | 65 | process->set_vfo_frequency( 440 ); |
shorie | 17:728ffc633179 | 66 | |
shorie | 22:dc2cbe8db9d9 | 67 | // set wave from |
shorie | 18:b9b1116f8768 | 68 | process->set_vfo_wave_form( form ); |
shorie | 22:dc2cbe8db9d9 | 69 | ukifune::turn_led_on( ukifune::led1_1 ); |
shorie | 22:dc2cbe8db9d9 | 70 | ukifune::turn_led_off( ukifune::led1_2 ); |
shorie | 22:dc2cbe8db9d9 | 71 | |
shorie | 22:dc2cbe8db9d9 | 72 | // set filter mode |
shorie | 22:dc2cbe8db9d9 | 73 | process->set_filter_mode( filter_mode ); |
shorie | 22:dc2cbe8db9d9 | 74 | ukifune::turn_led_on( ukifune::led2_1 ); |
shorie | 22:dc2cbe8db9d9 | 75 | ukifune::turn_led_off( ukifune::led2_2 ); |
shorie | 22:dc2cbe8db9d9 | 76 | ukifune::turn_led_off( ukifune::led2_3 ); |
shorie | 22:dc2cbe8db9d9 | 77 | ukifune::turn_led_off( ukifune::led2_4 ); |
shorie | 22:dc2cbe8db9d9 | 78 | |
shorie | 0:a837eeab3ca6 | 79 | |
shorie | 6:486b1cb03e61 | 80 | // main loop. Signal processing is done in background. |
shorie | 6:486b1cb03e61 | 81 | while(1) |
shorie | 6:486b1cb03e61 | 82 | { // place your foreground program here. |
shorie | 12:2b121255e2d1 | 83 | |
shorie | 12:2b121255e2d1 | 84 | // get volume from UI panel, then apply it to signal processing. |
shorie | 17:728ffc633179 | 85 | process->set_volume( ukifune::get_volume(0) ); |
shorie | 17:728ffc633179 | 86 | process->set_vfo_duty_cycle( ukifune::get_volume(1) ); |
shorie | 22:dc2cbe8db9d9 | 87 | process->set_filter_f_factor( ukifune::get_volume(2) ); |
shorie | 22:dc2cbe8db9d9 | 88 | process->set_filter_Q( ukifune::get_volume(3) ); |
shorie | 26:e99f71165e19 | 89 | process->set_eg_attack( ukifune::get_volume(4) ); // A |
shorie | 26:e99f71165e19 | 90 | process->set_eg_decay( ukifune::get_volume(5) ); // D |
shorie | 26:e99f71165e19 | 91 | process->set_eg_sustain( ukifune::get_volume(6) ); // S |
shorie | 26:e99f71165e19 | 92 | process->set_eg_release( ukifune::get_volume(7) ); // R |
shorie | 2:d5028a37f17b | 93 | |
shorie | 11:7d8740437e6a | 94 | // sample usage of button switch detection |
shorie | 11:7d8740437e6a | 95 | ukifune::get_button_state( pushing, releasing, holding); |
shorie | 11:7d8740437e6a | 96 | |
shorie | 11:7d8740437e6a | 97 | // pushing detection demo |
shorie | 22:dc2cbe8db9d9 | 98 | // waveform |
shorie | 11:7d8740437e6a | 99 | if ( pushing & (1 << ukifune::swm1 ) ) // is SWM1 switch pusshing down? |
shorie | 18:b9b1116f8768 | 100 | if ( form == triangle ) |
shorie | 17:728ffc633179 | 101 | { |
shorie | 18:b9b1116f8768 | 102 | form = square; |
shorie | 18:b9b1116f8768 | 103 | process->set_vfo_wave_form( form ); |
shorie | 22:dc2cbe8db9d9 | 104 | ukifune::turn_led_off( ukifune::led1_1 ); |
shorie | 22:dc2cbe8db9d9 | 105 | ukifune::turn_led_on( ukifune::led1_2 ); |
shorie | 17:728ffc633179 | 106 | } |
shorie | 17:728ffc633179 | 107 | else |
shorie | 17:728ffc633179 | 108 | { |
shorie | 18:b9b1116f8768 | 109 | form = triangle; |
shorie | 18:b9b1116f8768 | 110 | process->set_vfo_wave_form( form ); |
shorie | 22:dc2cbe8db9d9 | 111 | ukifune::turn_led_on( ukifune::led1_1 ); |
shorie | 22:dc2cbe8db9d9 | 112 | ukifune::turn_led_off( ukifune::led1_2 ); |
shorie | 17:728ffc633179 | 113 | } |
shorie | 17:728ffc633179 | 114 | |
shorie | 22:dc2cbe8db9d9 | 115 | // filter mode |
shorie | 22:dc2cbe8db9d9 | 116 | if ( pushing & (1 << ukifune::swm2 ) ) // is SWM2 switch pusshing down? |
shorie | 22:dc2cbe8db9d9 | 117 | if ( filter_mode == lpf ) |
shorie | 22:dc2cbe8db9d9 | 118 | { |
shorie | 22:dc2cbe8db9d9 | 119 | filter_mode = bpf; |
shorie | 22:dc2cbe8db9d9 | 120 | process->set_filter_mode( filter_mode ); |
shorie | 22:dc2cbe8db9d9 | 121 | ukifune::turn_led_off( ukifune::led2_1 ); |
shorie | 22:dc2cbe8db9d9 | 122 | ukifune::turn_led_on( ukifune::led2_2 ); |
shorie | 22:dc2cbe8db9d9 | 123 | ukifune::turn_led_off( ukifune::led2_3 ); |
shorie | 22:dc2cbe8db9d9 | 124 | ukifune::turn_led_off( ukifune::led2_4 ); |
shorie | 22:dc2cbe8db9d9 | 125 | } |
shorie | 22:dc2cbe8db9d9 | 126 | else if ( filter_mode == bpf ) |
shorie | 22:dc2cbe8db9d9 | 127 | { |
shorie | 22:dc2cbe8db9d9 | 128 | filter_mode = hpf; |
shorie | 22:dc2cbe8db9d9 | 129 | process->set_filter_mode( filter_mode ); |
shorie | 22:dc2cbe8db9d9 | 130 | ukifune::turn_led_off( ukifune::led2_1 ); |
shorie | 22:dc2cbe8db9d9 | 131 | ukifune::turn_led_off( ukifune::led2_2 ); |
shorie | 22:dc2cbe8db9d9 | 132 | ukifune::turn_led_on( ukifune::led2_3 ); |
shorie | 22:dc2cbe8db9d9 | 133 | ukifune::turn_led_off( ukifune::led2_4 ); |
shorie | 22:dc2cbe8db9d9 | 134 | } |
shorie | 22:dc2cbe8db9d9 | 135 | else // hpf |
shorie | 22:dc2cbe8db9d9 | 136 | { |
shorie | 22:dc2cbe8db9d9 | 137 | filter_mode = lpf; |
shorie | 22:dc2cbe8db9d9 | 138 | process->set_filter_mode( filter_mode ); |
shorie | 22:dc2cbe8db9d9 | 139 | ukifune::turn_led_on( ukifune::led2_1 ); |
shorie | 22:dc2cbe8db9d9 | 140 | ukifune::turn_led_off( ukifune::led2_2 ); |
shorie | 22:dc2cbe8db9d9 | 141 | ukifune::turn_led_off( ukifune::led2_3 ); |
shorie | 22:dc2cbe8db9d9 | 142 | ukifune::turn_led_off( ukifune::led2_4 ); |
shorie | 22:dc2cbe8db9d9 | 143 | } |
shorie | 11:7d8740437e6a | 144 | |
shorie | 11:7d8740437e6a | 145 | |
shorie | 28:547f19ed6f67 | 146 | // Key board control |
shorie | 28:547f19ed6f67 | 147 | KEYCTRL( swk1, 261.626 ) |
shorie | 28:547f19ed6f67 | 148 | KEYCTRL( swk2, 277.183 ) |
shorie | 28:547f19ed6f67 | 149 | KEYCTRL( swk3, 293.665 ) |
shorie | 28:547f19ed6f67 | 150 | KEYCTRL( swk4, 311.123 ) |
shorie | 28:547f19ed6f67 | 151 | KEYCTRL( swk5, 329.628 ) |
shorie | 28:547f19ed6f67 | 152 | KEYCTRL( swk6, 349.228 ) |
shorie | 28:547f19ed6f67 | 153 | KEYCTRL( swk7, 369.994 ) |
shorie | 28:547f19ed6f67 | 154 | KEYCTRL( swk8, 391.995 ) |
shorie | 28:547f19ed6f67 | 155 | KEYCTRL( swk9, 415.305 ) |
shorie | 28:547f19ed6f67 | 156 | KEYCTRL( swk10, 440.000 ) |
shorie | 28:547f19ed6f67 | 157 | KEYCTRL( swk11, 466.164 ) |
shorie | 28:547f19ed6f67 | 158 | KEYCTRL( swk12, 498.883 ) |
shorie | 28:547f19ed6f67 | 159 | KEYCTRL( swk13, 523.251 ) |
shorie | 26:e99f71165e19 | 160 | |
shorie | 11:7d8740437e6a | 161 | |
shorie | 6:486b1cb03e61 | 162 | // you have to call tick() every 20mS-50mS if you need get_volume() |
shorie | 6:486b1cb03e61 | 163 | wait(0.05); |
shorie | 6:486b1cb03e61 | 164 | ukifune::tick(); |
shorie | 6:486b1cb03e61 | 165 | } |
shorie | 7:e86c645231ff | 166 | } // End of main |
shorie | 7:e86c645231ff | 167 | |
shorie | 7:e86c645231ff | 168 | |
shorie | 8:d8d1776e865b | 169 | /************************* Unzen Dependent Callbacks **************************/ |
shorie | 7:e86c645231ff | 170 | // customer signal processing initialization call back. |
shorie | 7:e86c645231ff | 171 | void init_callback( |
shorie | 7:e86c645231ff | 172 | unsigned int block_size // block size [sample] |
shorie | 7:e86c645231ff | 173 | ) |
shorie | 7:e86c645231ff | 174 | { |
shorie | 7:e86c645231ff | 175 | // place initialization code here |
shorie | 7:e86c645231ff | 176 | process = new SignalProcessing( block_size ); |
shorie | 7:e86c645231ff | 177 | } // end of init_callback |
shorie | 7:e86c645231ff | 178 | |
shorie | 7:e86c645231ff | 179 | |
shorie | 7:e86c645231ff | 180 | // customer signal processing call back. |
shorie | 7:e86c645231ff | 181 | void process_callback( |
shorie | 7:e86c645231ff | 182 | float rx_left_buffer[], // array of the left input samples |
shorie | 7:e86c645231ff | 183 | float rx_right_buffer[], // array of the right input samples |
shorie | 7:e86c645231ff | 184 | float tx_left_buffer[], // place to write the left output samples |
shorie | 13:b33cb5925113 | 185 | float tx_right_buffer[], // place to write the right output samples |
shorie | 7:e86c645231ff | 186 | unsigned int block_size // block size [sample] |
shorie | 7:e86c645231ff | 187 | ) |
shorie | 7:e86c645231ff | 188 | { |
shorie | 7:e86c645231ff | 189 | // place signal processing code here |
shorie | 7:e86c645231ff | 190 | process->run( rx_left_buffer, rx_right_buffer, tx_left_buffer, tx_right_buffer, block_size ); |
shorie | 7:e86c645231ff | 191 | } // End of process_callback |
shorie | 2:d5028a37f17b | 192 | |
shorie | 6:486b1cb03e61 | 193 | |
shorie | 6:486b1cb03e61 | 194 | /************************* Unzen Dependent Function implementation ************/ |
shorie | 6:486b1cb03e61 | 195 | void initialize_system(void) |
shorie | 2:d5028a37f17b | 196 | { |
shorie | 6:486b1cb03e61 | 197 | // Set I3C clock to 100kHz |
shorie | 6:486b1cb03e61 | 198 | i2c.frequency( 100000 ); |
shorie | 6:486b1cb03e61 | 199 | |
shorie | 6:486b1cb03e61 | 200 | // Configure the optional block size of signal processing. By default, it is 1[Sample] |
shorie | 6:486b1cb03e61 | 201 | audio.set_block_size(BLOCKSIZE); |
shorie | 6:486b1cb03e61 | 202 | |
shorie | 6:486b1cb03e61 | 203 | // Start UI module. |
shorie | 6:486b1cb03e61 | 204 | ukifune::init( & audio ); |
shorie | 6:486b1cb03e61 | 205 | |
shorie | 6:486b1cb03e61 | 206 | // Start the ADAU1361. Audio codec starts to generate the I2C signals |
shorie | 6:486b1cb03e61 | 207 | codec.start(); |
shorie | 6:486b1cb03e61 | 208 | // Start the audio framework on ARM processor. |
shorie | 6:486b1cb03e61 | 209 | audio.start( init_callback, process_callback); // path the initializaiton and process call back to framework |
shorie | 6:486b1cb03e61 | 210 | |
shorie | 6:486b1cb03e61 | 211 | // Setup initial analog gain |
shorie | 6:486b1cb03e61 | 212 | codec.set_hp_output_gain( 0, 0 ); |
shorie | 6:486b1cb03e61 | 213 | codec.set_line_output_gain( 0, 0 ); |
shorie | 6:486b1cb03e61 | 214 | } |