#include "cwCommon.h" #include "cwLog.h" #include "cwCommonImpl.h" #include "cwTest.h" #include "cwMem.h" #include "cwTime.h" #include "cwTextBuf.h" #include "cwAudioDevice.h" #include "cwAudioBuf.h" #include "cwAudioDeviceAlsa.h" #include "cwObject.h" #include "cwAudioDeviceTest.h" namespace cw { namespace audio { namespace device { /// [cmAudioPortExample] // See test() below for the main point of entry. // Data structure used to hold the parameters for cpApPortTest() // and the user defined data record passed to the host from the // audio port callback functions. typedef struct { const char* inDevLabel; // Input audio device label const char* outDevLabel; // Output audio device label unsigned bufCnt; // 2=double buffering 3=triple buffering unsigned framesPerCycle; // DSP frames per cycle double srate; // audio sample rate unsigned meterMs; // audio meter buffer length unsigned inDevIdx; // input device index unsigned outDevIdx; // output device index unsigned iCbCnt; // count the callback unsigned oCbCnt; double amHz; // ampl. modulation frequency double amPhs; // phase double amMaxGain; // max gain. buf::handle_t audioBufH; } cmApPortTestRecd; rc_t _cmApGetCfg( cmApPortTestRecd* r, const object_t* cfg ) { rc_t rc; r->bufCnt = 3; r->srate = 48000; r->framesPerCycle = 512; r->meterMs = 50; r->amHz = 0; r->amMaxGain = 0.8; if((rc = cfg->getv_opt("inDev",r->inDevLabel,"outDev",r->outDevLabel,"srate",r->srate,"bufN",r->bufCnt,"framesPerCycle",r->framesPerCycle,"meterMs",r->meterMs,"amHz",r->amHz,"amMaxGain",r->amMaxGain)) != kOkRC ) return cwLogError(rc,"The audio device configuration is invalid."); return rc; } void _cmApPortCb2( void* arg, audioPacket_t* inPktArray, unsigned inPktCnt, audioPacket_t* outPktArray, unsigned outPktCnt ) { cmApPortTestRecd* p = reinterpret_cast(arg); for(unsigned i=0; i(inPktArray[i].cbArg)->iCbCnt++; for(unsigned i=0; i(outPktArray[i].cbArg)->oCbCnt++; if( p->amHz > 0 && outPktCnt > 0 ) { unsigned sampleFrameN = outPktArray[0].audioFramesCnt; double amGain = p->amMaxGain * (cos( p->amPhs ) + 1.0) / 2; p->amPhs += p->amHz * sampleFrameN * M_PI / p->srate; buf::setGain( p->audioBufH, p->outDevIdx, -1, buf::kOutFl, amGain); } buf::inputToOutput( p->audioBufH, p->inDevIdx, p->outDevIdx ); buf::update( p->audioBufH, inPktArray, inPktCnt, outPktArray, outPktCnt ); } } } } // Audio Port testing function cw::rc_t cw::audio::device::test( const object_t* cfg ) { cmApPortTestRecd r; unsigned i; rc_t rc; driver_t* drv = nullptr; handle_t h; alsa::handle_t alsaH; bool runFl = true; r.oCbCnt = 0; r.iCbCnt = 0; r.amPhs = 0; // initialize the audio device interface if((rc = create(h)) != kOkRC ) { cwLogError(rc,"Initialize failed."); goto errLabel; } // initialize the ALSA device driver interface if((rc = alsa::create(alsaH, drv )) != kOkRC ) { cwLogError(rc,"ALSA initialize failed."); goto errLabel; } // register the ALSA device driver with the audio interface if((rc = registerDriver( h, drv )) != kOkRC ) { cwLogError(rc,"ALSA driver registration failed."); goto errLabel; } // report the current audio device configuration for(i=0; i