diff --git a/cmAudDsp.c b/cmAudDsp.c index 43801be..ddab770 100644 --- a/cmAudDsp.c +++ b/cmAudDsp.c @@ -14,6 +14,7 @@ #include "cmAudioPort.h" #include "cmAudioAggDev.h" #include "cmAudioNrtDev.h" +#include "cmAudioPortFile.h" #include "cmApBuf.h" #include "cmMidi.h" #include "cmMidiPort.h" @@ -62,6 +63,15 @@ typedef struct unsigned cbPeriodMs; } cmAdNrtDev_t; +typedef struct +{ + const cmChar_t* label; + const cmChar_t* inAudioFn; + const cmChar_t* outAudioFn; + unsigned oBits; + unsigned oChCnt; +} cmAdAfpDev_t; + typedef struct { cmErr_t err; @@ -84,6 +94,9 @@ typedef struct cmAdNrtDev_t* nrtDevArray; unsigned nrtDevCnt; + cmAdAfpDev_t* afpDevArray; + unsigned afpDevCnt; + cmAdAsCfg_t* asCfgArray; unsigned asCfgCnt; @@ -151,6 +164,7 @@ cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p ) cmJsonNode_t* asCfgArrNodePtr = NULL; cmJsonNode_t* aggDevArrNodePtr = NULL; cmJsonNode_t* nrtDevArrNodePtr = NULL; + cmJsonNode_t* afpDevArrNodePtr = NULL; cmJsonNode_t* audDspNodePtr = NULL; const cmChar_t* errLabelPtr = NULL; unsigned i; @@ -171,6 +185,7 @@ cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p ) "audioSysCfgArray", kArrayTId, &asCfgArrNodePtr, "aggDevArray", kArrayTId | kOptArgJsFl, &aggDevArrNodePtr, "nrtDevArray", kArrayTId | kOptArgJsFl, &nrtDevArrNodePtr, + "afpDevArray", kArrayTId | kOptArgJsFl, &afpDevArrNodePtr, NULL )) != kOkJsRC ) { rc = _cmAdParseMemberErr(p, jsRC, errLabelPtr, "aud_dsp" ); @@ -242,6 +257,34 @@ cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p ) } } + + } + + // parse the audio file device specifications into p->afpDevArray[]. + if( afpDevArrNodePtr != NULL && (p->afpDevCnt = cmJsonChildCount(afpDevArrNodePtr)) > 0) + { + // alloc the non-real-time spec. array + p->afpDevArray = cmMemResizeZ( cmAdAfpDev_t, p->afpDevArray, p->afpDevCnt ); + + // for each afp. device spec. recd + for(i=0; iafpDevCnt; ++i) + { + const cmJsonNode_t* np = cmJsonArrayElementC(afpDevArrNodePtr,i); + + // read afpDevArray record values + if(( jsRC = cmJsonMemberValues( np, &errLabelPtr, + "label", kStringTId, &p->afpDevArray[i].label, + "iAudioFn", kStringTId | kOptArgJsFl, &p->afpDevArray[i].inAudioFn, + "oAudioFn", kStringTId | kOptArgJsFl, &p->afpDevArray[i].outAudioFn, + "oBits", kIntTId | kOptArgJsFl, &p->afpDevArray[i].oBits, + "oChCnt", kIntTId | kOptArgJsFl, &p->afpDevArray[i].oChCnt, + NULL )) != kOkJsRC ) + { + rc = _cmAdParseMemberErr(p, jsRC, errLabelPtr, cmStringNullGuard(p->afpDevArray[i].label) ); + goto errLabel; + } + + } } @@ -368,6 +411,26 @@ cmAdRC_t _cmAdCreateNrtDevices( cmAd_t* p ) return rc; } +cmAdRC_t _cmAdCreateAfpDevices( cmAd_t* p ) +{ + cmAdRC_t rc = kOkAdRC; + + if( cmApFileAllocate(p->err.rpt) != kOkApRC ) + return cmErrMsg(&p->err,kAfpDevSysFailAdRC,"The audio file device system allocation failed."); + + unsigned i; + // create the audio file devices + for(i=0; iafpDevCnt; ++i) + { + //const cmAudioSysFilePort_t* afp = cfg->afpArray + i; + cmAdAfpDev_t* afp = p->afpDevArray + i; + if( cmApFileDeviceCreate( afp->label, afp->inAudioFn, afp->outAudioFn, afp->oBits, afp->oChCnt ) != kOkApRC ) + rc = cmErrMsg(&p->err,kAfpDevSysFailAdRC,"The audio file device '%s' creation failed.",cmStringNullGuard(afp->label)); + } + + return rc; +} + cmAdRC_t _cmAdSendAudioSysCfgLabels( cmAd_t* p) { cmAdRC_t rc = kOkAdRC; @@ -480,9 +543,15 @@ cmAdRC_t _cmAudDspFree( cmAd_t* p ) goto errLabel; } + if( cmApFileFree() != kOkApRC ) + { + rc = cmErrMsg(&p->err,kAfpDevSysFailAdRC,"The audio file device system release failed."); + goto errLabel; + } + if( cmApNrtFree() != kOkAgRC ) { - rc = cmErrMsg(&p->err,kNrtDevSysFailAdRC,"The non-real-time device system realease failed."); + rc = cmErrMsg(&p->err,kNrtDevSysFailAdRC,"The non-real-time device system release failed."); goto errLabel; } @@ -562,6 +631,10 @@ cmAdRC_t cmAudDspAlloc( cmCtx_t* ctx, cmAdH_t* hp, cmMsgSendFuncPtr_t cbFunc, vo if( _cmAdCreateNrtDevices(p) != kOkAdRC ) goto errLabel; + // create the audio file devices + if( _cmAdCreateAfpDevices(p) != kOkAdRC ) + goto errLabel; + // initialize the audio device system if( cmApInitialize(&ctx->rpt) != kOkApRC ) { diff --git a/cmAudDsp.h b/cmAudDsp.h index 04edff4..6b83faa 100644 --- a/cmAudDsp.h +++ b/cmAudDsp.h @@ -25,6 +25,7 @@ extern "C" { kAggDevSysFailAdRC, kAggDevCreateFailAdRC, kNrtDevSysFailAdRC, + kAfpDevSysFailAdRC, kNetSysFailAdRC }; diff --git a/cmAudioFileDev.c b/cmAudioFileDev.c index 3929b37..8be3080 100644 --- a/cmAudioFileDev.c +++ b/cmAudioFileDev.c @@ -220,8 +220,6 @@ cmAfdRC_t cmAudioFileDevInitialize( goto errLabel; } - - p->iPkt.devIdx = devIdx; p->iPkt.begChIdx = 0; p->iPkt.chCnt = afInfo.chCnt; // setting iPkt.chCnt to a non-zero value marks the input file as active @@ -294,6 +292,7 @@ bool cmAudioFileDevIsValid( cmAfdH_t h ) cmAfdRC_t cmAudioFileDevSetup( cmAfdH_t h, + unsigned baseDevIdx, double srate, unsigned framesPerCycle, cmApCallbackPtr_t callbackPtr, @@ -344,13 +343,14 @@ cmAfdRC_t cmAudioFileDevSetup( cmApSample_t* bp = (cmApSample_t*)p->oPkt.audioBytesPtr; - p->oPkt.devIdx = p->devIdx; + p->oPkt.devIdx = p->devIdx + baseDevIdx; p->oPkt.begChIdx = 0; p->oPkt.chCnt = p->oChCnt; p->oPkt.audioFramesCnt = framesPerCycle; p->oPkt.bitsPerSample = p->oBits; p->oPkt.flags = kFloatApFl; p->oPkt.audioBytesPtr = bp = cmMemResizeZ( cmApSample_t, bp, framesPerCycle*p->oChCnt ); + p->oPkt.userCbPtr = cbDataPtr; p->oChArray = cmMemResizeZ( cmApSample_t*, p->oChArray, p->oChCnt ); for(i=0; ioChCnt; ++i) @@ -362,8 +362,10 @@ cmAfdRC_t cmAudioFileDevSetup( { cmApSample_t* bp = (cmApSample_t*)p->iPkt.audioBytesPtr; + p->iPkt.devIdx = p->devIdx + baseDevIdx; p->iPkt.audioFramesCnt = framesPerCycle; p->iPkt.audioBytesPtr = bp = cmMemResizeZ( cmApSample_t, bp, framesPerCycle*p->iPkt.chCnt ); ; + p->iPkt.userCbPtr = cbDataPtr; for(i=0; iiPkt.chCnt; ++i) p->iChArray[i] = bp + (i*framesPerCycle); } @@ -534,7 +536,7 @@ void cmAudioFileDevTest( cmRpt_t* rpt ) if( cmAudioFileDevInitialize(&afdH,"file",devIdx,iFn,oFn,oBits,oChCnt,rpt) != kOkAfdRC ) goto errLabel; - if( cmAudioFileDevSetup(afdH,srate,framesPerCycle,_cmAfdCallback,cbDataPtr) != kOkAfdRC ) + if( cmAudioFileDevSetup(afdH,0,srate,framesPerCycle,_cmAfdCallback,cbDataPtr) != kOkAfdRC ) goto errLabel; char c; diff --git a/cmAudioFileDev.h b/cmAudioFileDev.h index 1acce13..bb11852 100644 --- a/cmAudioFileDev.h +++ b/cmAudioFileDev.h @@ -37,6 +37,7 @@ bool cmAudioFileDevIsValid( cmAfdH_t h ); /// Setup the device. This function must be called prior to cmAudioFileDevStart(). cmAfdRC_t cmAudioFileDevSetup( cmAfdH_t h, + unsigned baseApDevIdx, double srate, unsigned framesPerCycle, cmApCallbackPtr_t callbackPtr, diff --git a/cmAudioNrtDev.c b/cmAudioNrtDev.c index 1b8817b..08ac125 100644 --- a/cmAudioNrtDev.c +++ b/cmAudioNrtDev.c @@ -25,7 +25,7 @@ typedef struct typedef struct cmApNrtDev_str { unsigned flags; - unsigned devIdx; // nrt device index + unsigned devIdx; // nrt device index unsigned baseApDevIdx; // global audio device index for first nrt device cmChar_t* label; unsigned iChCnt; diff --git a/cmAudioPortFile.c b/cmAudioPortFile.c index 71b8a86..3b57e0e 100644 --- a/cmAudioPortFile.c +++ b/cmAudioPortFile.c @@ -11,6 +11,8 @@ typedef struct { cmAfdH_t devH; + unsigned devIdx; // afp dev idx + unsigned baseApDevIdx; // global audio device index for first afp device } cmApDev_t; typedef struct @@ -18,19 +20,53 @@ typedef struct cmErr_t err; cmApDev_t* devArray; unsigned devCnt; + unsigned baseApDevIdx; } cmApf_t; cmApf_t* _cmApf = NULL; -cmApRC_t cmApFileInitialize( cmRpt_t* rpt, unsigned baseApDevIdx ) +cmApRC_t cmApFileAllocate( cmRpt_t* rpt ) { - cmApRC_t rc; - if((rc = cmApFileFinalize()) != kOkApRC ) - return rc; + cmApRC_t rc = kOkApRC; + + if( _cmApf != NULL ) + cmApFileFree(); _cmApf = cmMemAllocZ(cmApf_t,1); cmErrSetup(&_cmApf->err,rpt,"Audio Port File"); + _cmApf->devArray = NULL; + _cmApf->devCnt = 0; + _cmApf->baseApDevIdx = 0; + + return rc; +} + +cmApRC_t cmApFileFree() +{ + cmApRC_t rc = kOkApRC; + + if( _cmApf == NULL ) + return rc; + + if((rc = cmApFileFinalize()) != kOkApRC ) + return rc; + + cmMemFree(_cmApf); + _cmApf = NULL; + return rc; +} + + +cmApRC_t cmApFileInitialize( cmRpt_t* rpt, unsigned baseApDevIdx ) +{ + cmApRC_t rc = kOkApRC; + + unsigned i = 0; + for(; i<_cmApf->devCnt; ++i) + _cmApf->devArray[i].baseApDevIdx = baseApDevIdx; + + _cmApf->baseApDevIdx = baseApDevIdx; return rc; } @@ -85,7 +121,12 @@ unsigned cmApFileDeviceCreate( { cmErrMsg(&_cmApf->err,kAudioPortFileFailApRC,"The audio file device initialization failed."); i = cmInvalidIdx; + goto errLabel; } + + _cmApf->devArray[i].devIdx = i; + + errLabel: return i; } @@ -134,7 +175,7 @@ cmApRC_t cmApFileDeviceSetup( { assert( devIdx < cmApFileDeviceCount()); - if( cmAudioFileDevSetup( _cmApf->devArray[devIdx].devH,srate,framesPerCycle,callbackPtr,userCbPtr) != kOkAfdRC ) + if( cmAudioFileDevSetup( _cmApf->devArray[devIdx].devH,_cmApf->baseApDevIdx,srate,framesPerCycle,callbackPtr,userCbPtr) != kOkAfdRC ) return cmErrMsg(&_cmApf->err,kAudioPortFileFailApRC,"The audio file device setup failed."); return kOkApRC; diff --git a/cmAudioPortFile.h b/cmAudioPortFile.h index b2d1a9b..9383983 100644 --- a/cmAudioPortFile.h +++ b/cmAudioPortFile.h @@ -5,6 +5,8 @@ extern "C" { #endif + cmApRC_t cmApFileAllocate( cmRpt_t* rpt ); + cmApRC_t cmApFileFree(); cmApRC_t cmApFileInitialize( cmRpt_t* rpt, unsigned baseApDevIdx ); cmApRC_t cmApFileFinalize(); diff --git a/cmAudioSys.c b/cmAudioSys.c index 03adbbc..bb7e64a 100644 --- a/cmAudioSys.c +++ b/cmAudioSys.c @@ -729,11 +729,13 @@ cmAsRC_t cmAudioSysInitialize( cmAudioSysH_t h, const cmAudioSysCfg_t* cfg ) return rc; // create the audio file devices + /* for(i=0; iafpCnt; ++i) { const cmAudioSysFilePort_t* afp = cfg->afpArray + i; cmApFileDeviceCreate( afp->devLabel, afp->inAudioFn, afp->outAudioFn, afp->oBits, afp->oChCnt ); } + */ p->ssArray = cmMemAllocZ( _cmAsCfg_t, cfg->ssCnt ); p->ssCnt = cfg->ssCnt; @@ -1281,8 +1283,8 @@ void cmAudioSysTest( cmRpt_t* rpt, int argc, const char* argv[] ) cfg.ssArray = &ss; cfg.ssCnt = 1; - cfg.afpArray= NULL; - cfg.afpCnt = 0; + //cfg.afpArray= NULL; + //cfg.afpCnt = 0; cfg.meterMs = 50; if(_cmAsGetBoolOpt(argc,argv,"-h",false)) diff --git a/cmAudioSys.h b/cmAudioSys.h index cd62915..0e0bbbb 100644 --- a/cmAudioSys.h +++ b/cmAudioSys.h @@ -172,6 +172,7 @@ extern "C" { } cmAudioSysCtx_t; + /* typedef struct { const cmChar_t* devLabel; @@ -180,15 +181,15 @@ extern "C" { unsigned oBits; unsigned oChCnt; } cmAudioSysFilePort_t; - + */ /// Audio system configuration record used by cmAudioSysAllocate(). typedef struct cmAudioSysCfg_str { cmAudioSysSubSys_t* ssArray; ///< sub-system cfg record array unsigned ssCnt; ///< count of sub-systems - cmAudioSysFilePort_t* afpArray; ///< audio port file cfg recd array - unsigned afpCnt; ///< audio port file cnt + //cmAudioSysFilePort_t* afpArray; ///< audio port file cfg recd array + //unsigned afpCnt; ///< audio port file cnt unsigned meterMs; ///< Meter sample period in milliseconds void* clientCbData; ///< User arg. for clientCbFunc(). cmTsQueueCb_t clientCbFunc; ///< Called by cmAudioSysReceiveMsg() to deliver internally generated msg's to the host.