1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459 |
- #include "cmPrefix.h"
- #include "cmGlobal.h"
- #include "cmFloatTypes.h"
- #include "cmRpt.h"
- #include "cmErr.h"
- #include "cmCtx.h"
- #include "cmMem.h"
- #include "cmMallocDebug.h"
- #include "cmLinkedHeap.h"
- #include "cmSymTbl.h"
- #include "cmJson.h"
- #include "cmFileSys.h"
- #include "cmPrefs.h"
- #include "cmTime.h"
- #include "cmAudioPort.h"
- #include "cmAudioAggDev.h"
- #include "cmAudioNrtDev.h"
- #include "cmAudioPortFile.h"
- #include "cmApBuf.h"
- #include "cmMidi.h"
- #include "cmMidiPort.h"
- #include "cmSerialPort.h"
- #include "dsp/cmDspValue.h"
- #include "cmMsgProtocol.h"
- #include "cmThread.h"
- #include "cmUdpPort.h"
- #include "cmUdpNet.h"
- #include "cmAudioSys.h"
- #include "cmProcObj.h"
- #include "dsp/cmDspCtx.h"
- #include "dsp/cmDspClass.h"
- #include "dsp/cmDspSys.h"
- #include "cmAudDsp.h"
- #include "cmDspPgmJsonToDot.h"
-
- cmAdH_t cmAdNullHandle = cmSTATIC_NULL_HANDLE;
-
- typedef struct
- {
- cmDspSysH_t dsH;
- unsigned curPgmIdx;
- bool isLoadedFl;
- unsigned isSyncFl;
- } cmAdDsSubSys_t;
-
- typedef struct
- {
- const cmChar_t* label;
- bool dfltFl;
- cmAudioSysCfg_t cfg;
- } cmAdAsCfg_t;
-
- typedef struct
- {
- const cmChar_t* label;
- unsigned physDevCnt;
- unsigned* physDevIdxArray;
- } cmAdAggDev_t;
-
- typedef struct
- {
- const cmChar_t* label;
- double srate;
- unsigned iChCnt;
- unsigned oChCnt;
- 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;
- cmCtx_t ctx;
- cmMsgSendFuncPtr_t cbFunc;
- void* cbDataPtr;
- cmJsonH_t sysJsH;
- const cmChar_t* sysJsFn;
- cmUdpNetH_t netH;
- cmDspSysH_t dsH;
- cmAudioSysH_t asH;
-
- unsigned midiPortBufByteCnt;
- unsigned meterMs;
- unsigned msgsPerClientPoll;
- const cmChar_t* dfltProgramLabel;
-
- char* serialDeviceStr;
- unsigned serialBaud;
- unsigned serialCfgFlags;
- unsigned serialPollPeriodMs;
- cmSeH_t serialPortH;
-
- cmAdAggDev_t* aggDevArray;
- unsigned aggDevCnt;
-
- cmAdNrtDev_t* nrtDevArray;
- unsigned nrtDevCnt;
-
- cmAdAfpDev_t* afpDevArray;
- unsigned afpDevCnt;
-
- cmAdAsCfg_t* asCfgArray;
- unsigned asCfgCnt;
-
- unsigned curAsCfgIdx;
-
- unsigned dsSsCnt;
- cmAdDsSubSys_t* dsSsArray;
-
- bool syncFl; // all cmAdDsSubSys's are synced
- } cmAd_t;
-
- cmAd_t* _cmAdHandleToPtr( cmAdH_t h )
- {
- cmAd_t* p = (cmAd_t*)h.h;
- assert( p != NULL );
- return p;
- }
-
- // cmAudioSys DSP processing callback - this is the entry point
- // from the cmAudioSystem to the cmDspSystem. Note that it is called from the
- // the audio processing thread in cmAudioSys.c: _cmAsDeliverMsgsWithLock()
- cmRC_t _cmAudDspCallback( void *cbPtr, unsigned msgByteCnt, const void* msgDataPtr )
- {
- cmAudioSysCtx_t* ctx = (cmAudioSysCtx_t*)cbPtr;
- cmAdDsSubSys_t* p = (cmAdDsSubSys_t*)ctx->ss->cbDataPtr;
-
- if( p != NULL && p->isLoadedFl )
- return cmDspSysRcvMsg(p->dsH,ctx, msgDataPtr, msgByteCnt, ctx->srcNetNodeId );
-
- return cmOkRC;
- }
-
- // This function is called by cmAudioSysReceiveMsg() to transfer messages from the
- // cmAudioSys or cmDspSys to the client.
- cmRC_t _cmAudioSysToClientCallback(void* userCbPtr, unsigned msgByteCnt, const void* msgDataPtr )
- {
- cmAd_t* p = (cmAd_t*)userCbPtr;
- return p->cbFunc(p->cbDataPtr, msgByteCnt, msgDataPtr );
- }
-
- // This function is called by cmUdpNetReceive(), which is called in
- // cmAudioSys.c:_cmAsThreadCallback() just prior to executing the DSP process.
- void _cmAdUdpNetCallback( void* cbArg, cmUdpNetH_t h, const char* data, unsigned dataByteCnt, unsigned srcNetNodeId )
- {
- cmAd_t* p = (cmAd_t*)cbArg;
-
- // send the incoming message to the audio system for later delivery to the DSP system
- cmAudioSysDeliverMsg(p->asH, data, dataByteCnt, srcNetNodeId );
- }
-
-
- cmAdRC_t _cmAdParseMemberErr( cmAd_t* p, cmJsRC_t jsRC, const cmChar_t* errLabel, const cmChar_t* objectLabel )
- {
- if( jsRC == kNodeNotFoundJsRC && errLabel != NULL )
- return cmErrMsg(&p->err,kJsonFailAdRC,"The required field '%s'was not found in the audio DSP resource tree in the object '%s' in the file '%s'.",errLabel,cmStringNullGuard(objectLabel), cmStringNullGuard(p->sysJsFn));
-
- return cmErrMsg(&p->err,kJsonFailAdRC,"JSON parsing failed on the Audio DSP resource file '%s' in the resource object '%s'.",cmStringNullGuard(p->sysJsFn),cmStringNullGuard(objectLabel));
-
- }
-
-
- cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p )
- {
- cmAdRC_t rc = kOkAdRC;
- cmJsonNode_t* asCfgArrNodePtr = NULL;
- cmJsonNode_t* aggDevArrNodePtr = NULL;
- cmJsonNode_t* nrtDevArrNodePtr = NULL;
- cmJsonNode_t* afpDevArrNodePtr = NULL;
- cmJsonNode_t* audDspNodePtr = NULL;
- cmJsonNode_t* serialNodePtr = NULL;
- const cmChar_t* errLabelPtr = NULL;
- unsigned i;
- cmJsRC_t jsRC = kOkJsRC;
-
- // locate the aud_dsp container object
- if( cmJsonNodeMember( cmJsonRoot(p->sysJsH), "aud_dsp", &audDspNodePtr ) != kOkJsRC )
- {
- rc = cmErrMsg(&p->err,kJsonFailAdRC,"The audio DSP system resource file '%s' does not contain an 'aud_dsp' object.",cmStringNullGuard(p->sysJsFn));
- goto errLabel;
- }
-
- // locate the read the aud_dsp sub-elements
- if(( jsRC = cmJsonMemberValues( audDspNodePtr, &errLabelPtr,
- "midiPortBufByteCnt", kIntTId, &p->midiPortBufByteCnt,
- "meterMs", kIntTId, &p->meterMs,
- "msgsPerClientPoll", kIntTId, &p->msgsPerClientPoll,
- "dfltProgramLabel", kStringTId | kOptArgJsFl, &p->dfltProgramLabel,
- "audioSysCfgArray", kArrayTId, &asCfgArrNodePtr,
- "aggDevArray", kArrayTId | kOptArgJsFl, &aggDevArrNodePtr,
- "nrtDevArray", kArrayTId | kOptArgJsFl, &nrtDevArrNodePtr,
- "afpDevArray", kArrayTId | kOptArgJsFl, &afpDevArrNodePtr,
- "serial", kObjectTId | kOptArgJsFl, &serialNodePtr,
- NULL )) != kOkJsRC )
- {
- rc = _cmAdParseMemberErr(p, jsRC, errLabelPtr, "aud_dsp" );
- goto errLabel;
- }
-
- // parse the serial port cfg
- if( serialNodePtr != NULL )
- {
- if(( jsRC = cmJsonMemberValues( serialNodePtr, &errLabelPtr,
- "device", kStringTId, &p->serialDeviceStr,
- "baud", kIntTId, &p->serialBaud,
- "flags", kIntTId, &p->serialCfgFlags,
- "pollPeriodMs", kIntTId, &p->serialPollPeriodMs,
- NULL )) != kOkJsRC )
- {
- rc = _cmAdParseMemberErr(p, jsRC, errLabelPtr, "serial" );
- goto errLabel;
- }
- }
-
- // parse the aggregate device specifications into p->aggDevArray[].
- if( aggDevArrNodePtr != NULL && (p->aggDevCnt = cmJsonChildCount(aggDevArrNodePtr)) > 0)
- {
- // alloc the aggregate spec. array
- p->aggDevArray = cmMemResizeZ( cmAdAggDev_t, p->aggDevArray, p->aggDevCnt );
-
- // for each agg. device spec. recd
- for(i=0; i<p->aggDevCnt; ++i)
- {
- const cmJsonNode_t* np = cmJsonArrayElementC(aggDevArrNodePtr,i);
- const cmJsonNode_t* devIdxArrNodePtr = NULL;
- unsigned j;
-
- // read aggDevArray record values
- if(( jsRC = cmJsonMemberValues( np, &errLabelPtr,
- "label", kStringTId, &p->aggDevArray[i].label,
- "physDevIdxArray", kArrayTId, &devIdxArrNodePtr,
- NULL )) != kOkJsRC )
- {
- rc = _cmAdParseMemberErr(p, jsRC, errLabelPtr, cmStringNullGuard(p->aggDevArray[i].label) );
- goto errLabel;
- }
-
- unsigned physDevCnt = cmJsonChildCount(devIdxArrNodePtr);
-
- // alloc the dev idx array for to hold the phys. dev indexes for this agg device
- p->aggDevArray[i].physDevIdxArray = cmMemResizeZ( unsigned, p->aggDevArray[i].physDevIdxArray, physDevCnt);
- p->aggDevArray[i].physDevCnt = physDevCnt;
-
- // store the phys. dev. idx's
- for(j=0; j<physDevCnt; ++j)
- if( cmJsonUIntValue( cmJsonArrayElementC(devIdxArrNodePtr,j), p->aggDevArray[i].physDevIdxArray + j ) != kOkJsRC )
- {
- rc = cmErrMsg(&p->err,kJsonFailAdRC,"Unable to retrieve a physical device index for the aggregate device '%s'.", cmStringNullGuard(p->aggDevArray[i].label));
- goto errLabel;
- }
- }
-
- }
-
- // parse the non-real-time device specifications into p->nrtDevArray[].
- if( nrtDevArrNodePtr != NULL && (p->nrtDevCnt = cmJsonChildCount(nrtDevArrNodePtr)) > 0)
- {
- // alloc the non-real-time spec. array
- p->nrtDevArray = cmMemResizeZ( cmAdNrtDev_t, p->nrtDevArray, p->nrtDevCnt );
-
- // for each nrt. device spec. recd
- for(i=0; i<p->nrtDevCnt; ++i)
- {
- const cmJsonNode_t* np = cmJsonArrayElementC(nrtDevArrNodePtr,i);
-
- // read nrtDevArray record values
- if(( jsRC = cmJsonMemberValues( np, &errLabelPtr,
- "label", kStringTId, &p->nrtDevArray[i].label,
- "srate", kRealTId, &p->nrtDevArray[i].srate,
- "iChCnt", kIntTId, &p->nrtDevArray[i].iChCnt,
- "oChCnt", kIntTId, &p->nrtDevArray[i].oChCnt,
- "cbPeriodMs", kIntTId, &p->nrtDevArray[i].cbPeriodMs,
- NULL )) != kOkJsRC )
- {
- rc = _cmAdParseMemberErr(p, jsRC, errLabelPtr, cmStringNullGuard(p->nrtDevArray[i].label) );
- goto errLabel;
- }
-
- }
-
- }
-
- // 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; i<p->afpDevCnt; ++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;
- }
-
- }
-
- }
-
- if((p->asCfgCnt = cmJsonChildCount(asCfgArrNodePtr)) == 0 )
- goto errLabel;
-
- p->asCfgArray = cmMemResizeZ( cmAdAsCfg_t, p->asCfgArray, p->asCfgCnt);
-
- // for each cmAsAudioSysCfg record in audioSysCfgArray[]
- for(i=0; i<p->asCfgCnt; ++i)
- {
- unsigned j;
- const cmJsonNode_t* asCfgNodePtr = cmJsonArrayElementC(asCfgArrNodePtr,i);
- const cmJsonNode_t* ssArrayNodePtr = NULL;
- const char* cfgLabel = NULL;
- bool dfltFl = false;
-
- // read cmAsAudioSysCfg record values
- if(( jsRC = cmJsonMemberValues( asCfgNodePtr, &errLabelPtr,
- "label", kStringTId, &cfgLabel,
- "default", kTrueTId | kOptArgJsFl, &dfltFl,
- "ssArray", kArrayTId, &ssArrayNodePtr,
- NULL )) != kOkJsRC )
- {
- rc = _cmAdParseMemberErr(p, jsRC, errLabelPtr, cmStringNullGuard(p->asCfgArray[i].label) );
- goto errLabel;
- }
-
- p->asCfgArray[i].label = cfgLabel;
- p->asCfgArray[i].dfltFl = dfltFl;
- p->asCfgArray[i].cfg.ssCnt = cmJsonChildCount( ssArrayNodePtr );
- p->asCfgArray[i].cfg.ssArray = cmMemResizeZ( cmAudioSysSubSys_t, p->asCfgArray[i].cfg.ssArray, p->asCfgArray[i].cfg.ssCnt );
- p->asCfgArray[i].cfg.clientCbFunc = _cmAudioSysToClientCallback;
- p->asCfgArray[i].cfg.clientCbData = p;
-
-
- // for each audio system sub-subsystem
- for(j=0; j<p->asCfgArray[i].cfg.ssCnt; ++j)
- {
- cmAudioSysArgs_t* asap = &p->asCfgArray[i].cfg.ssArray[j].args;
- const cmJsonNode_t* argsNodePtr = cmJsonArrayElementC(ssArrayNodePtr,j);
-
- if((jsRC = cmJsonMemberValues( argsNodePtr, &errLabelPtr,
- "inDevIdx", kIntTId, &asap->inDevIdx,
- "outDevIdx", kIntTId, &asap->outDevIdx,
- "syncToInputFl", kTrueTId, &asap->syncInputFl,
- "msgQueueByteCnt", kIntTId, &asap->msgQueueByteCnt,
- "devFramesPerCycle", kIntTId, &asap->devFramesPerCycle,
- "dspFramesPerCycle", kIntTId, &asap->dspFramesPerCycle,
- "audioBufCnt", kIntTId, &asap->audioBufCnt,
- "srate", kRealTId, &asap->srate,
- NULL )) != kOkJsRC )
- {
- rc = _cmAdParseMemberErr(p, jsRC, errLabelPtr, cmStringNullGuard(p->asCfgArray[i].label));
- goto errLabel;
- }
-
- }
-
-
- }
- errLabel:
-
- return rc;
- }
-
- cmAdRC_t _cmAdSetup( cmAd_t* p )
- {
- unsigned i;
- cmAdRC_t rc = kOkAdRC;
-
- for(i=0; i<p->asCfgCnt; ++i)
- {
- unsigned j;
-
- p->asCfgArray[i].cfg.meterMs = p->meterMs;
-
- // BUG BUG BUG - each sub-system should have it's own network
- // manager, and socket port.
-
- p->asCfgArray[i].cfg.netH = p->netH;
-
- for(j=0; j<p->asCfgArray[i].cfg.ssCnt; ++j)
- {
- p->asCfgArray[i].cfg.ssArray[j].cbDataPtr = NULL;
- p->asCfgArray[i].cfg.ssArray[j].cbFunc = _cmAudDspCallback;
- p->asCfgArray[i].cfg.ssArray[j].args.rpt = p->err.rpt;
- }
- }
-
- return rc;
- }
-
- cmAdRC_t _cmAdCreateSerialPort( cmAd_t* p )
- {
- cmAdRC_t rc = kOkAdRC;
-
- if( p->serialDeviceStr != NULL )
- {
- p->serialPortH = cmSeCreate( &p->ctx, &p->serialPortH, p->serialDeviceStr, p->serialBaud, p->serialCfgFlags, NULL, NULL, p->serialPollPeriodMs );
-
- if( !cmSeIsOpen(p->serialPortH) )
- {
- rc = cmErrMsg(&p->err,kSerialDevCreateFailAdRC,"The serial device '%s' creation failed.",cmStringNullGuard(p->serialDeviceStr));
- }
- }
- return rc;
- }
-
- cmAdRC_t _cmAdCreateAggDevices( cmAd_t* p )
- {
- cmAdRC_t rc = kOkAdRC;
- unsigned i;
-
- if( cmApAggAllocate(p->err.rpt) != kOkAgRC )
- return cmErrMsg(&p->err,kAggDevSysFailAdRC,"The aggregate device system allocation failed.");
-
- for(i=0; i<p->aggDevCnt; ++i)
- {
- cmAdAggDev_t* adp = p->aggDevArray + i;
- if( cmApAggCreateDevice(adp->label,adp->physDevCnt,adp->physDevIdxArray,kInAggFl | kOutAggFl) != kOkAgRC )
- rc = cmErrMsg(&p->err,kAggDevCreateFailAdRC,"The aggregate device '%s' creation failed.",cmStringNullGuard(adp->label));
- }
-
- return rc;
- }
-
- cmAdRC_t _cmAdCreateNrtDevices( cmAd_t* p )
- {
- cmAdRC_t rc = kOkAdRC;
- unsigned i;
-
- if( cmApNrtAllocate(p->err.rpt) != kOkApRC )
- return cmErrMsg(&p->err,kNrtDevSysFailAdRC,"The non-real-time device system allocation failed.");
-
- for(i=0; i<p->nrtDevCnt; ++i)
- {
- cmAdNrtDev_t* adp = p->nrtDevArray + i;
- if( cmApNrtCreateDevice(adp->label,adp->srate,adp->iChCnt,adp->oChCnt,adp->cbPeriodMs) != kOkApRC )
- rc = cmErrMsg(&p->err,kNrtDevSysFailAdRC,"The non-real-time device '%s' creation failed.",cmStringNullGuard(adp->label));
- }
-
- 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; i<p->afpDevCnt; ++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;
- unsigned i;
-
- for(i=0; i<p->asCfgCnt; ++i)
- {
- cmDspValue_t v;
- cmDsvSetStrcz(&v, p->asCfgArray[i].label);
-
- if( cmMsgSend( &p->err,cmInvalidIdx,kUiSelAsId,kAudioSysCfgDuiId,0,i,p->asCfgCnt,&v,p->cbFunc,p->cbDataPtr) != kOkMsgRC )
- {
- rc = cmErrMsg(&p->err,kSendMsgFailAdRC,"Error sending audio system cfg. label message to host.");
- break;
- }
-
- }
- return rc;
- }
-
- cmAdRC_t _cmAdSendAudioSysCfgDefault( cmAd_t* p)
- {
- cmAdRC_t rc = kOkAdRC;
- unsigned i;
-
- for(i=0; i<p->asCfgCnt; ++i)
- if( p->asCfgArray[i].dfltFl )
- {
- cmDspValue_t v;
- cmDsvSetStrcz(&v, p->asCfgArray[i].label);
-
- if( cmMsgSend( &p->err,cmInvalidIdx,kUiSelAsId,kAudioSysCfgDfltDuiId,0,i,p->asCfgCnt,&v,p->cbFunc,p->cbDataPtr) != kOkMsgRC )
- rc = cmErrMsg(&p->err,kSendMsgFailAdRC,"Error sending audio system default cfg. label message to host.");
-
- break;
-
- }
-
- return rc;
- }
-
-
- cmAdRC_t _cmAdSendDeviceLabels( cmAd_t* p )
- {
- cmAdRC_t rc = kOkAdRC;
- unsigned i,j;
-
- unsigned n = cmApDeviceCount();
-
- for(i=0; i<2; ++i)
- {
- bool inputFl = i==0;
-
- for(j=0; j<n; ++j)
- if( cmApDeviceChannelCount(j,inputFl) )
- {
- cmDspValue_t v;
- cmDsvSetStrcz(&v, cmApDeviceLabel(j));
-
- if( cmMsgSend( &p->err,cmInvalidIdx,kUiSelAsId,kDeviceDuiId,inputFl,j,n,&v,p->cbFunc,p->cbDataPtr) != kOkMsgRC )
- {
- rc = cmErrMsg(&p->err,kSendMsgFailAdRC,"Error sending device label message to host.");
- break;
- }
-
- }
-
- }
- return rc;
- }
-
- cmAdRC_t _cmAdSendProgramLabels( cmAd_t* p )
- {
- cmAdRC_t rc = kOkAdRC;
- unsigned pgmCnt = cmDspSysPgmCount(p->dsH);
- unsigned i;
-
- for(i=0; i<pgmCnt; ++i)
- {
- cmDspValue_t v;
- cmDsvSetStrcz(&v, cmDspPgmLabel(p->dsH,i));
-
- if( cmMsgSend( &p->err,cmInvalidIdx,kUiSelAsId,kProgramDuiId,0,i,pgmCnt,&v,p->cbFunc,p->cbDataPtr) != kOkMsgRC )
- {
- rc = cmErrMsg(&p->err,kSendMsgFailAdRC,"Error sending program label message to host.");
- break;
- }
-
- }
-
- return rc;
- }
-
- cmAdRC_t _cmAdSendProgramDefault( cmAd_t* p)
- {
- cmAdRC_t rc = kOkAdRC;
-
- if( p->dfltProgramLabel != NULL )
- {
- cmDspValue_t v;
- cmDsvSetStrcz(&v, p->dfltProgramLabel);
-
- if( cmMsgSend( &p->err,cmInvalidIdx,kUiSelAsId,kProgramDfltDuiId,0,0,0,&v,p->cbFunc,p->cbDataPtr) != kOkMsgRC )
- rc = cmErrMsg(&p->err,kSendMsgFailAdRC,"Error sending default program label message to host.");
- }
-
- return rc;
- }
-
-
- cmAdRC_t _cmAudDspFree( cmAd_t* p )
- {
- cmAdRC_t rc = kOkAdRC;
-
- if( cmAudioSysFree(&p->asH) != kOkAsRC )
- {
- rc = cmErrMsg(&p->err,kAudioSysFailAdRC,"The audio system release failed.");
- goto errLabel;
- }
-
- if( cmDspSysFinalize(&p->dsH) != kOkDspRC )
- {
- rc = cmErrMsg(&p->err,kDspSysFailAdRC,"DSP system finalization failed.");
- goto errLabel;
- }
-
- if( cmUdpNetFree(&p->netH) != kOkUnRC )
- {
- rc = cmErrMsg(&p->err,kNetSysFailAdRC,"UDP Network finalization failed.");
- goto errLabel;
- }
-
- if( cmSeIsOpen(p->serialPortH) )
- {
- if( cmSeDestroy(&p->serialPortH) != kOkSeRC )
- {
- rc = cmErrMsg(&p->err,kSerialPortFailAdRC,"Serial port finalize failed.");
- goto errLabel;
- }
- }
-
- if( cmMpIsInitialized() )
- if( cmMpFinalize() != kOkMpRC )
- {
- rc = cmErrMsg(&p->err,kMidiSysFailAdRC,"MIDI system finalization failed.");
- goto errLabel;
- }
-
- if( cmApFinalize() != kOkApRC )
- {
- rc = cmErrMsg(&p->err,kAudioPortFailAdRC,"Audio port finalization failed.");
- goto errLabel;
- }
-
- if( cmApBufFinalize() != kOkApRC )
- {
- rc = cmErrMsg(&p->err,kAudioPortFailAdRC,"Audio port buffer finalization failed.");
- 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 release failed.");
- goto errLabel;
- }
-
- if( cmApAggFree() != kOkAgRC )
- {
- rc = cmErrMsg(&p->err,kAggDevSysFailAdRC,"The aggregate device system release failed.");
- goto errLabel;
- }
-
- cmMemPtrFree(&p->nrtDevArray);
-
- unsigned i;
- for(i=0; i<p->aggDevCnt; ++i)
- cmMemPtrFree(&p->aggDevArray[i].physDevIdxArray);
-
- cmMemPtrFree(&p->aggDevArray);
-
- for(i=0; i<p->asCfgCnt; ++i)
- cmMemPtrFree(&p->asCfgArray[i].cfg.ssArray);
-
- cmMemPtrFree(&p->asCfgArray);
-
- cmMemPtrFree(&p->dsSsArray);
-
- if( cmJsonFinalize(&p->sysJsH) != kOkJsRC )
- {
- rc = cmErrMsg(&p->err,kJsonFailAdRC,"System JSON tree finalization failed.");
- goto errLabel;
- }
-
- if( p->sysJsFn != NULL )
- cmFsFreeFn(p->sysJsFn);
-
- cmMemFree(p);
-
- errLabel:
-
- return rc;
- }
-
- cmAdRC_t cmAudDspAlloc( cmCtx_t* ctx, cmAdH_t* hp, cmMsgSendFuncPtr_t cbFunc, void* cbDataPtr )
- {
-
- cmAdRC_t rc = kOkAdRC;
- cmAdRC_t rc0 = kOkAdRC;
-
- if((rc = cmAudDspFree(hp)) != kOkAdRC )
- return rc;
-
- cmAd_t* p = cmMemAllocZ(cmAd_t,1);
-
- cmErrSetup(&p->err,&ctx->rpt,"Audio DSP Engine");
-
- // form the audio dsp resource file name
- if((p->sysJsFn = cmFsMakeFn( cmFsPrefsDir(),cmAudDspSys_FILENAME,NULL,NULL)) == NULL )
- {
- rc = cmErrMsg(&p->err,kFileSysFailAdRC,"Unable to form the audio dsp system resource file name.");
- goto errLabel;
- }
-
- // open the audio dsp resource file
- if(cmJsonInitializeFromFile(&p->sysJsH,p->sysJsFn,ctx) != kOkJsRC )
- {
- rc = cmErrMsg(&p->err,kJsonFailAdRC,"Unable to open the audio dsp resource file: '%s'.",cmStringNullGuard(p->sysJsFn));
- goto errLabel;
- }
-
- // parse the JSON tree
- if((rc = _cmAdParseSysJsonTree(p)) != kOkAdRC )
- goto errLabel;
-
- // create the aggregate device
- if( _cmAdCreateAggDevices(p) != kOkAdRC )
- goto errLabel;
-
- // create the non-real-time devices
- 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 )
- {
- rc = cmErrMsg(&p->err,kAudioPortFailAdRC,"Audio port intialization failed.");
- goto errLabel;
- }
-
- // initialize the audio buffer
- if( cmApBufInitialize( cmApDeviceCount(), p->meterMs ) != kOkApRC )
- {
- rc = cmErrMsg(&p->err,kAudioPortFailAdRC,"Audio port buffer initialization failed.");
- goto errLabel;
- }
-
- // create the serial port
- if( _cmAdCreateSerialPort(p) != kOkAdRC )
- {
- rc = cmErrMsg(&p->err,kSerialPortFailAdRC,"The MIDI system initialization failed.");
- goto errLabel;
- }
-
- // initialize the MIDI system
- if( cmMpInitialize(ctx,NULL,NULL,p->midiPortBufByteCnt,"app") != kOkMpRC )
- {
- rc = cmErrMsg(&p->err,kMidiSysFailAdRC,"The MIDI system initialization failed.");
- goto errLabel;
- }
-
- // initialize the UDP network - but do not go into 'listening' mode.
- if( cmUdpNetAllocJson(ctx,&p->netH,p->sysJsH,_cmAdUdpNetCallback,p,kNetOptionalUnFl) != kOkUnRC )
- {
- cmErrMsg(&p->err,kNetSysFailAdRC,"The UDP network initialization failed.");
- goto errLabel;
- }
-
- if((rc = _cmAdSetup(p)) != kOkAdRC )
- goto errLabel;
-
- // initialize the DSP system
- if( cmDspSysInitialize(ctx,&p->dsH,p->netH,p->serialPortH) )
- {
- rc = cmErrMsg(&p->err,kDspSysFailAdRC,"The DSP system initialization failed.");
- goto errLabel;
- }
-
- // allocate the audio system
- if( cmAudioSysAllocate(&p->asH, &ctx->rpt, NULL ) != kOkAsRC )
- {
- rc = cmErrMsg(&p->err,kAudioSysFailAdRC,"The audio system allocation failed.");
- goto errLabel;
- }
-
- p->cbFunc = cbFunc;
- p->cbDataPtr = cbDataPtr;
- p->curAsCfgIdx = cmInvalidIdx;
- p->ctx = *ctx;
-
-
- hp->h = p;
-
- errLabel:
-
-
- if( rc != kOkAdRC )
- rc0 = _cmAudDspFree(p);
-
- return rc == kOkAdRC ? rc0 : rc;
- }
-
- cmAdRC_t cmAudDspFree( cmAdH_t* hp )
- {
- cmAdRC_t rc = kOkAdRC;
-
- if( hp == NULL || cmAudDspIsValid(*hp)==false )
- return kOkAdRC;
-
- cmAd_t* p = _cmAdHandleToPtr(*hp);
-
- if((rc = _cmAudDspFree(p)) != kOkAdRC )
- return rc;
-
- hp->h = NULL;
-
- return rc;
- }
-
- cmAdRC_t cmAudDspSendSetup( cmAdH_t h )
- {
- cmAdRC_t rc = kOkAdRC;
- cmAd_t* p = _cmAdHandleToPtr( h );
-
- // notify the client of the available audio system configurations
- if((rc = _cmAdSendAudioSysCfgLabels(p)) != kOkAdRC )
- goto errLabel;
-
- // notify the client of the available devices
- if((rc = _cmAdSendDeviceLabels(p)) != kOkAdRC)
- goto errLabel;
-
- // notify the client of the available programs
- if((rc = _cmAdSendProgramLabels(p)) != kOkAdRC )
- goto errLabel;
-
- // notify the client of the default audio sys cfg
- if((rc= _cmAdSendAudioSysCfgDefault(p)) != kOkAdRC )
- goto errLabel;
-
- // notify the client of the default program
- if((rc= _cmAdSendProgramDefault(p)) != kOkAdRC )
- goto errLabel;
-
-
- errLabel:
- return rc;
- }
-
- bool cmAudDspIsValid( cmAdH_t h )
- { return h.h != NULL; }
-
-
- cmAdRC_t _cmAudDspUnloadPgm( cmAd_t* p, unsigned asSubSysIdx )
- {
- cmAdRC_t rc = kOkAdRC;
- const cmAdAsCfg_t* cfgPtr = NULL;
-
- // Must disable audio thread callbacks to _cmAudDspCallback()
- // while changing DSP system data structures.
- if( cmAudioSysIsEnabled(p->asH) )
- if(cmAudioSysEnable(p->asH,false) != kOkAsRC )
- {
- rc = cmErrMsg(&p->err,kAudioSysFailAdRC,"The audio system could not be disabled.");
- goto errLabel;
- }
-
- // validate the sub-system index
- if( asSubSysIdx >= p->dsSsCnt )
- {
- rc = cmErrMsg(&p->err,kInvalidSubSysIdxAdRC,"The invalid sub-system index %i was encountered while unloading a program.",asSubSysIdx);
- goto errLabel;
- }
-
- // if a valid cfg recd exists
- if( p->curAsCfgIdx != cmInvalidIdx )
- {
- // pointer to audio system configuration
- cfgPtr = p->asCfgArray + p->curAsCfgIdx;
-
- // count of audio system sub-systems should be the same as the current cfg
- assert( p->dsSsCnt == cfgPtr->cfg.ssCnt );
-
- // mark the DSP program as unloaded and pre-sync
- p->dsSsArray[ asSubSysIdx ].isLoadedFl = false;
- p->dsSsArray[ asSubSysIdx ].isSyncFl = false;
- p->syncFl = false;
- }
-
- // unload the current program
- if( cmDspSysUnload(p->dsSsArray[asSubSysIdx].dsH) != kOkDspRC )
- {
- rc = cmErrMsg(&p->err,kDspSysFailAdRC,"Program unload failed.");
- goto errLabel;
- }
-
-
- errLabel:
- return rc;
- }
-
-
- cmAdRC_t _cmAudDspUnloadAudioSys( cmAd_t* p )
- {
- unsigned i;
- cmAdRC_t rc = kOkAdRC;
-
- p->syncFl = false;
-
- for(i=1; i<p->dsSsCnt; ++i)
- {
- if((rc = _cmAudDspUnloadPgm(p,i)) != kOkAdRC )
- goto errLabel;
-
- if( cmDspSysFinalize(&p->dsSsArray[i].dsH) != kOkDspRC )
- {
- rc = cmErrMsg(&p->err,kDspSysFailAdRC,"DSP system finalization failed.");
- goto errLabel;
- }
- }
-
- p->curAsCfgIdx = cmInvalidIdx;
-
- errLabel:
- return rc;
- }
-
- cmAdRC_t _cmAdSendIntMsgToHost( cmAd_t* p, unsigned asSubIdx, unsigned selId, unsigned flags, unsigned intValue )
- {
- cmAdRC_t rc = kOkAdRC;
- cmDspValue_t v;
- cmDsvSetUInt(&v,intValue);
-
- if( cmMsgSend( &p->err,asSubIdx,kUiSelAsId,selId,flags,cmInvalidId,cmInvalidId,&v,p->cbFunc,p->cbDataPtr) != kOkMsgRC )
- rc = cmErrMsg(&p->err,kSendMsgFailAdRC,"Error sending message to host.");
-
- return rc;
- }
-
- // verify that a valid audio cfg has been selected
- cmAdRC_t _cmAdIsAudioSysLoaded( cmAd_t* p )
- {
- cmAdRC_t rc = kOkAdRC;
-
- if( cmAudioSysHandleIsValid(p->asH) == false )
- {
- rc = cmErrMsg(&p->err,kAudioSysFailAdRC,"The audio system is not allocated.");
- goto errLabel;
- }
-
- if( p->curAsCfgIdx == cmInvalidIdx )
- return kInvalidCfgIdxAdRC;
-
- // verify that an audio system is loaded
- if( cmAudioSysIsInitialized(p->asH) && p->curAsCfgIdx == cmInvalidIdx )
- {
- rc = cmErrMsg(&p->err,kInvalidCfgIdxAdRC,"The audio system has not been configured.");
- goto errLabel;
- }
-
- // count of audio system sub-systems should be the same as the current cfg
- assert( p->dsSsCnt == p->asCfgArray[p->curAsCfgIdx].cfg.ssCnt );
-
- errLabel:
- return rc;
- }
-
- // verify that a valid audio cfg and DSP program has been selected
- cmAdRC_t _cmAdIsPgmLoaded( cmAd_t* p, bool verboseFl )
- {
- cmAdRC_t rc;
-
- // a program cannot be loaded if the audio system has not been configured
- if((rc = _cmAdIsAudioSysLoaded(p)) != kOkAdRC )
- return rc;
-
- unsigned i;
-
- // for each sub-system
- for(i=0; i<p->dsSsCnt; ++i)
- {
- // verify that the DSP system has been created
- if( cmDspSysIsValid(p->dsSsArray[i].dsH) == false )
- return cmErrMsg(&p->err,kDspSysFailAdRC,"The DSP sub-system at index %i is not initialized.",i);
-
- // verify that the DSP program was loaded
- if( p->dsSsArray[ i ].isLoadedFl == false )
- {
- if( verboseFl )
- cmErrMsg(&p->err,kNoPgmLoadedAdRC,"There is no program loaded.");
-
- return kNoPgmLoadedAdRC;
- }
- }
-
- return rc;
- }
-
- bool _cmAudDspIsPgmSynced( cmAd_t* p )
- {
- unsigned syncCnt = 0;
- unsigned i;
-
- if( p->syncFl )
- return true;
-
- // if the pgm is not loaded then it cannot be sync'd
- if(_cmAdIsPgmLoaded(p,false) != kOkAdRC )
- return false;
-
- // check each sub-system
- for(i=0; i<p->dsSsCnt; ++i)
- {
- unsigned syncState = cmDspSysSyncState(p->dsSsArray[i].dsH);
-
- // if the subsys is already synced
- if( p->dsSsArray[i].isSyncFl )
- ++syncCnt;
- else
- {
- switch( syncState )
- {
- // the sub-sys is pre or pending sync mode
- case kSyncPreDspId:
- case kSyncPendingDspId:
- break;
-
- // sync mode completed - w/ success or fail
- case kSyncSuccessDspId:
- case kSyncFailDspId:
- {
- // notify the client of the the sync state
- bool syncFl = syncState == kSyncSuccessDspId;
- _cmAdSendIntMsgToHost(p,cmInvalidIdx,kSyncDuiId,syncFl,cmInvalidIdx);
- p->dsSsArray[i].isSyncFl = syncFl;
- }
- break;
-
- }
- }
- }
-
- p->syncFl = syncCnt == p->dsSsCnt;
-
- return p->syncFl;
- }
-
-
- cmAdRC_t _cmAudDspLoadPgm( cmAd_t* p, unsigned asSubSysIdx, unsigned pgmIdx )
- {
- cmAdRC_t rc = kOkAdRC;
- unsigned i;
-
- p->syncFl = false;
-
- // the audio system must be configured before a program is loaded
- if((rc = _cmAdIsAudioSysLoaded(p)) != kOkAdRC )
- return cmErrMsg(&p->err,rc,"The audio system is not configured. Program load failed.");
-
- // validate the sub-system index arg.
- if( asSubSysIdx!=cmInvalidIdx && asSubSysIdx >= p->dsSsCnt )
- {
- rc = cmErrMsg(&p->err,kInvalidSubSysIdxAdRC,"The sub-system index %i is invalid. Program load failed.",asSubSysIdx);
- goto errLabel;
- }
-
- // for each sub-system
- for(i=0; i<p->dsSsCnt; ++i)
- if( asSubSysIdx==cmInvalidIdx || i==asSubSysIdx )
- {
- // unload any currently loaded program on this sub-system
- // (unloading a program automatically disables the audio system)
- if((rc = _cmAudDspUnloadPgm(p, i )) != kOkAdRC )
- goto errLabel;
-
- // load the program
- if( cmDspSysLoad(p->dsSsArray[ i ].dsH, cmAudioSysContext(p->asH,i), pgmIdx ) != kOkDspRC )
- {
- rc = cmErrMsg(&p->err,kDspSysFailAdRC,"The program load failed on audio sub-system %i.",i);
- goto errLabel;
- }
-
- // update the state of the DSP sub-system
- p->dsSsArray[i].curPgmIdx = pgmIdx;
- p->dsSsArray[i].isLoadedFl = true;
- p->dsSsArray[i].isSyncFl = false;
- p->syncFl = false;
-
- // notify the host of the new program
- _cmAdSendIntMsgToHost(p,i,kSetPgmDuiId,0,pgmIdx);
- }
-
- errLabel:
- return rc;
- }
-
- cmAdRC_t _cmAudDspPrintPgm( cmAd_t* p, unsigned asSubSysIdx, const cmChar_t* fn )
- {
- cmAdRC_t rc = kOkAdRC;
- unsigned i;
-
- // the audio system must be configured before a program is loaded
- if((rc = _cmAdIsAudioSysLoaded(p)) != kOkAdRC )
- return cmErrMsg(&p->err,rc,"The audio system is not configured. Program print failed.");
-
- // validate the sub-system index arg.
- if( asSubSysIdx!=cmInvalidIdx && asSubSysIdx >= p->dsSsCnt )
- {
- rc = cmErrMsg(&p->err,kInvalidSubSysIdxAdRC,"The sub-system index %i is invalid. Program print failed.",asSubSysIdx);
- goto errLabel;
- }
-
- // for each sub-system
- for(i=0; i<p->dsSsCnt; ++i)
- if( i==asSubSysIdx || asSubSysIdx==cmInvalidIdx )
- {
- if( cmDspSysPrintPgm(p->dsSsArray[i].dsH,fn) != kOkDspRC )
- rc = cmErrMsg(&p->err,kDspSysFailAdRC,"The program print failed.");
- else
- {
- if( cmDspPgmJsonToDot(&p->ctx,fn,fn) != kOkDspRC )
- rc = cmErrMsg(&p->err,kDspSysFailAdRC,"The program print conversion to DOT failed.");
- }
-
- break;
- }
-
- errLabel:
- return rc;
- }
-
- cmAdRC_t _cmAdReinitAudioSys( cmAd_t* p )
- {
- cmAdRC_t rc = kOkAdRC;
-
- p->syncFl = false;
-
- // pointer to the new audio system configuration
- cmAdAsCfg_t* cfgPtr = p->asCfgArray + p->curAsCfgIdx;
-
- // initialize the audio system
- if( cmAudioSysInitialize(p->asH, &cfgPtr->cfg ) != kOkAsRC )
- {
- rc = cmErrMsg(&p->err,kAudioSysFailAdRC,"The audio system initialization failed.");
- goto errLabel;
- }
-
- // reload any currently loaded programs
- unsigned i;
- for(i=0; i<p->dsSsCnt; ++i)
- {
- unsigned pgmIdx;
- if((pgmIdx = p->dsSsArray[i].curPgmIdx) != cmInvalidIdx )
- if((rc = _cmAudDspLoadPgm(p,i,pgmIdx)) != kOkAdRC )
- break;
- }
-
- errLabel:
- return rc;
- }
-
- cmAdRC_t _cmAudDspLoadAudioSys( cmAd_t* p, unsigned asCfgIdx )
- {
- cmAdRC_t rc = kOkAdRC;
- cmAdAsCfg_t* cfgPtr;
- unsigned i;
-
- // validate asCfgIdx
- if( asCfgIdx >= p->asCfgCnt )
- {
- cmErrMsg(&p->err,kInvalidCfgIdxAdRC,"The audio system index %i is invalid.",asCfgIdx);
- goto errLabel;
- }
-
- // clear the current audio system setup - this will automatically disable the audio system
- if((rc = _cmAudDspUnloadAudioSys(p)) != kOkAdRC )
- goto errLabel;
-
- // pointer to the new audio system configuration
- cfgPtr = p->asCfgArray + asCfgIdx;
-
- // get the count of audio system sub-systems
- p->dsSsCnt = cfgPtr->cfg.ssCnt;
-
- // store the index of the current audio system configuration
- p->curAsCfgIdx = asCfgIdx;
-
- if( p->dsSsCnt > 0 )
- {
- p->dsSsArray = cmMemResizeZ(cmAdDsSubSys_t, p->dsSsArray, p->dsSsCnt );
-
- for(i=0; i<p->dsSsCnt; ++i)
- {
- cmDspSysH_t dsH;
-
- // the first sub-system will always use the existing DSP system handle ...
- if( i==0 )
- dsH = p->dsH;
- else
- {
- // ... and allocate additional DSP systems when more than one sub-sys is
- // defined in the audio system configuration
- if( cmDspSysInitialize(&p->ctx,&dsH,p->netH,p->serialPortH) != kOkDspRC )
- {
- rc = cmErrMsg(&p->err,kDspSysFailAdRC,"Unable to initialize an additional DSP system.");
- goto errLabel;
- }
- }
-
- p->dsSsArray[i].dsH = dsH;
- p->dsSsArray[i].curPgmIdx = cmInvalidIdx;
- p->dsSsArray[i].isLoadedFl= false;
-
- // this cbDataPtr is picked up in _cmAudDspCallback().
- // It is used to connect the audio system to a DSP system handle.
- cfgPtr->cfg.ssArray[i].cbDataPtr = p->dsSsArray + i;
-
- }
- }
-
- // notify the client of the change of audio configuration
- _cmAdSendIntMsgToHost(p,cmInvalidIdx,kSetAudioCfgDuiId,0,asCfgIdx);
-
- // notify the client of the count of audio sub-systems
- _cmAdSendIntMsgToHost(p,cmInvalidIdx,kSubSysCntDuiId,0,p->dsSsCnt);
-
- // for each sub-system
- for(i=0; i<p->dsSsCnt; ++i)
- {
- // notify the client of the currently selected devices
- _cmAdSendIntMsgToHost(p,i,kSetAudioDevDuiId,true, cfgPtr->cfg.ssArray[i].args.inDevIdx);
- _cmAdSendIntMsgToHost(p,i,kSetAudioDevDuiId,false,cfgPtr->cfg.ssArray[i].args.outDevIdx);
-
- // notify the client of the sample rate
- _cmAdSendIntMsgToHost(p,i,kSetSampleRateDuiId,0,(unsigned)cfgPtr->cfg.ssArray[i].args.srate);
-
- _cmAdSendIntMsgToHost(p,i,kSetPgmDuiId,0,cmInvalidIdx);
- }
-
- // the audio system configuration changed so we need to initialize the audio system
- if((rc = _cmAdReinitAudioSys(p)) != kOkAdRC )
- goto errLabel;
-
- errLabel:
- if( rc != kOkAdRC )
- _cmAudDspUnloadAudioSys(p);
-
- return rc;
- }
-
-
-
- cmAdRC_t _cmAudDspEnableAudio( cmAd_t* p, bool enableFl )
- {
- cmAdRC_t rc = kOkAdRC;
-
- if( enableFl )
- {
- // verify an audio system cfg and DSP program has been selected
- if(( rc = _cmAdIsPgmLoaded(p,true)) != kOkAdRC )
- return cmErrMsg(&p->err,rc,"Audio enable failed.");
-
- // if the audio system is already enabled/disabled then do nothing
- if( cmAudioSysIsEnabled(p->asH) == enableFl )
- return kOkAdRC;
-
- // for each sub-system
- unsigned i;
- for(i=0; i<p->dsSsCnt; ++i)
- {
- if( cmDspSysReset(p->dsSsArray[i].dsH) != kOkDspRC )
- {
- rc = cmErrMsg(&p->err,kDspSysFailAdRC,"The DSP system reset failed.");
- goto errLabel;
- }
- }
-
- }
-
- // start/stop the audio sub-system
- if( cmAudioSysEnable(p->asH,enableFl) != kOkAsRC )
- {
- rc = cmErrMsg(&p->err,kAudioSysFailAdRC,"The audio system %s failed.", enableFl ? "enable" : "disable");
- goto errLabel;
- }
-
- // notify the host of the new enable state
- _cmAdSendIntMsgToHost(p,cmInvalidIdx,kEnableDuiId,enableFl,cmInvalidIdx);
-
- errLabel:
- return rc;
-
- }
-
- cmAdRC_t _cmAudDspSetDevice(cmAd_t* p,unsigned asSubIdx, bool inputFl, unsigned devIdx)
- {
- cmAdRC_t rc;
-
- // a device cannot be set if the audio system is not already configured
- if((rc = _cmAdIsAudioSysLoaded(p)) != kOkAdRC )
- return cmErrMsg(&p->err,rc,"Set audio device failed.");
-
- cmAdAsCfg_t* cfgPtr = p->asCfgArray + p->curAsCfgIdx;
-
- // validate the sub-system index
- if( asSubIdx >= p->dsSsCnt )
- {
- rc = cmErrMsg(&p->err,kInvalidSubSysIdxAdRC,"The sub-system index %i is invalid.",asSubIdx);
- goto errLabel;
- }
-
- // assign the new device index to the indicated audio system configuration recd
- if( inputFl )
- {
- if( cfgPtr->cfg.ssArray[ asSubIdx ].args.inDevIdx != devIdx )
- cfgPtr->cfg.ssArray[ asSubIdx ].args.inDevIdx = devIdx;
-
- }
- else
- {
- if( cfgPtr->cfg.ssArray[ asSubIdx ].args.outDevIdx != devIdx )
- cfgPtr->cfg.ssArray[ asSubIdx ].args.outDevIdx = devIdx;
- }
-
- // notify the host that the new device has been set
- _cmAdSendIntMsgToHost(p,asSubIdx,kSetAudioDevDuiId,inputFl, devIdx);
-
- // reinitialize the audio system
- rc = _cmAdReinitAudioSys(p);
-
- errLabel:
-
- return rc;
- }
-
- cmAdRC_t _cmAudDspSetSampleRate(cmAd_t* p, unsigned asSubIdx, double srate )
- {
- cmAdRC_t rc;
-
- if((rc = _cmAdIsAudioSysLoaded(p)) != kOkAdRC )
- return cmErrMsg(&p->err,rc,"Set audio device failed.");
-
- cmAdAsCfg_t* cfgPtr = p->asCfgArray + p->curAsCfgIdx;
-
- // validate the sub-system index
- if( asSubIdx != cmInvalidIdx && asSubIdx >= p->dsSsCnt )
- {
- rc = cmErrMsg(&p->err,kInvalidSubSysIdxAdRC,"The sub-system index %i is invalid.",asSubIdx);
- goto errLabel;
- }
-
- unsigned i;
- for(i=0; i<p->dsSsCnt; ++i)
- {
- // assign the new device index to the indicated audio system configuration recd
- if( asSubIdx==cmInvalidIdx || asSubIdx == i )
- {
- if( cfgPtr->cfg.ssArray[ i ].args.srate != srate )
- cfgPtr->cfg.ssArray[ i ].args.srate = srate;
- }
- }
-
- // notify the client of the new sample rate
- _cmAdSendIntMsgToHost(p,asSubIdx,kSetSampleRateDuiId,0,(unsigned)srate);
-
- // reinitialize the audio system
- rc = _cmAdReinitAudioSys(p);
-
- errLabel:
-
- return rc;
- }
-
-
- cmAdRC_t _cmAudDspClientMsgPoll( cmAd_t* p )
- {
- unsigned i = 0;
-
- // if the program is not synced then don't bother polling the audio system
- if( _cmAudDspIsPgmSynced(p) == false )
- return kOkAdRC;
-
- for(i=0; i<p->msgsPerClientPoll; ++i)
- {
- if( cmAudioSysIsMsgWaiting(p->asH) == 0 )
- break;
-
- if(cmAudioSysReceiveMsg(p->asH,NULL,0) != kOkAsRC )
- return cmErrMsg(&p->err,kAudioSysFailAdRC,"The delivery of an audio system msg for the client failed.");
-
- }
-
- return kOkAdRC;
- }
-
- cmAdRC_t cmAudDspReceiveClientMsg( cmAdH_t h, unsigned msgByteCnt, const void* msg )
- {
- cmAdRC_t rc = kOkAdRC;
- cmAd_t* p = _cmAdHandleToPtr(h);
- cmDspUiHdr_t* m = (cmDspUiHdr_t*)msg;
- /*
- if( m->uiId != kUiSelAsId )
- {
- rc = cmErrMsg(&p->err,kUnknownMsgTypeAdRC,"The message type %i is unknown.");
- goto errLabel;
- }
- */
-
- switch( m->selId )
- {
- case kDevReportDuiId:
- cmRptPrintf(p->err.rpt,"\nAUDIO DEVICES\n");
- cmApReport(p->err.rpt);
- cmRptPrintf(p->err.rpt,"\nMIDI DEVICES\n");
- cmMpReport(p->err.rpt);
- break;
-
- case kSetAudioCfgDuiId:
- rc = _cmAudDspLoadAudioSys(p,cmDsvUInt(&m->value));
- break;
-
- case kSetPgmDuiId:
- rc = _cmAudDspLoadPgm(p,m->asSubIdx,cmDsvUInt(&m->value));
- break;
-
- case kSetAudioDevDuiId:
- rc = _cmAudDspSetDevice(p,m->asSubIdx,m->flags,cmDsvUInt(&m->value));
- break;
-
- case kSetSampleRateDuiId:
- rc = _cmAudDspSetSampleRate(p,m->asSubIdx,cmDsvDouble(&m->value));
- break;
-
- case kEnableDuiId:
- rc = _cmAudDspEnableAudio(p,m->flags);
- break;
-
- case kSetNotifyEnableDuiId:
- cmAudioSysStatusNotifyEnable(p->asH, cmInvalidIdx, m->flags );
- break;
-
- case kClientMsgPollDuiId:
- rc = _cmAudDspClientMsgPoll(p);
- break;
-
- case kPrintPgmDuiId:
- _cmAudDspPrintPgm(p,m->asSubIdx,cmDsvStrcz(&m->value));
- break;
-
- default:
- if( cmAudioSysDeliverMsg(p->asH,msg,msgByteCnt,cmInvalidId) != kOkAsRC )
- rc = cmErrMsg(&p->err,kSendMsgFailAdRC,"Message delivery to the audio system failed.");
- break;
- }
-
-
-
- // errLabel:
- return rc;
- }
|