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-05-09
- Revision:
- 2:1aef7b703249
- Parent:
- 1:48ed86c8430a
- Child:
- 3:3bfdd8be834f
File content as of revision 2:1aef7b703249:
//----------------------------------------------------------- // SiaIO class // 2016/05/09, 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; } if (ioBoth != INPUT) { 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_; } // Input start void SaiIO::RecordIn() { if (BSP_AUDIO_IN_Record((uint16_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; 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_++]; } void SaiIO::PlayOut() { ClearBuffer(); if (BSP_AUDIO_OUT_Play((uint16_t *)outBuffer_, bufferSize_*AUDIODATA_SIZE) == AUDIO_ERROR) ErrorTrap(); } 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) { 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); } 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); // 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_; }