SAI_IO class for using CODEC (MW8994) as analog input and output. このライブラリを登録した際のプログラム:「F746_AudioIO_Demo」
Dependents: F746_SD_WavPlayer F746_SD_GraphicEqualizer_ren0620 Joerg_turbo_ede CW_Decoder_using_FFT_on_DiscoF746NG ... more
SAI_InOut.cpp
- Committer:
- MikamiUitOpen
- Date:
- 2016-07-23
- Revision:
- 5:20cc265d7aec
- Parent:
- 4:2170289dfe94
- Child:
- 7:60c57b2dc83e
File content as of revision 5:20cc265d7aec:
//----------------------------------------------------------- // SiaIO class // 2016/07/23, Copyright (c) 2016 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((uint16_t *)((int16_t *)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_; return true; } void SaiIO::PlayOut() { ClearBuffer(); BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); if (BSP_AUDIO_OUT_Play((uint16_t *)((int16_t *)outBuffer_), bufferSize_*AUDIODATA_SIZE) == AUDIO_ERROR) ErrorTrap(); } // Return true if transfer completion to output bool SaiIO::IsXferred() { if (!xferred_) return false; tmpIndex_ = 0; 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, 90, 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 : 100; 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<int16_t> SaiIO::outBuffer_; Array<int16_t> SaiIO::tmp_; __IO bool SaiIO::xferred_; }