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:
- 2018-03-12
- Revision:
- 12:61e2c3cc79a3
- Parent:
- 10:eb439bbba0f2
File content as of revision 12:61e2c3cc79a3:
//-----------------------------------------------------------
// SaiIO class
// BSP_DISCO_F746NG Rev.9 に合わせて変更
// InitInput() の内容を一部変更(変更前の部分はコメントアウト)
//
// 2017/09/17, 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)
*/
if (BSP_AUDIO_IN_OUT_Init(inputDevice, OUTPUT_DEVICE_HEADPHONE,
FS_, DEFAULT_AUDIO_IN_BIT_RESOLUTION,
DEFAULT_AUDIO_IN_CHANNEL_NBR) == 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_;
}