First Publish. Works fine.

Dependents:   unzen_sample_LPC4088_quickstart

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers unzen.h Source File

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