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@3:1b420050bdda, 2017-01-21 (annotated)
- Committer:
- shorie
- Date:
- Sat Jan 21 07:17:14 2017 +0000
- Revision:
- 3:1b420050bdda
- Parent:
- 2:d5028a37f17b
- Child:
- 6:486b1cb03e61
Commit for test
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 | 0:a837eeab3ca6 | 3 | #include "unzen.h" // audio framework include file |
shorie | 1:98ddcbbe10ba | 4 | #include "umb_adau1361a.h" // audio codec contoler include file |
shorie | 3:1b420050bdda | 5 | #include "amakusa.h" // audio signal processing class library. |
shorie | 3:1b420050bdda | 6 | #include "ukifune.h" // UI board support routines |
shorie | 3:1b420050bdda | 7 | |
shorie | 3:1b420050bdda | 8 | #define BLOCKSIZE 1 |
shorie | 3:1b420050bdda | 9 | #define TAPS 200 |
shorie | 0:a837eeab3ca6 | 10 | |
shorie | 1:98ddcbbe10ba | 11 | #define CODEC_I2C_ADDR 0x38 // Address of the ADAU-1361A |
shorie | 2:d5028a37f17b | 12 | #define AD7999 (0x29<<1) |
shorie | 2:d5028a37f17b | 13 | #define ADCBUFSIZE 8 |
shorie | 2:d5028a37f17b | 14 | |
shorie | 3:1b420050bdda | 15 | |
shorie | 0:a837eeab3ca6 | 16 | DigitalOut myled1(LED1); |
shorie | 2:d5028a37f17b | 17 | float gain = 1.0; |
shorie | 0:a837eeab3ca6 | 18 | |
shorie | 3:1b420050bdda | 19 | amakusa::OSCSinCos *osc; |
shorie | 3:1b420050bdda | 20 | amakusa::FIRFilter *filter; |
shorie | 3:1b420050bdda | 21 | float coeff[TAPS]; |
shorie | 2:d5028a37f17b | 22 | |
shorie | 2:d5028a37f17b | 23 | void parse_adc( char * buf, int &ch, int &data ); |
shorie | 0:a837eeab3ca6 | 24 | |
shorie | 0:a837eeab3ca6 | 25 | // customer signal processing initialization call back. |
shorie | 0:a837eeab3ca6 | 26 | void init_callback( |
shorie | 0:a837eeab3ca6 | 27 | unsigned int block_size // block size [sample] |
shorie | 0:a837eeab3ca6 | 28 | ) |
shorie | 0:a837eeab3ca6 | 29 | { |
shorie | 0:a837eeab3ca6 | 30 | // place initialization code here |
shorie | 3:1b420050bdda | 31 | osc = new amakusa::OSCSinCos( 440.0, 48000, block_size ); // freq=440Hz, Fs=48kHz. |
shorie | 3:1b420050bdda | 32 | |
shorie | 3:1b420050bdda | 33 | filter = new amakusa::FIRFilter( TAPS, coeff, block_size ); // |
shorie | 0:a837eeab3ca6 | 34 | } |
shorie | 0:a837eeab3ca6 | 35 | |
shorie | 0:a837eeab3ca6 | 36 | |
shorie | 0:a837eeab3ca6 | 37 | // customer signal processing call back. |
shorie | 0:a837eeab3ca6 | 38 | void process_callback( |
shorie | 0:a837eeab3ca6 | 39 | float rx_left_buffer[], // array of the left input samples |
shorie | 0:a837eeab3ca6 | 40 | float rx_right_buffer[], // array of the right input samples |
shorie | 0:a837eeab3ca6 | 41 | float tx_left_buffer[], // place to write the left output samples |
shorie | 0:a837eeab3ca6 | 42 | float tx_right_buffer[], // place to write the left output samples |
shorie | 0:a837eeab3ca6 | 43 | unsigned int block_size // block size [sample] |
shorie | 0:a837eeab3ca6 | 44 | ) |
shorie | 0:a837eeab3ca6 | 45 | { |
shorie | 3:1b420050bdda | 46 | #if 0 |
shorie | 1:98ddcbbe10ba | 47 | // generate tone. |
shorie | 3:1b420050bdda | 48 | osc->run( tx_left_buffer ); |
shorie | 3:1b420050bdda | 49 | #elif 0 |
shorie | 3:1b420050bdda | 50 | filter->run( rx_left_buffer, tx_left_buffer ); |
shorie | 3:1b420050bdda | 51 | #else |
shorie | 3:1b420050bdda | 52 | for ( int i=0; i<block_size; i++) // for all sample |
shorie | 3:1b420050bdda | 53 | { |
shorie | 3:1b420050bdda | 54 | tx_right_buffer[i] = atan2( rx_right_buffer[i], rx_left_buffer[i] ); |
shorie | 3:1b420050bdda | 55 | |
shorie | 3:1b420050bdda | 56 | } |
shorie | 3:1b420050bdda | 57 | |
shorie | 3:1b420050bdda | 58 | #endif |
shorie | 1:98ddcbbe10ba | 59 | |
shorie | 1:98ddcbbe10ba | 60 | // copy left to right |
shorie | 0:a837eeab3ca6 | 61 | for ( int i=0; i<block_size; i++) // for all sample |
shorie | 0:a837eeab3ca6 | 62 | { |
shorie | 2:d5028a37f17b | 63 | tx_right_buffer[i] = tx_left_buffer[i] *= 0.5F * gain; |
shorie | 0:a837eeab3ca6 | 64 | |
shorie | 0:a837eeab3ca6 | 65 | } |
shorie | 0:a837eeab3ca6 | 66 | } |
shorie | 0:a837eeab3ca6 | 67 | |
shorie | 0:a837eeab3ca6 | 68 | |
shorie | 0:a837eeab3ca6 | 69 | |
shorie | 0:a837eeab3ca6 | 70 | int main() |
shorie | 0:a837eeab3ca6 | 71 | { |
shorie | 2:d5028a37f17b | 72 | char adcbuf[ADCBUFSIZE]; |
shorie | 2:d5028a37f17b | 73 | int dacch, dacdata; |
shorie | 2:d5028a37f17b | 74 | |
shorie | 0:a837eeab3ca6 | 75 | // I2C is essential to talk with ADAU1361 |
shorie | 0:a837eeab3ca6 | 76 | I2C i2c(D14, D15); |
shorie | 0:a837eeab3ca6 | 77 | |
shorie | 0:a837eeab3ca6 | 78 | // create an audio codec contoler |
shorie | 1:98ddcbbe10ba | 79 | shimabara::UMB_ADAU1361A codec(shimabara::Fs_48, i2c, CODEC_I2C_ADDR ); // Fs can be Fs_32, Fs_441, Fs_48, Fs_96 |
shorie | 0:a837eeab3ca6 | 80 | |
shorie | 0:a837eeab3ca6 | 81 | // create an audio framework by singlton pattern |
shorie | 0:a837eeab3ca6 | 82 | unzen::Framework audio; |
shorie | 0:a837eeab3ca6 | 83 | |
shorie | 0:a837eeab3ca6 | 84 | // Set I3C clock to 100kHz |
shorie | 0:a837eeab3ca6 | 85 | i2c.frequency( 100000 ); |
shorie | 0:a837eeab3ca6 | 86 | |
shorie | 0:a837eeab3ca6 | 87 | |
shorie | 0:a837eeab3ca6 | 88 | // Configure the optional block size of signal processing. By default, it is 1[Sample] |
shorie | 0:a837eeab3ca6 | 89 | // audio.set_block_size(16); |
shorie | 0:a837eeab3ca6 | 90 | |
shorie | 0:a837eeab3ca6 | 91 | |
shorie | 0:a837eeab3ca6 | 92 | // Start the ADAU1361. Audio codec starts to generate the I2C signals |
shorie | 0:a837eeab3ca6 | 93 | codec.start(); |
shorie | 0:a837eeab3ca6 | 94 | |
shorie | 3:1b420050bdda | 95 | ukifune::init( & audio ); |
shorie | 3:1b420050bdda | 96 | |
shorie | 3:1b420050bdda | 97 | audio.set_block_size(BLOCKSIZE); |
shorie | 3:1b420050bdda | 98 | |
shorie | 0:a837eeab3ca6 | 99 | // Start the audio framework on ARM processor. |
shorie | 0:a837eeab3ca6 | 100 | audio.start( init_callback, process_callback); // path the initializaiton and process call back to framework |
shorie | 0:a837eeab3ca6 | 101 | |
shorie | 1:98ddcbbe10ba | 102 | codec.set_hp_output_gain( -3, -3 ); |
shorie | 1:98ddcbbe10ba | 103 | codec.set_line_output_gain( -3, -3 ); |
shorie | 0:a837eeab3ca6 | 104 | |
shorie | 0:a837eeab3ca6 | 105 | // periodically changing gain for test |
shorie | 0:a837eeab3ca6 | 106 | while(1) |
shorie | 0:a837eeab3ca6 | 107 | { |
shorie | 2:d5028a37f17b | 108 | |
shorie | 2:d5028a37f17b | 109 | i2c.read( AD7999, adcbuf, ADCBUFSIZE); |
shorie | 2:d5028a37f17b | 110 | parse_adc( &adcbuf[0],dacch, dacdata ); |
shorie | 2:d5028a37f17b | 111 | gain = dacdata / 255.0; |
shorie | 1:98ddcbbe10ba | 112 | /* |
shorie | 1:98ddcbbe10ba | 113 | myled1 = 1; |
shorie | 1:98ddcbbe10ba | 114 | wait(0.2); |
shorie | 1:98ddcbbe10ba | 115 | myled1 = 0; |
shorie | 1:98ddcbbe10ba | 116 | wait(0.2); |
shorie | 1:98ddcbbe10ba | 117 | */ |
shorie | 0:a837eeab3ca6 | 118 | } |
shorie | 2:d5028a37f17b | 119 | } |
shorie | 2:d5028a37f17b | 120 | |
shorie | 2:d5028a37f17b | 121 | void parse_adc( char * buf, int &ch, int &data ) |
shorie | 2:d5028a37f17b | 122 | { |
shorie | 2:d5028a37f17b | 123 | ch = ( buf[0] & 0x30 ) >> 4; |
shorie | 2:d5028a37f17b | 124 | data = |
shorie | 2:d5028a37f17b | 125 | ( buf[0] & 0x0F ) << 4 | |
shorie | 2:d5028a37f17b | 126 | ( buf[1] & 0xF0 ) >> 4; |
shorie | 2:d5028a37f17b | 127 | |
shorie | 0:a837eeab3ca6 | 128 | } |