sp

Dependencies:   Array_Matrix

Dependents:   WAV

Files at this revision

API Documentation at this revision

Comitter:
phungductung
Date:
Fri Jun 07 05:10:10 2019 +0000
Commit message:
spkt; ;

Changed in this revision

Array_Matrix.lib Show annotated file Show diff for this revision Revisions of this file
BSP_AudioIn_Overwrite.cpp Show annotated file Show diff for this revision Revisions of this file
BSP_AudioIn_Overwrite.hpp Show annotated file Show diff for this revision Revisions of this file
BSP_AudioOut_Overwrite.cpp Show annotated file Show diff for this revision Revisions of this file
BSP_AudioOut_Overwrite.hpp Show annotated file Show diff for this revision Revisions of this file
SAI_InOut.cpp Show annotated file Show diff for this revision Revisions of this file
SAI_InOut.hpp Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r f255629eada1 Array_Matrix.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Array_Matrix.lib	Fri Jun 07 05:10:10 2019 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/MikamiUitOpen/code/Array_Matrix/#a25dba17218c
diff -r 000000000000 -r f255629eada1 BSP_AudioIn_Overwrite.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BSP_AudioIn_Overwrite.cpp	Fri Jun 07 05:10:10 2019 +0000
@@ -0,0 +1,102 @@
+//------------------------------------------------------------------------------
+//  Overwrite functuions and define calback function
+//  for functions in stm32746g_discovery_audio.cpp
+//
+//  Original version: BSP_overwrite.cpp by Nanase
+//      https://developer.mbed.org/users/nanase/code/DISCO-F746NG_Oscilloscope/
+//------------------------------------------------------------------------------
+
+#include "BSP_AudioIn_Overwrite.hpp"
+
+// These three callback functions are modyfied by Mikami
+void BSP_AUDIO_IN_HalfTransfer_CallBack()
+{
+    Mikami::SaiIO::Captured1st();
+}
+
+void BSP_AUDIO_IN_TransferComplete_CallBack()
+{
+    Mikami::SaiIO::Captured2nd();
+}
+
+void BSP_AUDIO_IN_Error_CallBack()
+{
+    Mikami::SaiIO::ErrorTrap();
+}
+
+//--------------------------------------------------------------
+//  Followings are original by Nanase
+//--------------------------------------------------------------
+
+DMA_HandleTypeDef hdma_sai_rx;
+
+void AUDIO_IN_SAIx_DMAx_IRQHandler()
+{
+    HAL_DMA_IRQHandler(&hdma_sai_rx);
+}
+
+void  BSP_AUDIO_IN_MspInit(SAI_HandleTypeDef *hsai, void *Params)
+{
+    GPIO_InitTypeDef  gpio_init_structure;
+
+    /* Enable SAI clock */
+    AUDIO_IN_SAIx_CLK_ENABLE();
+
+    /* Enable SD GPIO clock */
+    AUDIO_IN_SAIx_SD_ENABLE();
+    /* CODEC_SAI pin configuration: SD pin */
+    gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN;
+    gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+    gpio_init_structure.Pull = GPIO_NOPULL;
+    gpio_init_structure.Speed = GPIO_SPEED_FAST;
+    gpio_init_structure.Alternate = AUDIO_IN_SAIx_SD_AF;
+    HAL_GPIO_Init(AUDIO_IN_SAIx_SD_GPIO_PORT, &gpio_init_structure);
+
+    /* Enable Audio INT GPIO clock */
+    AUDIO_IN_INT_GPIO_ENABLE();
+    /* Audio INT pin configuration: input */
+    gpio_init_structure.Pin = AUDIO_IN_INT_GPIO_PIN;
+    gpio_init_structure.Mode = GPIO_MODE_INPUT;
+    gpio_init_structure.Pull = GPIO_NOPULL;
+    gpio_init_structure.Speed = GPIO_SPEED_FAST;
+    HAL_GPIO_Init(AUDIO_IN_INT_GPIO_PORT, &gpio_init_structure);
+
+    /* Enable the DMA clock */
+    AUDIO_IN_SAIx_DMAx_CLK_ENABLE();
+
+    if(hsai->Instance == AUDIO_IN_SAIx)
+    {
+        /* Configure the hdma_sai_rx handle parameters */
+        hdma_sai_rx.Init.Channel             = AUDIO_IN_SAIx_DMAx_CHANNEL;
+        hdma_sai_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
+        hdma_sai_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
+        hdma_sai_rx.Init.MemInc              = DMA_MINC_ENABLE;
+        hdma_sai_rx.Init.PeriphDataAlignment = AUDIO_IN_SAIx_DMAx_PERIPH_DATA_SIZE;
+        hdma_sai_rx.Init.MemDataAlignment    = AUDIO_IN_SAIx_DMAx_MEM_DATA_SIZE;
+        hdma_sai_rx.Init.Mode                = DMA_CIRCULAR;
+        hdma_sai_rx.Init.Priority            = DMA_PRIORITY_HIGH;
+        hdma_sai_rx.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;
+        hdma_sai_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
+        hdma_sai_rx.Init.MemBurst            = DMA_MBURST_SINGLE;
+        hdma_sai_rx.Init.PeriphBurst         = DMA_MBURST_SINGLE;
+
+        hdma_sai_rx.Instance = AUDIO_IN_SAIx_DMAx_STREAM;
+
+        /* Associate the DMA handle */
+        __HAL_LINKDMA(hsai, hdmarx, hdma_sai_rx);
+
+        /* Deinitialize the Stream for new transfer */
+        HAL_DMA_DeInit(&hdma_sai_rx);
+
+        /* Configure the DMA Stream */
+        HAL_DMA_Init(&hdma_sai_rx);
+    }
+
+    /* SAI DMA IRQ Channel configuration */
+    HAL_NVIC_SetPriority(AUDIO_IN_SAIx_DMAx_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
+    HAL_NVIC_EnableIRQ(AUDIO_IN_SAIx_DMAx_IRQ);
+
+    /* Audio INT IRQ Channel configuration */
+    HAL_NVIC_SetPriority(AUDIO_IN_INT_IRQ, AUDIO_IN_IRQ_PREPRIO, 0);
+    HAL_NVIC_EnableIRQ(AUDIO_IN_INT_IRQ);
+}
diff -r 000000000000 -r f255629eada1 BSP_AudioIn_Overwrite.hpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BSP_AudioIn_Overwrite.hpp	Fri Jun 07 05:10:10 2019 +0000
@@ -0,0 +1,15 @@
+//--------------------------------------------------------------
+//  Overwrite functuions and define calback function (Header)
+//  for functions in stm32746g_discovery_audio.cpp
+//--------------------------------------------------------------
+
+#ifndef F746_AUDIO_IN_OVERWRITE_HPP
+#define F746_AUDIO_IN_OVERWRITE_HPP
+
+#include "stm32746g_discovery_audio.h"
+#include "SAI_InOut.hpp"
+
+void AUDIO_IN_SAIx_DMAx_IRQHandler();
+
+#endif  // F746_AUDIO_IN_OVERWRITE_HPP
+
diff -r 000000000000 -r f255629eada1 BSP_AudioOut_Overwrite.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BSP_AudioOut_Overwrite.cpp	Fri Jun 07 05:10:10 2019 +0000
@@ -0,0 +1,113 @@
+//------------------------------------------------------------------------------
+//  Overwrite functuions and define calback functions
+//  for functions in stm32746g_discovery_audio.cpp
+//
+//  Original version: BSP_overwrite.cpp by Nanase
+//      https://developer.mbed.org/users/nanase/code/DISCO-F746NG_Sweep/
+//------------------------------------------------------------------------------
+#include "BSP_AudioOut_Overwrite.hpp"
+
+// These three callback functions are modyfied by Mikami
+void BSP_AUDIO_OUT_HalfTransfer_CallBack()
+{
+    Mikami::SaiIO::FillBuffer1st();
+}
+
+void BSP_AUDIO_OUT_TransferComplete_CallBack()
+{
+    Mikami::SaiIO::FillBuffer2nd();
+}
+
+void BSP_AUDIO_OUT_Error_CallBack()
+{
+    Mikami::SaiIO::ErrorTrap();
+}
+
+//--------------------------------------------------------------
+//  Followings are original by Nanase
+//--------------------------------------------------------------
+
+DMA_HandleTypeDef hdma_sai_tx;
+
+void AUDIO_OUT_SAIx_DMAx_IRQHandler()
+{
+    HAL_DMA_IRQHandler(&hdma_sai_tx);
+}
+
+void BSP_AUDIO_OUT_MspInit(SAI_HandleTypeDef *hsai, void *Params)
+{
+    //static DMA_HandleTypeDef hdma_sai_tx;
+    GPIO_InitTypeDef  gpio_init_structure;
+
+    /* Enable SAI clock */
+    AUDIO_OUT_SAIx_CLK_ENABLE();
+
+    /* Enable GPIO clock */
+    AUDIO_OUT_SAIx_MCLK_ENABLE();
+    AUDIO_OUT_SAIx_SCK_SD_ENABLE();
+    AUDIO_OUT_SAIx_FS_ENABLE();
+
+    /* CODEC_SAI pins configuration: FS, SCK, MCK and SD pins ------------------*/
+    gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN;
+    gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+    gpio_init_structure.Pull = GPIO_NOPULL;
+    gpio_init_structure.Speed = GPIO_SPEED_HIGH;
+    gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF;
+    HAL_GPIO_Init(AUDIO_OUT_SAIx_FS_GPIO_PORT, &gpio_init_structure);
+
+    gpio_init_structure.Pin = AUDIO_OUT_SAIx_SCK_PIN;
+    gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+    gpio_init_structure.Pull = GPIO_NOPULL;
+    gpio_init_structure.Speed = GPIO_SPEED_HIGH;
+    gpio_init_structure.Alternate = AUDIO_OUT_SAIx_SCK_AF;
+    HAL_GPIO_Init(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, &gpio_init_structure);
+
+    gpio_init_structure.Pin =  AUDIO_OUT_SAIx_SD_PIN;
+    gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+    gpio_init_structure.Pull = GPIO_NOPULL;
+    gpio_init_structure.Speed = GPIO_SPEED_HIGH;
+    gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF;
+    HAL_GPIO_Init(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, &gpio_init_structure);
+
+    gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN;
+    gpio_init_structure.Mode = GPIO_MODE_AF_PP;
+    gpio_init_structure.Pull = GPIO_NOPULL;
+    gpio_init_structure.Speed = GPIO_SPEED_HIGH;
+    gpio_init_structure.Alternate = AUDIO_OUT_SAIx_FS_SD_MCLK_AF;
+    HAL_GPIO_Init(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, &gpio_init_structure);
+
+    /* Enable the DMA clock */
+    AUDIO_OUT_SAIx_DMAx_CLK_ENABLE();
+
+    if(hsai->Instance == AUDIO_OUT_SAIx)
+    {
+        /* Configure the hdma_saiTx handle parameters */
+        hdma_sai_tx.Init.Channel             = AUDIO_OUT_SAIx_DMAx_CHANNEL;
+        hdma_sai_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
+        hdma_sai_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
+        hdma_sai_tx.Init.MemInc              = DMA_MINC_ENABLE;
+        hdma_sai_tx.Init.PeriphDataAlignment = AUDIO_OUT_SAIx_DMAx_PERIPH_DATA_SIZE;
+        hdma_sai_tx.Init.MemDataAlignment    = AUDIO_OUT_SAIx_DMAx_MEM_DATA_SIZE;
+        hdma_sai_tx.Init.Mode                = DMA_CIRCULAR;
+        hdma_sai_tx.Init.Priority            = DMA_PRIORITY_HIGH;
+        hdma_sai_tx.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
+        hdma_sai_tx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
+        hdma_sai_tx.Init.MemBurst            = DMA_MBURST_SINGLE;
+        hdma_sai_tx.Init.PeriphBurst         = DMA_PBURST_SINGLE;
+
+        hdma_sai_tx.Instance = AUDIO_OUT_SAIx_DMAx_STREAM;
+
+        /* Associate the DMA handle */
+        __HAL_LINKDMA(hsai, hdmatx, hdma_sai_tx);
+
+        /* Deinitialize the Stream for new transfer */
+        HAL_DMA_DeInit(&hdma_sai_tx);
+
+        /* Configure the DMA Stream */
+        HAL_DMA_Init(&hdma_sai_tx);
+    }
+    
+    /* SAI DMA IRQ Channel configuration */
+    HAL_NVIC_SetPriority(AUDIO_OUT_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
+    HAL_NVIC_EnableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ);
+}
diff -r 000000000000 -r f255629eada1 BSP_AudioOut_Overwrite.hpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BSP_AudioOut_Overwrite.hpp	Fri Jun 07 05:10:10 2019 +0000
@@ -0,0 +1,14 @@
+//--------------------------------------------------------------
+//  Overwrite functuions and define calback function (Header)
+//  for functions in stm32746g_discovery_audio.cpp
+//--------------------------------------------------------------
+
+#ifndef F746_AUDIO_OUT_OVERWRITE_HPP
+#define F746_AUDIO_OUT_OVERWRITE_HPP
+
+#include "stm32746g_discovery_audio.h"
+#include "SAI_InOut.hpp"
+
+void AUDIO_OUT_SAIx_DMAx_IRQHandler();
+
+#endif  // F746_AUDIO_OUT_OVERWRITE_HPP
diff -r 000000000000 -r f255629eada1 SAI_InOut.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SAI_InOut.cpp	Fri Jun 07 05:10:10 2019 +0000
@@ -0,0 +1,190 @@
+//-----------------------------------------------------------
+//  SaiIO class
+//  2017/03/16, Copyright (c) 2017 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#include "SAI_InOut.hpp"
+
+namespace Mikami
+{
+    // Constructor
+    SaiIO::SaiIO(InOutBoth ioBoth, int size, int fs,
+                 uint16_t inputDevice)
+        : FS_(fs), IOBOTH_(ioBoth)
+    {
+        nData_ = size;
+        bufferSize_ = (size*2)*2;
+        
+        if (ioBoth != OUTPUT)
+        {
+            inBuffer_.SetSize((size*2)*2);
+            inOffset_ = 0;
+            captured_ = false;
+        }
+        if (ioBoth != INPUT)
+        {
+            outBuffer_.SetSize((size*2)*2);
+            tmp_.SetSize(size*2);
+            tmpIndex_ = 0;
+            xferred_ = false;
+            ClearBuffer();
+        }
+        InitCodec(inputDevice);
+    }
+
+    // Input start
+    void SaiIO::RecordIn()
+    {
+        if (BSP_AUDIO_IN_Record(inBuffer_, bufferSize_) == AUDIO_ERROR)
+            ErrorTrap();
+    }
+
+    // Switching input device and run
+    void SaiIO::SwitchInputDevice(int sw)
+    {
+        uint16_t dev = (sw == 0) ?
+                        INPUT_DEVICE_DIGITAL_MICROPHONE_2
+                      : INPUT_DEVICE_INPUT_LINE_1;
+        InitInput(dev);
+        ClearBuffer();
+        RecordIn();
+        if (IOBOTH_ == BOTH) PlayOut();
+    }
+    
+    // If captured, return true
+    bool SaiIO::IsCaptured()
+    {
+        if (!captured_) return false;
+
+        inIndex_ = inOffset_;
+        captured_ = false;
+        return true;
+    }
+
+    void SaiIO::PlayOut()
+    {
+        ClearBuffer();
+        BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
+        if (BSP_AUDIO_OUT_Play(outBuffer_, bufferSize_*AUDIODATA_SIZE)
+            == AUDIO_ERROR)
+            ErrorTrap();
+    }
+
+    // Return true if transfer completion to output
+    bool SaiIO::IsXferred()
+    {
+        if (!xferred_) return false;
+        
+        tmpIndex_ = 0;
+        xferred_ = false;
+        return true;
+    }
+
+    void SaiIO::Output(int16_t xL, int16_t xR)
+    {
+        tmp_[tmpIndex_++] = xL; // Left
+        tmp_[tmpIndex_++] = xR; // Right
+    }
+
+    void SaiIO::ErrorTrap()
+    {
+        DigitalOut led1(LED1);
+        fprintf(stderr, "\r\n#### ERROR ####\r\n");
+        while(true)
+        {
+            led1 = !led1;
+            wait_ms(250);
+        }
+    }   
+
+    // Initialize audio input and output 
+    void SaiIO::InitCodec(uint16_t inputDevice)
+    {
+        if (inputDevice != 0) InitInput(inputDevice);
+
+        if (IOBOTH_ == OUTPUT)
+            if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE,
+                                   100, FS_) == AUDIO_ERROR)
+                ErrorTrap();
+
+        if (IOBOTH_ != OUTPUT) SetInput();
+        if (IOBOTH_ != INPUT) SetOutput();
+    }
+
+    void SaiIO::InitInput(uint16_t inputDevice)
+    {
+        int audioInVolume = (inputDevice == INPUT_DEVICE_INPUT_LINE_1) ?
+                            70 : 90;
+        InputFp = (inputDevice == INPUT_DEVICE_INPUT_LINE_1) ?
+                  &SaiIO::InputNormal : &SaiIO::InputReversal;
+
+        if (IOBOTH_ == BOTH)
+            if (BSP_AUDIO_IN_OUT_Init(inputDevice, OUTPUT_DEVICE_HEADPHONE,
+                                      audioInVolume, FS_) == AUDIO_ERROR)
+                ErrorTrap();
+
+        if (IOBOTH_ == INPUT)
+            if (BSP_AUDIO_IN_Init(inputDevice,
+                                  audioInVolume, FS_) == AUDIO_ERROR)
+                ErrorTrap();
+    }
+
+    void SaiIO::SetInput()
+    {
+        NVIC_SetVector(AUDIO_IN_SAIx_DMAx_IRQ,
+                       (uint32_t)AUDIO_IN_SAIx_DMAx_IRQHandler);
+    }
+
+    void SaiIO::SetOutput()
+    {
+        NVIC_SetVector(AUDIO_OUT_SAIx_DMAx_IRQ,
+                       (uint32_t)AUDIO_OUT_SAIx_DMAx_IRQHandler);
+        BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
+    }
+
+    void SaiIO::ClearBuffer()
+    {
+        if (IOBOTH_ != OUTPUT)
+            for (int n=0; n<bufferSize_; n++) inBuffer_[n] = 0;
+        for (int n=0; n<bufferSize_; n++) outBuffer_[n] = 0;
+        for (int n=0; n<nData_*2; n++) tmp_[n] = 0;
+    }
+
+    // For line input
+    void SaiIO::InputNormal(int16_t &xL, int16_t &xR)
+    {
+        xL = inBuffer_[inIndex_++];
+        xR = inBuffer_[inIndex_++];
+    }
+
+    // For MEMS microphone input
+    void SaiIO::InputReversal(int16_t &xL, int16_t &xR)       
+    {
+        xR = inBuffer_[inIndex_++];
+        xL = inBuffer_[inIndex_++];
+    }
+
+    void SaiIO::Captured(int32_t offset)
+    {
+        captured_ = true;
+        inOffset_ = offset;
+    }
+
+    void SaiIO::FillBuffer(uint32_t offset)
+    {
+        int k = offset;
+        for (int n=0; n<nData_*2; n++)
+             outBuffer_[k++] = tmp_[n];
+        xferred_ = true;
+    }
+
+    int32_t SaiIO::nData_;
+    int32_t SaiIO::bufferSize_;
+
+    __IO bool SaiIO::captured_;
+    __IO int32_t SaiIO::inOffset_;
+
+    Array<uint16_t> SaiIO::outBuffer_;
+    Array<uint16_t> SaiIO::tmp_;       
+    __IO bool SaiIO::xferred_;
+}
diff -r 000000000000 -r f255629eada1 SAI_InOut.hpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SAI_InOut.hpp	Fri Jun 07 05:10:10 2019 +0000
@@ -0,0 +1,110 @@
+//-----------------------------------------------------------
+//  SaiIO class (Header)
+//  2017/03/17, Copyright (c) 2017 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#ifndef F746_SAI_IO_HPP
+#define F746_SAI_IO_HPP
+
+#include "mbed.h"
+#include "stm32746g_discovery_audio.h"
+#include "BSP_AudioIn_Overwrite.hpp"
+#include "BSP_AudioOut_Overwrite.hpp"
+#include "Array.hpp"
+
+namespace Mikami
+{
+    class SaiIO
+    {
+    public:
+        enum InOutBoth { INPUT,     // input only
+                         OUTPUT,    // output only
+                         BOTH };    // input and output
+        // Constructor
+        //      inputDevice: INPUT_DEVICE_DIGITAL_MICROPHONE_2 or
+        //                   INPUT_DEVICE_INPUT_LINE_1
+        //      inputDevice == 0 : not use input device
+        SaiIO(InOutBoth ioBoth, int size, int fs,
+              uint16_t inputDevice = 0);
+        virtual ~SaiIO() {}
+ 
+        int32_t GetLength() { return nData_; }
+        
+        void RecordIn();
+        // sw = 0: DIGITAL_MICROPHONE_2
+        //      1: LINE_1
+        void SwitchInputDevice(int sw);
+
+        bool IsCaptured();
+        // Input using SAI
+        void Input(int16_t &xL, int16_t &xR)
+        {   (this->*InputFp)(xL, xR); }
+
+        void StopIn()   { BSP_AUDIO_IN_Stop(CODEC_PDWN_SW); }
+        void PauseIn()  { BSP_AUDIO_IN_Pause(); }
+        void ResumeIn() { BSP_AUDIO_IN_Resume(); }
+
+        void PlayOut();
+        bool IsXferred();
+        // Output using SAI
+        void Output(int16_t xL, int16_t xR);
+      
+        void StopOut()   { BSP_AUDIO_OUT_Stop(CODEC_PDWN_SW); }
+        void PauseOut()  { BSP_AUDIO_OUT_Pause(); }
+        void ResumeOut() { BSP_AUDIO_OUT_Resume(); }
+       
+        // IF you use both input and output of SAI,
+        // you can use following function
+        bool IsCompleted()
+        {   return IsCaptured() && IsXferred(); }
+
+        // Following two member functions are called from
+        // callback functions in "BSP_AudioIn_Overwrite.cpp"
+        static void Captured1st() { Captured(0); }
+        static void Captured2nd() { Captured(bufferSize_/2); }
+
+        // Following two member functions are called from
+        // callback functions in "BSP_AudioOut_Overwrite.cpp"
+        static void FillBuffer1st() { FillBuffer(0); }
+        static void FillBuffer2nd() { FillBuffer(bufferSize_/2); }
+
+        // Called form the functions in "BSP_AudioIn_Overwrite.cpp"
+        // and "BSP_AudioOut_Overwrite.cpp" 
+        static void ErrorTrap();
+
+    private:
+        const int FS_;
+        const InOutBoth IOBOTH_; 
+
+        Array<uint16_t> inBuffer_;
+        static Array<uint16_t> outBuffer_;
+        static Array<uint16_t> tmp_;       
+
+        __IO int32_t inIndex_;
+        __IO int32_t tmpIndex_;
+
+        static int32_t nData_;
+        static int32_t bufferSize_;
+        static __IO bool captured_;
+        static __IO int32_t inOffset_;
+        static __IO bool xferred_;
+
+        void InitCodec(uint16_t inputDevice);
+        void InitInput(uint16_t inputDevice);
+        void SetInput();
+        void SetOutput();
+        void ClearBuffer();
+
+        // This function pointer is assigned by
+        // InputNormal() or InputReversal()
+        void (SaiIO::*InputFp)(int16_t &, int16_t &);
+        // For line input
+        void InputNormal(int16_t &xL, int16_t &xR);
+        // For MEMS microphone input
+        void InputReversal(int16_t &xL, int16_t &xR);
+        
+        static void Captured(int32_t offset);
+        static void FillBuffer(uint32_t offset);
+    };
+}
+#endif  // F746_SAI_IO_HPP