First Publish. Works fine.

Dependents:   unzen_sample_nucleo_f746 unzen_delay_sample_nucleo_f746 skeleton_unzen_nucleo_f746 ifmag_noise_canceller ... more

Nucleo F746ZG用のオーディオ・フレームワークです。フレームワーク地震の詳細は『雲仙』オーディオ・フレームワークを参照してください。

参考リンク

  • skeleton_unzen_nucleo_f746 Nucleo F746ZGおよびUI基板を使う場合のスケルトンプログラム。F746を使う方はここから読み始めると良いでしょう。
Committer:
shorie
Date:
Sun Jan 29 02:50:31 2017 +0000
Revision:
20:e995396b427b
Parent:
12:5e73a102d809
Update comment.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shorie 2:6613e62da521 1 #include "algorithm"
shorie 2:6613e62da521 2 #include "limits.h"
shorie 2:6613e62da521 3
shorie 0:5ac19c994288 4 #include "unzen.h"
shorie 0:5ac19c994288 5 #include "unzen_hal.h"
shorie 0:5ac19c994288 6
shorie 0:5ac19c994288 7 namespace unzen
shorie 0:5ac19c994288 8 {
shorie 11:5f91f55065c1 9 Framework::Framework()
shorie 0:5ac19c994288 10 {
shorie 12:5e73a102d809 11 // setup handle for the interrupt handler
shorie 12:5e73a102d809 12 Framework::_fw = this;
shorie 2:6613e62da521 13
shorie 2:6613e62da521 14 // Clear all buffers
shorie 10:45cbff9ee6e4 15 _tx_int_buffer[0] = NULL;
shorie 10:45cbff9ee6e4 16 _tx_int_buffer[1] = NULL;
shorie 10:45cbff9ee6e4 17 _rx_int_buffer[0] = NULL;
shorie 10:45cbff9ee6e4 18 _rx_int_buffer[1] = NULL;
shorie 0:5ac19c994288 19
shorie 10:45cbff9ee6e4 20 _tx_left_buffer = NULL;
shorie 10:45cbff9ee6e4 21 _tx_right_buffer = NULL;
shorie 10:45cbff9ee6e4 22 _rx_left_buffer = NULL;
shorie 10:45cbff9ee6e4 23 _rx_right_buffer = NULL;
shorie 0:5ac19c994288 24
shorie 2:6613e62da521 25 // Initialize all buffer
shorie 10:45cbff9ee6e4 26 _buffer_index = 0;
shorie 10:45cbff9ee6e4 27 _sample_index = 0;
shorie 0:5ac19c994288 28
shorie 2:6613e62da521 29 // Clear all callbacks
shorie 10:45cbff9ee6e4 30 _pre_interrupt_callback = NULL;
shorie 10:45cbff9ee6e4 31 _post_interrupt_callback = NULL;
shorie 10:45cbff9ee6e4 32 _pre_process_callback = NULL;
shorie 10:45cbff9ee6e4 33 _post_process_callback = NULL;
shorie 0:5ac19c994288 34
shorie 10:45cbff9ee6e4 35 _process_callback = NULL;
shorie 12:5e73a102d809 36
shorie 0:5ac19c994288 37
shorie 2:6613e62da521 38 // Initialy block(buffer) size is 1.
shorie 0:5ac19c994288 39 set_block_size( 1 );
shorie 0:5ac19c994288 40
shorie 2:6613e62da521 41 // Initialize I2S peripheral
shorie 0:5ac19c994288 42 hal_i2s_setup();
shorie 0:5ac19c994288 43
shorie 2:6613e62da521 44 // Setup the interrupt for the I2S
shorie 10:45cbff9ee6e4 45 NVIC_SetVector(hal_get_i2s_irq_id(), (uint32_t)_i2s_irq_handler);
shorie 2:6613e62da521 46 set_i2s_irq_priority(hal_get_i2s_irq_priority_level());
shorie 0:5ac19c994288 47 NVIC_EnableIRQ(hal_get_i2s_irq_id());
shorie 0:5ac19c994288 48
shorie 2:6613e62da521 49 // Setup the interrupt for the process
shorie 10:45cbff9ee6e4 50 NVIC_SetVector(hal_get_process_irq_id(), (uint32_t)_process_irq_handler);
shorie 2:6613e62da521 51 set_process_irq_priority(hal_get_process_irq_priority_level());
shorie 0:5ac19c994288 52 NVIC_EnableIRQ(hal_get_process_irq_id());
shorie 0:5ac19c994288 53
shorie 0:5ac19c994288 54 }
shorie 0:5ac19c994288 55
shorie 11:5f91f55065c1 56 error_type Framework::set_block_size( unsigned int new_block_size )
shorie 0:5ac19c994288 57 {
shorie 0:5ac19c994288 58
shorie 10:45cbff9ee6e4 59 delete [] _tx_int_buffer[0];
shorie 10:45cbff9ee6e4 60 delete [] _tx_int_buffer[1];
shorie 10:45cbff9ee6e4 61 delete [] _rx_int_buffer[0];
shorie 10:45cbff9ee6e4 62 delete [] _rx_int_buffer[1];
shorie 0:5ac19c994288 63
shorie 10:45cbff9ee6e4 64 delete [] _tx_left_buffer;
shorie 10:45cbff9ee6e4 65 delete [] _tx_right_buffer;
shorie 10:45cbff9ee6e4 66 delete [] _rx_left_buffer;
shorie 10:45cbff9ee6e4 67 delete [] _rx_right_buffer;
shorie 0:5ac19c994288 68
shorie 10:45cbff9ee6e4 69 _block_size = new_block_size;
shorie 0:5ac19c994288 70
shorie 10:45cbff9ee6e4 71 _tx_int_buffer[0] = new int[ 2 * _block_size ];
shorie 10:45cbff9ee6e4 72 _tx_int_buffer[1] = new int[ 2 * _block_size ];
shorie 10:45cbff9ee6e4 73 _rx_int_buffer[0] = new int[ 2 * _block_size ];
shorie 10:45cbff9ee6e4 74 _rx_int_buffer[1] = new int[ 2 * _block_size ];
shorie 0:5ac19c994288 75
shorie 10:45cbff9ee6e4 76 _tx_left_buffer = new float[ _block_size ];
shorie 10:45cbff9ee6e4 77 _tx_right_buffer = new float[ _block_size ];
shorie 10:45cbff9ee6e4 78 _rx_left_buffer = new float[ _block_size ];
shorie 10:45cbff9ee6e4 79 _rx_right_buffer = new float[ _block_size ];
shorie 0:5ac19c994288 80
shorie 0:5ac19c994288 81 // error check
shorie 10:45cbff9ee6e4 82 if ( _rx_int_buffer[0] == NULL |
shorie 10:45cbff9ee6e4 83 _rx_int_buffer[1] == NULL |
shorie 10:45cbff9ee6e4 84 _tx_int_buffer[0] == NULL |
shorie 10:45cbff9ee6e4 85 _tx_int_buffer[1] == NULL |
shorie 10:45cbff9ee6e4 86 _rx_right_buffer == NULL |
shorie 10:45cbff9ee6e4 87 _tx_right_buffer == NULL |
shorie 10:45cbff9ee6e4 88 _rx_left_buffer == NULL |
shorie 10:45cbff9ee6e4 89 _tx_left_buffer == NULL )
shorie 0:5ac19c994288 90 { // if error, release all
shorie 10:45cbff9ee6e4 91 delete [] _tx_int_buffer[0];
shorie 10:45cbff9ee6e4 92 delete [] _tx_int_buffer[1];
shorie 10:45cbff9ee6e4 93 delete [] _rx_int_buffer[0];
shorie 10:45cbff9ee6e4 94 delete [] _rx_int_buffer[1];
shorie 0:5ac19c994288 95
shorie 10:45cbff9ee6e4 96 delete [] _tx_left_buffer;
shorie 10:45cbff9ee6e4 97 delete [] _tx_right_buffer;
shorie 10:45cbff9ee6e4 98 delete [] _rx_left_buffer;
shorie 10:45cbff9ee6e4 99 delete [] _rx_right_buffer;
shorie 0:5ac19c994288 100
shorie 10:45cbff9ee6e4 101 _tx_int_buffer[0] = NULL;
shorie 10:45cbff9ee6e4 102 _tx_int_buffer[1] = NULL;
shorie 10:45cbff9ee6e4 103 _rx_int_buffer[0] = NULL;
shorie 10:45cbff9ee6e4 104 _rx_int_buffer[1] = NULL;
shorie 0:5ac19c994288 105
shorie 10:45cbff9ee6e4 106 _tx_left_buffer = NULL;
shorie 10:45cbff9ee6e4 107 _tx_right_buffer = NULL;
shorie 10:45cbff9ee6e4 108 _rx_left_buffer = NULL;
shorie 10:45cbff9ee6e4 109 _rx_right_buffer = NULL;
shorie 0:5ac19c994288 110
shorie 0:5ac19c994288 111 return memory_allocation_error;
shorie 0:5ac19c994288 112 }
shorie 0:5ac19c994288 113
shorie 0:5ac19c994288 114 // clear blocks
shorie 10:45cbff9ee6e4 115 for ( int i=0; i<_block_size*2; i++ )
shorie 0:5ac19c994288 116 {
shorie 0:5ac19c994288 117
shorie 10:45cbff9ee6e4 118 _tx_int_buffer[0][i] = 0;
shorie 10:45cbff9ee6e4 119 _tx_int_buffer[1][i] = 0;
shorie 10:45cbff9ee6e4 120 _rx_int_buffer[0][i] = 0;
shorie 10:45cbff9ee6e4 121 _rx_int_buffer[1][i] = 0;
shorie 0:5ac19c994288 122
shorie 0:5ac19c994288 123 }
shorie 0:5ac19c994288 124 // clear blocks
shorie 10:45cbff9ee6e4 125 for ( int i=0; i<_block_size ; i++ )
shorie 0:5ac19c994288 126 {
shorie 0:5ac19c994288 127
shorie 10:45cbff9ee6e4 128 _tx_left_buffer[i] = 0;
shorie 10:45cbff9ee6e4 129 _tx_right_buffer[i] = 0;
shorie 10:45cbff9ee6e4 130 _rx_left_buffer[i] = 0;
shorie 10:45cbff9ee6e4 131 _rx_right_buffer[i] = 0;
shorie 0:5ac19c994288 132
shorie 0:5ac19c994288 133 }
shorie 0:5ac19c994288 134
shorie 0:5ac19c994288 135 return no_error;
shorie 0:5ac19c994288 136 }
shorie 0:5ac19c994288 137
shorie 12:5e73a102d809 138 void Framework::start(
shorie 12:5e73a102d809 139 void (* init_cb ) (unsigned int),
shorie 12:5e73a102d809 140 void (* process_cb ) (float[], float[], float[], float[], unsigned int)
shorie 12:5e73a102d809 141 )
shorie 0:5ac19c994288 142 {
shorie 12:5e73a102d809 143 // if needed, call the initializer
shorie 12:5e73a102d809 144 if ( init_cb )
shorie 12:5e73a102d809 145 init_cb( _block_size );
shorie 12:5e73a102d809 146
shorie 12:5e73a102d809 147 // register the signal processing callback
shorie 12:5e73a102d809 148 _process_callback = process_cb;
shorie 12:5e73a102d809 149
shorie 2:6613e62da521 150 // synchronize with Word select signal, to process RX/TX as atomic timing.
shorie 1:9710fb328a08 151 hal_i2s_pin_config_and_wait_ws();
shorie 0:5ac19c994288 152 hal_i2s_start();
shorie 0:5ac19c994288 153 }
shorie 0:5ac19c994288 154
shorie 11:5f91f55065c1 155 void Framework::set_i2s_irq_priority( unsigned int pri )
shorie 0:5ac19c994288 156 {
shorie 0:5ac19c994288 157 NVIC_SetPriority(hal_get_process_irq_id(), pri); // must be higher than PendSV of mbed-RTOS
shorie 0:5ac19c994288 158 }
shorie 0:5ac19c994288 159
shorie 11:5f91f55065c1 160 void Framework::set_process_irq_priority( unsigned int pri )
shorie 0:5ac19c994288 161 {
shorie 0:5ac19c994288 162 NVIC_SetPriority(hal_get_i2s_irq_id(), pri); // must be higher than process IRQ
shorie 0:5ac19c994288 163 }
shorie 0:5ac19c994288 164
shorie 11:5f91f55065c1 165 void Framework::set_pre_interrupt_callback( void (* cb ) (void))
shorie 0:5ac19c994288 166 {
shorie 10:45cbff9ee6e4 167 _pre_interrupt_callback = cb;
shorie 0:5ac19c994288 168 }
shorie 0:5ac19c994288 169
shorie 11:5f91f55065c1 170 void Framework::set_post_interrupt_callback( void (* cb ) (void))
shorie 0:5ac19c994288 171 {
shorie 10:45cbff9ee6e4 172 _post_interrupt_callback = cb;
shorie 0:5ac19c994288 173 }
shorie 0:5ac19c994288 174
shorie 11:5f91f55065c1 175 void Framework::set_pre_process_callback( void (* cb ) (void))
shorie 0:5ac19c994288 176 {
shorie 10:45cbff9ee6e4 177 _pre_process_callback = cb;
shorie 0:5ac19c994288 178 }
shorie 0:5ac19c994288 179
shorie 11:5f91f55065c1 180 void Framework::set_post_process_callback( void (* cb ) (void))
shorie 0:5ac19c994288 181 {
shorie 10:45cbff9ee6e4 182 _post_process_callback = cb;
shorie 0:5ac19c994288 183 }
shorie 0:5ac19c994288 184
shorie 11:5f91f55065c1 185 void Framework::_do_i2s_irq(void)
shorie 0:5ac19c994288 186 {
shorie 2:6613e62da521 187 // if needed, call pre-interrupt call back
shorie 10:45cbff9ee6e4 188 if ( _pre_interrupt_callback )
shorie 10:45cbff9ee6e4 189 _pre_interrupt_callback();
shorie 0:5ac19c994288 190
shorie 0:5ac19c994288 191 // irq is handled only when the buffer is correctly allocated
shorie 10:45cbff9ee6e4 192 if (_tx_left_buffer)
shorie 0:5ac19c994288 193 {
shorie 0:5ac19c994288 194 int sample;
shorie 2:6613e62da521 195
shorie 2:6613e62da521 196 // check how many data have to be transmimted per interrupt.
shorie 2:6613e62da521 197 for ( int i=0; i<hal_data_per_sample(); i++ )
shorie 0:5ac19c994288 198 {
shorie 2:6613e62da521 199 // copy received data to buffer
shorie 2:6613e62da521 200 hal_get_i2s_rx_data( sample );
shorie 10:45cbff9ee6e4 201 _rx_int_buffer[_buffer_index][_sample_index] = sample;
shorie 2:6613e62da521 202
shorie 2:6613e62da521 203 // copy buffer data to transmit register
shorie 10:45cbff9ee6e4 204 sample = _tx_int_buffer[_buffer_index][_sample_index];
shorie 2:6613e62da521 205 hal_put_i2s_tx_data( sample );
shorie 2:6613e62da521 206
shorie 2:6613e62da521 207 // increment index
shorie 10:45cbff9ee6e4 208 _sample_index ++;
shorie 0:5ac19c994288 209 }
shorie 2:6613e62da521 210
shorie 0:5ac19c994288 211 // Implementation of the double buffer algorithm.
shorie 0:5ac19c994288 212 // if buffer transfer is complete, swap the buffer
shorie 10:45cbff9ee6e4 213 if (_sample_index >= _block_size * 2)
shorie 0:5ac19c994288 214 {
shorie 0:5ac19c994288 215 // index for the signal processing
shorie 10:45cbff9ee6e4 216 _process_index = _buffer_index;
shorie 2:6613e62da521 217
shorie 0:5ac19c994288 218 // swap buffer
shorie 10:45cbff9ee6e4 219 if ( _buffer_index == 0 )
shorie 10:45cbff9ee6e4 220 _buffer_index = 1;
shorie 2:6613e62da521 221 else
shorie 10:45cbff9ee6e4 222 _buffer_index = 0;
shorie 0:5ac19c994288 223
shorie 2:6613e62da521 224 // rewind sample index
shorie 10:45cbff9ee6e4 225 _sample_index = 0;
shorie 2:6613e62da521 226
shorie 2:6613e62da521 227 // Trigger interrupt for signal processing
shorie 2:6613e62da521 228 NVIC->STIR = hal_get_process_irq_id();
shorie 0:5ac19c994288 229 }
shorie 0:5ac19c994288 230 }
shorie 0:5ac19c994288 231
shorie 2:6613e62da521 232 // if needed, call post-interrupt call back
shorie 10:45cbff9ee6e4 233 if ( _post_interrupt_callback )
shorie 10:45cbff9ee6e4 234 _post_interrupt_callback();
shorie 3:707608830793 235
shorie 0:5ac19c994288 236 }
shorie 0:5ac19c994288 237
shorie 11:5f91f55065c1 238 void Framework::_do_process_irq(void)
shorie 0:5ac19c994288 239 {
shorie 2:6613e62da521 240 // If needed, call the pre-process hook
shorie 10:45cbff9ee6e4 241 if ( _pre_process_callback )
shorie 10:45cbff9ee6e4 242 _pre_process_callback();
shorie 0:5ac19c994288 243
shorie 2:6613e62da521 244 // Only when the process_call back is registered.
shorie 10:45cbff9ee6e4 245 if ( _process_callback )
shorie 0:5ac19c994288 246 {
shorie 0:5ac19c994288 247 int j = 0;
shorie 0:5ac19c994288 248
shorie 2:6613e62da521 249 // Format conversion.
shorie 2:6613e62da521 250 // -- premuted from LRLRLR... to LLL.., RRR...
shorie 2:6613e62da521 251 // -- convert from fixed point to floating point
shorie 2:6613e62da521 252 // -- scale down as range of [-1, 1)
shorie 10:45cbff9ee6e4 253 for ( int i=0; i<_block_size; i++ )
shorie 0:5ac19c994288 254 {
shorie 10:45cbff9ee6e4 255 _rx_left_buffer[i] = _rx_int_buffer[_process_index][j++]/ -(float)INT_MIN;
shorie 10:45cbff9ee6e4 256 _rx_right_buffer[i] = _rx_int_buffer[_process_index][j++]/ -(float)INT_MIN;
shorie 0:5ac19c994288 257 }
shorie 0:5ac19c994288 258
shorie 10:45cbff9ee6e4 259 _process_callback
shorie 10:45cbff9ee6e4 260 (
shorie 10:45cbff9ee6e4 261 _rx_left_buffer,
shorie 10:45cbff9ee6e4 262 _rx_right_buffer,
shorie 10:45cbff9ee6e4 263 _tx_left_buffer,
shorie 10:45cbff9ee6e4 264 _tx_right_buffer,
shorie 10:45cbff9ee6e4 265 _block_size
shorie 10:45cbff9ee6e4 266 );
shorie 0:5ac19c994288 267
shorie 2:6613e62da521 268 // Format conversion.
shorie 2:6613e62da521 269 // -- premuted from LLL.., RRR... to LRLRLR...
shorie 2:6613e62da521 270 // -- convert from floating point to fixed point
shorie 2:6613e62da521 271 // -- scale up from range of [-1, 1)
shorie 0:5ac19c994288 272 j = 0;
shorie 10:45cbff9ee6e4 273 for ( int i=0; i<_block_size; i++ )
shorie 0:5ac19c994288 274 {
shorie 10:45cbff9ee6e4 275 _tx_int_buffer[_process_index][j++] = _tx_left_buffer[i] * -(float)INT_MIN ;
shorie 10:45cbff9ee6e4 276 _tx_int_buffer[_process_index][j++] = _tx_right_buffer[i] * -(float)INT_MIN ;
shorie 0:5ac19c994288 277 }
shorie 0:5ac19c994288 278
shorie 0:5ac19c994288 279 }
shorie 0:5ac19c994288 280
shorie 2:6613e62da521 281 // if needed, call post-process callback
shorie 10:45cbff9ee6e4 282 if ( _post_process_callback )
shorie 10:45cbff9ee6e4 283 _post_process_callback();
shorie 0:5ac19c994288 284 }
shorie 0:5ac19c994288 285
shorie 11:5f91f55065c1 286 void Framework::_process_irq_handler()
shorie 0:5ac19c994288 287 {
shorie 12:5e73a102d809 288 Framework::_fw->_do_process_irq();
shorie 0:5ac19c994288 289 }
shorie 0:5ac19c994288 290
shorie 11:5f91f55065c1 291 void Framework::_i2s_irq_handler()
shorie 2:6613e62da521 292 {
shorie 12:5e73a102d809 293 Framework::_fw->_do_i2s_irq();
shorie 0:5ac19c994288 294 }
shorie 1:9710fb328a08 295
shorie 2:6613e62da521 296
shorie 12:5e73a102d809 297 Framework * Framework::_fw;
shorie 5:1cbfb7a9cd0c 298
shorie 0:5ac19c994288 299 }
shorie 0:5ac19c994288 300