Copyright (C) Kevin Larke 2009-2020
This file is part of libcm.
libcm is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
libcm is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
See the GNU General Public License distributed with the libcm
package or look here:
void cmApBufTest( cmRpt_t* rpt ) { unsigned devIdx = 0; unsigned devCnt = 1 ; unsigned dspFrameCnt = 10; unsigned cycleCnt = 3; unsigned framesPerCycle = 25; unsigned inChCnt = 2; unsigned outChCnt = inChCnt; unsigned sigN = cycleCnt*framesPerCycle*inChCnt; double srate = 44100.0; unsigned meterMs = 50; int srateMult = 1; unsigned bufChCnt= inChCnt; cmApSample_t* inBufArray[ bufChCnt ]; cmApSample_t* outBufArray[ bufChCnt ]; cmApSample_t iSig[ sigN ]; cmApSample_t oSig[ sigN ]; cmApSample_t* os = oSig; cmApAudioPacket_t pkt; int i,j; // create a simulated signal for(i=0; i<sigN; ++i) { iSig[i] = i; oSig[i] = 0; } pkt.devIdx = 0; pkt.begChIdx = 0; pkt.chCnt = inChCnt; pkt.audioFramesCnt = framesPerCycle; pkt.bitsPerSample = 32; pkt.flags = 0; // initialize a the audio buffer cmApBufInitialize(devCnt,meterMs); // setup the buffer with the specific parameters to by used by the host audio ports cmApBufSetup(devIdx,srate,dspFrameCnt,cycleCnt,inChCnt,framesPerCycle,outChCnt,framesPerCycle, srateMult); // simulate cylcing through sigN buffer transactions for(i=0; i<sigN; i+=framesPerCycle*inChCnt) { // setup an incoming audio packet pkt.audioFramesCnt = framesPerCycle; pkt.audioBytesPtr = iSig+i; // simulate a call from the audio port with incoming samples // (fill the audio buffers internal input buffers) cmApBufUpdate(&pkt,1,NULL,0); // if all devices need to be serviced while( cmApBufIsDeviceReady( devIdx, kInApFl | kOutApFl )) { // get pointers to full internal input buffers cmApBufGet(devIdx, kInApFl, inBufArray, bufChCnt ); // get pointers to empty internal output buffers cmApBufGet(devIdx, kOutApFl, outBufArray, bufChCnt ); // Warning: pointers to disabled channels will be set to NULL. // simulate a play through by copying the incoming samples to the outgoing buffers. for(j=0; j<bufChCnt; ++j) if( outBufArray[j] != NULL ) { // if the input is disabled - but the output is not then zero the output buffer if( inBufArray[j] == NULL ) memset( outBufArray[j], 0, dspFrameCnt*sizeof(cmApSample_t)); else // copy the input to the output memcpy( outBufArray[j], inBufArray[j], dspFrameCnt*sizeof(cmApSample_t)); } // signal the buffer that this cycle is complete. // (marks current internal input/output buffer empty/full) cmApBufAdvance( devIdx, kInApFl | kOutApFl ); } pkt.audioBytesPtr = os; // simulate a call from the audio port picking up outgoing samples // (empties the audio buffers internal output buffers) cmApBufUpdate(NULL,0,&pkt,1); os += pkt.audioFramesCnt * pkt.chCnt; } for(i=0; i<sigN; ++i) cmRptPrintf(rpt,"%f ",oSig[i]); cmRptPrintf(rpt,"\n"); cmApBufFinalize(); }