First Publish. Works fine.
Dependents: unzen_sample_LPC4088_quickstart
unzen.h
00001 /** 00002 * \brief header file for the unzen audio frame work 00003 * \arthur SeiichiHorie 00004 * \date 6/Apr/2016 00005 */ 00006 00007 #ifndef _unzen_h_ 00008 #define _unzen_h_ 00009 00010 #include "mbed.h" 00011 /** 00012 \brief audio framework name space. 00013 */ 00014 namespace unzen 00015 { 00016 /** 00017 \brief error status type. 00018 */ 00019 enum error_type { 00020 no_error, 00021 memory_allocation_error 00022 }; 00023 00024 /** 00025 \brief adio frame work. Create a object and execute the \ref Framework::start() method. 00026 00027 example : 00028 \code 00029 #include "unzen.h" // audio framework include file 00030 #include "umb_adau1361a.h" // audio codec contoler include file 00031 #include "mbed.h" 00032 00033 #define CODEC_I2C_ADDR 0x38 00034 00035 DigitalOut myled1(LED1); 00036 00037 00038 // customer signal processing initialization call back. 00039 void init_callback( 00040 unsigned int block_size // block size [sample] 00041 ) 00042 { 00043 // place initialization code here 00044 } 00045 00046 00047 // customer signal processing call back. 00048 void process_callback( 00049 float rx_left_buffer[], // array of the left input samples 00050 float rx_right_buffer[], // array of the right input samples 00051 float tx_left_buffer[], // place to write the left output samples 00052 float tx_right_buffer[], // place to write the left output samples 00053 unsigned int block_size // block size [sample] 00054 ) 00055 { 00056 // Sample processing 00057 for ( int i=0; i<block_size; i++) // for all sample 00058 { 00059 tx_left_buffer[i] = rx_left_buffer[i]; // copy from input to output 00060 tx_right_buffer[i] = rx_right_buffer[i]; 00061 00062 } 00063 } 00064 00065 00066 00067 int main() 00068 { 00069 // I2C is essential to talk with ADAU1361 00070 I2C i2c(SDA, SCL); 00071 00072 // create an audio codec contoler 00073 shimabara::UMB_ADAU1361A codec(shimabara::Fs_32, i2c, CODEC_I2C_ADDR ); // Default Fs is 48kHz 00074 // shimabara::UMB_ADAU1361A codec(shimabara::Fs_441, i2c, CODEC_I2C_ADDR ); 00075 // shimabara::UMB_ADAU1361A codec(shimabara::Fs_48, i2c, CODEC_I2C_ADDR ); 00076 // shimabara::UMB_ADAU1361A codec(shimabara::Fs_96, i2c, CODEC_I2C_ADDR ); 00077 00078 // create an audio framework by singlton pattern 00079 unzen::Framework audio; 00080 00081 // Set I3C clock to 100kHz 00082 i2c.frequency( 100000 ); 00083 00084 00085 // Configure the optional block size of signal processing. By default, it is 1[Sample] 00086 // audio.set_block_size(16); 00087 00088 00089 // Start the ADAU1361. Audio codec starts to generate the I2C signals 00090 codec.start(); 00091 00092 // Start the audio framework on ARM processor. 00093 audio.start( init_callback, process_callback); // path the initializaiton and process call back to framework 00094 00095 00096 // periodically changing gain for test 00097 while(1) 00098 { 00099 for ( int i=-15; i<4; i++ ) 00100 { 00101 codec.set_hp_output_gain( i, i ); 00102 codec.set_line_output_gain( i, i ); 00103 myled1 = 1; 00104 wait(0.2); 00105 myled1 = 0; 00106 wait(0.2); 00107 } 00108 } 00109 } 00110 00111 00112 \endcode 00113 */ 00114 class Framework 00115 { 00116 public: 00117 /** 00118 \constructor 00119 \details 00120 initialize the internal variables and set up all interrrupt / I2S related peripheral. 00121 If needed, power up the peripheral, assign the clock and pins. 00122 At the end of this constructor, the audio framework is ready to run, but still paused. 00123 To start the real processing, call the \ref start method. 00124 00125 Note that this constructor set the block size ( interval count which audio processing 00126 call back is called ) 00127 as 1. If it is needed to use other value, call \ref set_brock_size() method. 00128 */ 00129 Framework (void); 00130 00131 /** 00132 \brief set the interval interrupt count for each time call back is called. 00133 \param block_size An integer parameter > 1. If set to n, for each n interrupts, the audio call back is called. 00134 \returns show the error status 00135 \details 00136 This method re-allocate the internal buffer. Then, the memory allocation error could occur. To detect the 00137 memory allocation error, use \ref get_error() method. 00138 */ 00139 error_type set_block_size( unsigned int new_block_size ); 00140 00141 /** 00142 \brief the real audio signal transfer. Trigger the I2S interrupt and call the call back. 00143 \param init_cb initializer call back for signal processing. This is invoked only once before processing. Can be NUL 00144 \param process_cb The call back function 00145 \details 00146 Set the call back function, then start the transer on I2S 00147 00148 Before the real data transaction on I2S, this method call init_cb(int) call back. The 00149 parameter is block size (>0) which is set by set_block_size() method. If the init_cb is NUL, 00150 this part is skipped. 00151 00152 This process_cb function is called for each time the rx buffer is filled. The call back has 5 parameters. 00153 \li left_rx Received data from I2S rx port. Left data only. 00154 \li right_rx Received data from I2S rx port. Right data only. 00155 \li left_tx Buffer to fill the transmission data. This buffer mus be filled by call back. Left data only 00156 \li right_tx Buffer to fill the transmission data. This buffer mus be filled by call back. Right data only 00157 \li length length of above buffers. 00158 00159 The process call back is called for each time interrupt comes n times. Where n is the value which is specified by \ref set_block_size() 00160 function. This n is also passed to call back as above length parameter. By default, n is 1. 00161 00162 Note that the call back is called at interrupt context. Not the thread level context. 00163 That mean, it is better to avoid to call mbed API except the mbed-RTOS API for interrupt handler. 00164 */ 00165 void start( 00166 void (* init_cb ) (unsigned int), 00167 void (* process_cb ) (float[], float[], float[], float[], unsigned int) 00168 ); 00169 00170 00171 void set_pre_interrupt_callback( void (* cb ) (void)); 00172 00173 /** 00174 \brief Debug hook for interrupt handler. 00175 \param cb A call back which is called at the end of I2S interrupt. 00176 \details 00177 Parameter cb is call at the end of the I2S interrupt. This call back can be 00178 used to mesure the timing of interrupt by toggling the GPIO pin. 00179 00180 Passing 0 to cb parameter let the framwork ignore the callback. 00181 */ 00182 void set_post_interrupt_callback( void (* cb ) (void)); 00183 00184 /** 00185 \brief Debug hook for processing handler. 00186 \param cb A call back which is called at the beggining of processing. 00187 \details 00188 Parameter cb is call at the beggining of the signal processing. This call back can be 00189 used to mesure the load of CPU by toggling the GPIO pin. 00190 00191 Passing 0 to cb parameter let the framwork ignore the callback. 00192 */ 00193 void set_pre_process_callback( void (* cb ) (void)); 00194 00195 /** 00196 \brief Debug hook for processing handler. 00197 \param cb A call back which is called at the end of processing. 00198 \details 00199 Parameter cb is call at the end of the signal processing. This call back can be 00200 used to mesure the load of CPU by toggling the GPIO pin. 00201 00202 Passing 0 to cb parameter let the framwork ignore the callback. 00203 */ 00204 void set_post_process_callback( void (* cb ) (void)); 00205 00206 /** 00207 \brief optional priority control for I2S IRQ. 00208 \param pri Priority of IRQ. 00209 \details 00210 This is optional control. Usually, user doesn't need to call this method. 00211 In case the framework has serious irq priority contention with other software, 00212 this API help programmer to change the priority of the Unzen framework. 00213 00214 Value must be acceptable to CMSIS NVIC_SetPriority(). For LPC4337, it is range of 0..7. The 0 is highest priority. 00215 00216 00217 By default, the framework set this priority as +2 higher than the lowest. 00218 00219 The priority set by this API must be higher than priority set by \ref set_process_irq_priority 00220 */ 00221 void set_i2s_irq_priority( unsigned int pri ); 00222 00223 /** 00224 \brief optional priority control for Signal Processing IRQ. 00225 \param pri Priority of IRQ. 00226 \details 00227 This is optional control. Usually, user doesn't need to call this method. 00228 In case the framework has serious irq priority contention with other software, 00229 this API help programmer to change the priority of the Unzen framework 00230 00231 Value must be acceptable to CMSIS NVIC_SetPriority(). For LPC4337, it is range of 0..7. The 0 is highest priority. 00232 00233 By default, the framework set this priority as +2 higher than the lowest. 00234 00235 */ 00236 void set_process_irq_priority( unsigned int pri ); 00237 00238 private: 00239 static Framework * _fw; 00240 private: 00241 void (* _pre_interrupt_callback )(void); 00242 void (* _post_interrupt_callback )(void); 00243 void (* _pre_process_callback )(void); 00244 void (* _post_process_callback )(void); 00245 00246 void (* _process_callback )( float left_in[], float right_in[], float left_out[], float right_out[], unsigned int length ); 00247 00248 // Size of the blocks ( interval of interrupt to call process_callback. 1 means every interrupt. 2 means every 2 interrupt ) 00249 int _block_size; 00250 00251 // Index for indentifying the buffer for interrupt. 0 or 1. 00252 int _buffer_index; 00253 00254 // Index for indentifying the buffer for processing. 0 or 1. 00255 int _process_index; 00256 00257 // next transfer position in buffer 00258 int _sample_index; 00259 00260 // buffer for interrupt handler. 00261 // data format is LRLR... 00262 int *_tx_int_buffer[2]; 00263 int *_rx_int_buffer[2]; 00264 00265 // buffers for passing 00266 float * _tx_left_buffer, * _tx_right_buffer; 00267 float * _rx_left_buffer, * _rx_right_buffer; 00268 00269 // real processing method. 00270 void _do_i2s_irq(void); 00271 void _do_process_irq(void); 00272 00273 // handler for NIVC 00274 static void _i2s_irq_handler(); 00275 static void _process_irq_handler(); 00276 }; 00277 00278 00279 00280 } 00281 00282 #endif
Generated on Wed Jul 13 2022 06:48:06 by
![doxygen](doxygen.png)