sp
Diff: SAI_InOut.cpp
- Revision:
- 0:f255629eada1
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_; +}