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
Diff: SAI_InOut.cpp
- Revision:
- 0:eade5d3ae0eb
- Child:
- 1:48ed86c8430a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SAI_InOut.cpp Thu May 05 11:12:45 2016 +0000 @@ -0,0 +1,199 @@ +//----------------------------------------------------------- +// SiaIO class +// 2016/05/05, Copyright (c) 2016 MIKAMI, Naoki +//----------------------------------------------------------- + +#include "SAI_InOut.hpp" +#include "MyBSP_AUDIO_IN_OUT_Init.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_ = new int16_t[(size*2)*2]; + inOffset_ = 0; + captured_ = false; + } + outBuffer_ = new int16_t[(size*2)*2]; + tmp_ = new int16_t[size*2]; + tmpIndex_ = 0; + xferred_ = false; + + ClearBuffer(); + InitCodec(inputDevice); + } + + SaiIO::~SaiIO() + { + delete[] tmp_; + delete[] outBuffer_; + if (IOBOTH_ != OUTPUT) delete[] inBuffer_; + } + + // Stop audio input + void SaiIO::StopAudioIn() + { + if (BSP_AUDIO_IN_Stop(CODEC_PDWN_SW) == 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; + InitCodec(dev); + } + + // If captured, return true + bool SaiIO::IsCaptured() + { + if (!captured_) return false; + + inIndex_ = inOffset_; + return true; + } + + // Input from input buffer + void SaiIO::Input(int16_t &xL, int16_t &xR) + { + xL = inBuffer_[inIndex_++]; + xR = inBuffer_[inIndex_++]; + } + + 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::Pause() + { + BSP_AUDIO_OUT_SetMute(AUDIO_MUTE_ON); + BSP_AUDIO_IN_Pause(); + BSP_AUDIO_OUT_Pause(); + ClearBuffer(); + } + + void SaiIO::Resume() + { + BSP_AUDIO_IN_Resume(); + BSP_AUDIO_OUT_Resume(); + BSP_AUDIO_OUT_SetMute(AUDIO_MUTE_OFF); + } + + 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) + { + int audioInVolume = 0; + if (inputDevice != 0) + audioInVolume = (inputDevice == INPUT_DEVICE_INPUT_LINE_1) ? + 60 : 100; + + if (IOBOTH_ == BOTH) + if (MyBSP_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(); + + if (IOBOTH_ == OUTPUT) + if (BSP_AUDIO_OUT_Init(OUTPUT_DEVICE_HEADPHONE, + 90, FS_) == AUDIO_ERROR) + ErrorTrap(); + + if (IOBOTH_ != OUTPUT) InitInput(); + if (IOBOTH_ != INPUT) InitOutput(); + } + + void SaiIO::InitInput() + { + NVIC_SetVector(AUDIO_IN_SAIx_DMAx_IRQ, + (uint32_t)AUDIO_IN_SAIx_DMAx_IRQHandler); + + if (BSP_AUDIO_IN_Record((uint16_t*)inBuffer_, + bufferSize_) == AUDIO_ERROR) + ErrorTrap(); + } + + void SaiIO::InitOutput() + { + NVIC_SetVector(AUDIO_OUT_SAIx_DMAx_IRQ, + (uint32_t)AUDIO_OUT_SAIx_DMAx_IRQHandler); + BSP_AUDIO_OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); + + if (BSP_AUDIO_OUT_Play((uint16_t *)outBuffer_, + bufferSize_*AUDIODATA_SIZE) == AUDIO_ERROR) + ErrorTrap(); + + // Set output volume of headphone maximum + // AUDIO_IO_Write() is defined in "stm32746g_discovery.c" + // AUDIO_I2C_ADDRESS is defined in "stm32746g_discovery.h" + AUDIO_IO_Write(AUDIO_I2C_ADDRESS, 0x1C, 0x17F); // 0x1C: R28 of WM8994 + AUDIO_IO_Write(AUDIO_I2C_ADDRESS, 0x1D, 0x17F); // 0x1D: R29 of WM8994 + } + + 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; + } + + 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_; + + int16_t* SaiIO::outBuffer_; + int16_t* SaiIO::tmp_; + __IO bool SaiIO::xferred_; +} +