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を使う方はここから読み始めると良いでしょう。
unzen.cpp@9:2da6ce640691, 2016-05-08 (annotated)
- Committer:
- shorie
- Date:
- Sun May 08 02:44:45 2016 +0000
- Revision:
- 9:2da6ce640691
- Parent:
- 8:63e098b779e9
- Child:
- 10:45cbff9ee6e4
audio codec controller is now outside of unzen framework.
Who changed what in which revision?
User | Revision | Line number | New 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 | 0:5ac19c994288 | 9 | framework::framework() |
shorie | 0:5ac19c994288 | 10 | { |
shorie | 2:6613e62da521 | 11 | |
shorie | 2:6613e62da521 | 12 | // Clear all buffers |
shorie | 0:5ac19c994288 | 13 | tx_int_buffer[0] = NULL; |
shorie | 0:5ac19c994288 | 14 | tx_int_buffer[1] = NULL; |
shorie | 0:5ac19c994288 | 15 | rx_int_buffer[0] = NULL; |
shorie | 0:5ac19c994288 | 16 | rx_int_buffer[1] = NULL; |
shorie | 0:5ac19c994288 | 17 | |
shorie | 0:5ac19c994288 | 18 | tx_left_buffer = NULL; |
shorie | 0:5ac19c994288 | 19 | tx_right_buffer = NULL; |
shorie | 0:5ac19c994288 | 20 | rx_left_buffer = NULL; |
shorie | 0:5ac19c994288 | 21 | rx_right_buffer = NULL; |
shorie | 0:5ac19c994288 | 22 | |
shorie | 2:6613e62da521 | 23 | // Initialize all buffer |
shorie | 0:5ac19c994288 | 24 | buffer_index = 0; |
shorie | 2:6613e62da521 | 25 | sample_index = 0; |
shorie | 0:5ac19c994288 | 26 | |
shorie | 2:6613e62da521 | 27 | // Clear all callbacks |
shorie | 0:5ac19c994288 | 28 | pre_interrupt_callback = NULL; |
shorie | 0:5ac19c994288 | 29 | post_interrupt_callback = NULL; |
shorie | 0:5ac19c994288 | 30 | pre_process_callback = NULL; |
shorie | 0:5ac19c994288 | 31 | post_process_callback = NULL; |
shorie | 0:5ac19c994288 | 32 | |
shorie | 0:5ac19c994288 | 33 | process_callback = NULL; |
shorie | 0:5ac19c994288 | 34 | |
shorie | 2:6613e62da521 | 35 | // Initialy block(buffer) size is 1. |
shorie | 0:5ac19c994288 | 36 | set_block_size( 1 ); |
shorie | 0:5ac19c994288 | 37 | |
shorie | 2:6613e62da521 | 38 | // Initialize I2S peripheral |
shorie | 0:5ac19c994288 | 39 | hal_i2s_setup(); |
shorie | 0:5ac19c994288 | 40 | |
shorie | 2:6613e62da521 | 41 | // Setup the interrupt for the I2S |
shorie | 0:5ac19c994288 | 42 | NVIC_SetVector(hal_get_i2s_irq_id(), (uint32_t)i2s_irq_handler); |
shorie | 2:6613e62da521 | 43 | set_i2s_irq_priority(hal_get_i2s_irq_priority_level()); |
shorie | 0:5ac19c994288 | 44 | NVIC_EnableIRQ(hal_get_i2s_irq_id()); |
shorie | 0:5ac19c994288 | 45 | |
shorie | 2:6613e62da521 | 46 | // Setup the interrupt for the process |
shorie | 0:5ac19c994288 | 47 | NVIC_SetVector(hal_get_process_irq_id(), (uint32_t)process_irq_handler); |
shorie | 2:6613e62da521 | 48 | set_process_irq_priority(hal_get_process_irq_priority_level()); |
shorie | 0:5ac19c994288 | 49 | NVIC_EnableIRQ(hal_get_process_irq_id()); |
shorie | 0:5ac19c994288 | 50 | |
shorie | 0:5ac19c994288 | 51 | } |
shorie | 0:5ac19c994288 | 52 | |
shorie | 0:5ac19c994288 | 53 | error_type framework::set_block_size( unsigned int new_block_size ) |
shorie | 0:5ac19c994288 | 54 | { |
shorie | 0:5ac19c994288 | 55 | |
shorie | 0:5ac19c994288 | 56 | delete [] tx_int_buffer[0]; |
shorie | 0:5ac19c994288 | 57 | delete [] tx_int_buffer[1]; |
shorie | 0:5ac19c994288 | 58 | delete [] rx_int_buffer[0]; |
shorie | 0:5ac19c994288 | 59 | delete [] rx_int_buffer[1]; |
shorie | 0:5ac19c994288 | 60 | |
shorie | 0:5ac19c994288 | 61 | delete [] tx_left_buffer; |
shorie | 0:5ac19c994288 | 62 | delete [] tx_right_buffer; |
shorie | 0:5ac19c994288 | 63 | delete [] rx_left_buffer; |
shorie | 0:5ac19c994288 | 64 | delete [] rx_right_buffer; |
shorie | 0:5ac19c994288 | 65 | |
shorie | 0:5ac19c994288 | 66 | block_size = new_block_size; |
shorie | 0:5ac19c994288 | 67 | |
shorie | 0:5ac19c994288 | 68 | tx_int_buffer[0] = new int[ 2 * block_size ]; |
shorie | 0:5ac19c994288 | 69 | tx_int_buffer[1] = new int[ 2 * block_size ]; |
shorie | 0:5ac19c994288 | 70 | rx_int_buffer[0] = new int[ 2 * block_size ]; |
shorie | 0:5ac19c994288 | 71 | rx_int_buffer[1] = new int[ 2 * block_size ]; |
shorie | 0:5ac19c994288 | 72 | |
shorie | 0:5ac19c994288 | 73 | tx_left_buffer = new float[ block_size ]; |
shorie | 0:5ac19c994288 | 74 | tx_right_buffer = new float[ block_size ]; |
shorie | 0:5ac19c994288 | 75 | rx_left_buffer = new float[ block_size ]; |
shorie | 0:5ac19c994288 | 76 | rx_right_buffer = new float[ block_size ]; |
shorie | 0:5ac19c994288 | 77 | |
shorie | 0:5ac19c994288 | 78 | // error check |
shorie | 0:5ac19c994288 | 79 | if ( rx_int_buffer[0] == NULL | |
shorie | 0:5ac19c994288 | 80 | rx_int_buffer[1] == NULL | |
shorie | 0:5ac19c994288 | 81 | tx_int_buffer[0] == NULL | |
shorie | 0:5ac19c994288 | 82 | tx_int_buffer[1] == NULL | |
shorie | 0:5ac19c994288 | 83 | rx_right_buffer == NULL | |
shorie | 0:5ac19c994288 | 84 | tx_right_buffer == NULL | |
shorie | 0:5ac19c994288 | 85 | rx_left_buffer == NULL | |
shorie | 0:5ac19c994288 | 86 | tx_left_buffer == NULL ) |
shorie | 0:5ac19c994288 | 87 | { // if error, release all |
shorie | 0:5ac19c994288 | 88 | delete [] tx_int_buffer[0]; |
shorie | 0:5ac19c994288 | 89 | delete [] tx_int_buffer[1]; |
shorie | 0:5ac19c994288 | 90 | delete [] rx_int_buffer[0]; |
shorie | 0:5ac19c994288 | 91 | delete [] rx_int_buffer[1]; |
shorie | 0:5ac19c994288 | 92 | |
shorie | 0:5ac19c994288 | 93 | delete [] tx_left_buffer; |
shorie | 0:5ac19c994288 | 94 | delete [] tx_right_buffer; |
shorie | 0:5ac19c994288 | 95 | delete [] rx_left_buffer; |
shorie | 0:5ac19c994288 | 96 | delete [] rx_right_buffer; |
shorie | 0:5ac19c994288 | 97 | |
shorie | 0:5ac19c994288 | 98 | tx_int_buffer[0] = NULL; |
shorie | 0:5ac19c994288 | 99 | tx_int_buffer[1] = NULL; |
shorie | 0:5ac19c994288 | 100 | rx_int_buffer[0] = NULL; |
shorie | 0:5ac19c994288 | 101 | rx_int_buffer[1] = NULL; |
shorie | 0:5ac19c994288 | 102 | |
shorie | 0:5ac19c994288 | 103 | tx_left_buffer = NULL; |
shorie | 0:5ac19c994288 | 104 | tx_right_buffer = NULL; |
shorie | 0:5ac19c994288 | 105 | rx_left_buffer = NULL; |
shorie | 0:5ac19c994288 | 106 | rx_right_buffer = NULL; |
shorie | 0:5ac19c994288 | 107 | |
shorie | 0:5ac19c994288 | 108 | return memory_allocation_error; |
shorie | 0:5ac19c994288 | 109 | } |
shorie | 0:5ac19c994288 | 110 | |
shorie | 0:5ac19c994288 | 111 | // clear blocks |
shorie | 0:5ac19c994288 | 112 | for ( int i=0; i<block_size*2; i++ ) |
shorie | 0:5ac19c994288 | 113 | { |
shorie | 0:5ac19c994288 | 114 | |
shorie | 0:5ac19c994288 | 115 | tx_int_buffer[0][i] = 0; |
shorie | 0:5ac19c994288 | 116 | tx_int_buffer[1][i] = 0; |
shorie | 0:5ac19c994288 | 117 | rx_int_buffer[0][i] = 0; |
shorie | 0:5ac19c994288 | 118 | rx_int_buffer[1][i] = 0; |
shorie | 0:5ac19c994288 | 119 | |
shorie | 0:5ac19c994288 | 120 | } |
shorie | 0:5ac19c994288 | 121 | // clear blocks |
shorie | 0:5ac19c994288 | 122 | for ( int i=0; i<block_size ; i++ ) |
shorie | 0:5ac19c994288 | 123 | { |
shorie | 0:5ac19c994288 | 124 | |
shorie | 0:5ac19c994288 | 125 | tx_left_buffer[i] = 0; |
shorie | 0:5ac19c994288 | 126 | tx_right_buffer[i] = 0; |
shorie | 0:5ac19c994288 | 127 | rx_left_buffer[i] = 0; |
shorie | 0:5ac19c994288 | 128 | rx_right_buffer[i] = 0; |
shorie | 0:5ac19c994288 | 129 | |
shorie | 0:5ac19c994288 | 130 | } |
shorie | 0:5ac19c994288 | 131 | |
shorie | 0:5ac19c994288 | 132 | return no_error; |
shorie | 0:5ac19c994288 | 133 | } |
shorie | 0:5ac19c994288 | 134 | |
shorie | 0:5ac19c994288 | 135 | void framework::start() |
shorie | 0:5ac19c994288 | 136 | { |
shorie | 2:6613e62da521 | 137 | // synchronize with Word select signal, to process RX/TX as atomic timing. |
shorie | 1:9710fb328a08 | 138 | hal_i2s_pin_config_and_wait_ws(); |
shorie | 0:5ac19c994288 | 139 | hal_i2s_start(); |
shorie | 0:5ac19c994288 | 140 | } |
shorie | 0:5ac19c994288 | 141 | |
shorie | 0:5ac19c994288 | 142 | void framework::set_i2s_irq_priority( unsigned int pri ) |
shorie | 0:5ac19c994288 | 143 | { |
shorie | 0:5ac19c994288 | 144 | NVIC_SetPriority(hal_get_process_irq_id(), pri); // must be higher than PendSV of mbed-RTOS |
shorie | 0:5ac19c994288 | 145 | |
shorie | 0:5ac19c994288 | 146 | } |
shorie | 0:5ac19c994288 | 147 | |
shorie | 0:5ac19c994288 | 148 | void framework::set_process_irq_priority( unsigned int pri ) |
shorie | 0:5ac19c994288 | 149 | { |
shorie | 0:5ac19c994288 | 150 | NVIC_SetPriority(hal_get_i2s_irq_id(), pri); // must be higher than process IRQ |
shorie | 0:5ac19c994288 | 151 | |
shorie | 0:5ac19c994288 | 152 | } |
shorie | 0:5ac19c994288 | 153 | |
shorie | 0:5ac19c994288 | 154 | void framework::set_process_callback( void (* cb ) (float[], float[], float[], float[], unsigned int)) |
shorie | 0:5ac19c994288 | 155 | { |
shorie | 0:5ac19c994288 | 156 | process_callback = cb; |
shorie | 0:5ac19c994288 | 157 | } |
shorie | 0:5ac19c994288 | 158 | |
shorie | 0:5ac19c994288 | 159 | void framework::set_pre_interrupt_callback( void (* cb ) (void)) |
shorie | 0:5ac19c994288 | 160 | { |
shorie | 0:5ac19c994288 | 161 | pre_interrupt_callback = cb; |
shorie | 0:5ac19c994288 | 162 | } |
shorie | 0:5ac19c994288 | 163 | |
shorie | 0:5ac19c994288 | 164 | void framework::set_post_interrupt_callback( void (* cb ) (void)) |
shorie | 0:5ac19c994288 | 165 | { |
shorie | 0:5ac19c994288 | 166 | post_interrupt_callback = cb; |
shorie | 0:5ac19c994288 | 167 | } |
shorie | 0:5ac19c994288 | 168 | |
shorie | 0:5ac19c994288 | 169 | void framework::set_pre_process_callback( void (* cb ) (void)) |
shorie | 0:5ac19c994288 | 170 | { |
shorie | 0:5ac19c994288 | 171 | pre_process_callback = cb; |
shorie | 0:5ac19c994288 | 172 | } |
shorie | 0:5ac19c994288 | 173 | |
shorie | 0:5ac19c994288 | 174 | void framework::set_post_process_callback( void (* cb ) (void)) |
shorie | 0:5ac19c994288 | 175 | { |
shorie | 0:5ac19c994288 | 176 | post_process_callback = cb; |
shorie | 0:5ac19c994288 | 177 | } |
shorie | 0:5ac19c994288 | 178 | |
shorie | 0:5ac19c994288 | 179 | void framework::do_i2s_irq(void) |
shorie | 0:5ac19c994288 | 180 | { |
shorie | 2:6613e62da521 | 181 | // if needed, call pre-interrupt call back |
shorie | 0:5ac19c994288 | 182 | if ( pre_interrupt_callback ) |
shorie | 0:5ac19c994288 | 183 | pre_interrupt_callback(); |
shorie | 0:5ac19c994288 | 184 | |
shorie | 0:5ac19c994288 | 185 | // irq is handled only when the buffer is correctly allocated |
shorie | 0:5ac19c994288 | 186 | if (tx_left_buffer) |
shorie | 0:5ac19c994288 | 187 | { |
shorie | 0:5ac19c994288 | 188 | int sample; |
shorie | 2:6613e62da521 | 189 | |
shorie | 2:6613e62da521 | 190 | // check how many data have to be transmimted per interrupt. |
shorie | 2:6613e62da521 | 191 | for ( int i=0; i<hal_data_per_sample(); i++ ) |
shorie | 0:5ac19c994288 | 192 | { |
shorie | 2:6613e62da521 | 193 | // copy received data to buffer |
shorie | 2:6613e62da521 | 194 | hal_get_i2s_rx_data( sample ); |
shorie | 2:6613e62da521 | 195 | rx_int_buffer[buffer_index][sample_index] = sample; |
shorie | 2:6613e62da521 | 196 | |
shorie | 2:6613e62da521 | 197 | // copy buffer data to transmit register |
shorie | 2:6613e62da521 | 198 | sample = tx_int_buffer[buffer_index][sample_index]; |
shorie | 2:6613e62da521 | 199 | hal_put_i2s_tx_data( sample ); |
shorie | 2:6613e62da521 | 200 | |
shorie | 2:6613e62da521 | 201 | // increment index |
shorie | 2:6613e62da521 | 202 | sample_index ++; |
shorie | 0:5ac19c994288 | 203 | } |
shorie | 2:6613e62da521 | 204 | |
shorie | 0:5ac19c994288 | 205 | // Implementation of the double buffer algorithm. |
shorie | 0:5ac19c994288 | 206 | // if buffer transfer is complete, swap the buffer |
shorie | 3:707608830793 | 207 | if (sample_index >= block_size * 2) |
shorie | 0:5ac19c994288 | 208 | { |
shorie | 0:5ac19c994288 | 209 | // index for the signal processing |
shorie | 0:5ac19c994288 | 210 | process_index = buffer_index; |
shorie | 2:6613e62da521 | 211 | |
shorie | 0:5ac19c994288 | 212 | // swap buffer |
shorie | 2:6613e62da521 | 213 | if ( buffer_index == 0 ) |
shorie | 2:6613e62da521 | 214 | buffer_index = 1; |
shorie | 2:6613e62da521 | 215 | else |
shorie | 2:6613e62da521 | 216 | buffer_index = 0; |
shorie | 0:5ac19c994288 | 217 | |
shorie | 2:6613e62da521 | 218 | // rewind sample index |
shorie | 2:6613e62da521 | 219 | sample_index = 0; |
shorie | 2:6613e62da521 | 220 | |
shorie | 2:6613e62da521 | 221 | // Trigger interrupt for signal processing |
shorie | 2:6613e62da521 | 222 | NVIC->STIR = hal_get_process_irq_id(); |
shorie | 0:5ac19c994288 | 223 | } |
shorie | 0:5ac19c994288 | 224 | } |
shorie | 0:5ac19c994288 | 225 | |
shorie | 2:6613e62da521 | 226 | // if needed, call post-interrupt call back |
shorie | 0:5ac19c994288 | 227 | if ( post_interrupt_callback ) |
shorie | 0:5ac19c994288 | 228 | post_interrupt_callback(); |
shorie | 3:707608830793 | 229 | |
shorie | 0:5ac19c994288 | 230 | } |
shorie | 0:5ac19c994288 | 231 | |
shorie | 0:5ac19c994288 | 232 | void framework::do_process_irq(void) |
shorie | 0:5ac19c994288 | 233 | { |
shorie | 2:6613e62da521 | 234 | // If needed, call the pre-process hook |
shorie | 0:5ac19c994288 | 235 | if ( pre_process_callback ) |
shorie | 0:5ac19c994288 | 236 | pre_process_callback(); |
shorie | 0:5ac19c994288 | 237 | |
shorie | 2:6613e62da521 | 238 | // Only when the process_call back is registered. |
shorie | 0:5ac19c994288 | 239 | if ( process_callback ) |
shorie | 0:5ac19c994288 | 240 | { |
shorie | 0:5ac19c994288 | 241 | int j = 0; |
shorie | 0:5ac19c994288 | 242 | |
shorie | 2:6613e62da521 | 243 | // Format conversion. |
shorie | 2:6613e62da521 | 244 | // -- premuted from LRLRLR... to LLL.., RRR... |
shorie | 2:6613e62da521 | 245 | // -- convert from fixed point to floating point |
shorie | 2:6613e62da521 | 246 | // -- scale down as range of [-1, 1) |
shorie | 0:5ac19c994288 | 247 | for ( int i=0; i<block_size; i++ ) |
shorie | 0:5ac19c994288 | 248 | { |
shorie | 0:5ac19c994288 | 249 | rx_left_buffer[i] = rx_int_buffer[process_index][j++]/ -(float)INT_MIN; |
shorie | 0:5ac19c994288 | 250 | rx_right_buffer[i] = rx_int_buffer[process_index][j++]/ -(float)INT_MIN; |
shorie | 0:5ac19c994288 | 251 | } |
shorie | 0:5ac19c994288 | 252 | |
shorie | 1:9710fb328a08 | 253 | process_callback |
shorie | 1:9710fb328a08 | 254 | ( |
shorie | 0:5ac19c994288 | 255 | rx_left_buffer, |
shorie | 0:5ac19c994288 | 256 | rx_right_buffer, |
shorie | 0:5ac19c994288 | 257 | tx_left_buffer, |
shorie | 0:5ac19c994288 | 258 | tx_right_buffer, |
shorie | 0:5ac19c994288 | 259 | block_size |
shorie | 1:9710fb328a08 | 260 | ); |
shorie | 0:5ac19c994288 | 261 | |
shorie | 2:6613e62da521 | 262 | // Format conversion. |
shorie | 2:6613e62da521 | 263 | // -- premuted from LLL.., RRR... to LRLRLR... |
shorie | 2:6613e62da521 | 264 | // -- convert from floating point to fixed point |
shorie | 2:6613e62da521 | 265 | // -- scale up from range of [-1, 1) |
shorie | 0:5ac19c994288 | 266 | j = 0; |
shorie | 0:5ac19c994288 | 267 | for ( int i=0; i<block_size; i++ ) |
shorie | 0:5ac19c994288 | 268 | { |
shorie | 6:df928d55613b | 269 | tx_int_buffer[process_index][j++] = tx_left_buffer[i] * -(float)INT_MIN ; |
shorie | 6:df928d55613b | 270 | tx_int_buffer[process_index][j++] = tx_right_buffer[i] * -(float)INT_MIN ; |
shorie | 0:5ac19c994288 | 271 | } |
shorie | 0:5ac19c994288 | 272 | |
shorie | 0:5ac19c994288 | 273 | } |
shorie | 0:5ac19c994288 | 274 | |
shorie | 2:6613e62da521 | 275 | // if needed, call post-process callback |
shorie | 0:5ac19c994288 | 276 | if ( post_process_callback ) |
shorie | 0:5ac19c994288 | 277 | post_process_callback(); |
shorie | 0:5ac19c994288 | 278 | } |
shorie | 0:5ac19c994288 | 279 | |
shorie | 0:5ac19c994288 | 280 | void framework::process_irq_handler() |
shorie | 0:5ac19c994288 | 281 | { |
shorie | 1:9710fb328a08 | 282 | framework::get()->do_process_irq(); |
shorie | 0:5ac19c994288 | 283 | } |
shorie | 0:5ac19c994288 | 284 | |
shorie | 0:5ac19c994288 | 285 | void framework::i2s_irq_handler() |
shorie | 2:6613e62da521 | 286 | { |
shorie | 1:9710fb328a08 | 287 | framework::get()->do_i2s_irq(); |
shorie | 0:5ac19c994288 | 288 | } |
shorie | 1:9710fb328a08 | 289 | |
shorie | 2:6613e62da521 | 290 | |
shorie | 2:6613e62da521 | 291 | |
shorie | 5:1cbfb7a9cd0c | 292 | |
shorie | 0:5ac19c994288 | 293 | } |
shorie | 0:5ac19c994288 | 294 |