libcm/cmAudDspIF.c
2013-08-12 00:10:03 -07:00

299 líneas
8.5 KiB
C

#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 "cmFileSys.h"
#include "cmJson.h"
#include "cmThread.h"
#include "dsp/cmDspValue.h"
#include "cmMsgProtocol.h"
#include "cmAudDspIF.h"
cmAiH_t cmAiNullHandle = cmSTATIC_NULL_HANDLE;
typedef struct
{
cmErr_t err;
cmAdIfParm_t parms;
cmJsonH_t jsH;
} cmAi_t;
cmAi_t* _cmAiHandleToPtr( cmAiH_t h )
{
cmAi_t* p = (cmAi_t*)h.h;
assert(p != NULL);
return p;
}
// Dispatch a message to the client application.
// This function is called from within cmTsQueueDequeueMsg() which is called
// by cmAdIfDispatchMsgToHost().
cmRC_t _cmAiDispatchMsgToClient(void* cbDataPtr, unsigned msgByteCnt, const void* msgDataPtr )
{
cmAi_t* p = (cmAi_t*)cbDataPtr;
cmDspUiHdr_t* m = (cmDspUiHdr_t*)msgDataPtr;
cmRC_t rc = cmOkRC;
switch( m->uiId )
{
case kStatusSelAsId:
{
// handle a status mesage
const char* base = (const char*)msgDataPtr;
const cmAudioSysStatus_t* st = (const cmAudioSysStatus_t*)(base + (2 * sizeof(unsigned)));
const double* iMeterArray = (const double*)(st + 1);
const double* oMeterArray = iMeterArray + st->iMeterCnt;
rc = p->parms.dispatchRecd.statusFunc(p->parms.dispatchRecd.cbDataPtr, st, iMeterArray, oMeterArray );
}
break;
case kSsInitSelAsId:
{
// handle an ssInit message
const cmAudioSysSsInitMsg_t* sip = (const cmAudioSysSsInitMsg_t*)msgDataPtr;
const char* iDevLabel = (const char*)(sip+1);
const char* oDevLabel = iDevLabel + strlen(iDevLabel) + 1;
rc = p->parms.dispatchRecd.ssInitFunc(p->parms.dispatchRecd.cbDataPtr, sip, iDevLabel, oDevLabel );
}
break;
case kUiSelAsId:
{
bool jsFl = false;
cmDsvRC_t rc = kOkDsvRC;
// if the value associated with this msg is a mtx then set
// its mtx data area pointer to just after the msg header.
if( cmDsvIsJson(&m->value) )
{
rc = cmDsvDeserializeJson(&m->value,p->jsH);
jsFl = true;
}
else
rc = cmDsvDeserializeInPlace(&m->value,msgByteCnt-sizeof(cmDspUiHdr_t));
if( rc != kOkDsvRC )
cmErrMsg(&p->err,kDeserialFailAiRC,"Deserialize failed.");
else
rc = p->parms.dispatchRecd.uiFunc(p->parms.dispatchRecd.cbDataPtr,m);
if( jsFl )
cmJsonClearTree(p->jsH);
}
break;
default:
cmErrMsg(&p->err,kUnknownMsgTypeAiRC,"The message type %i is unknown.",m->uiId);
break;
}
return rc;
}
cmAiRC_t _cmAdIfReadCfgFile( cmAi_t* p, cmCtx_t* ctx )
{
cmAiRC_t rc = kOkAiRC;
const cmChar_t* sysJsFn = NULL;
cmJsonH_t jsH = cmJsonNullHandle;
cmJsonNode_t* audDspNodePtr = NULL;
//const cmChar_t* errLabelPtr = NULL;
// form the audio dsp resource file name
if((sysJsFn = cmFsMakeFn( cmFsPrefsDir(),cmAudDspSys_FILENAME,NULL,NULL)) == NULL )
{
rc = cmErrMsg(&p->err,kFileSysFailAiRC,"Unable to form the audio dsp system resource file name.");
goto errLabel;
}
// open the audio dsp resource file
if(cmJsonInitializeFromFile(&jsH,sysJsFn,ctx) != kOkJsRC )
{
rc = cmErrMsg(&p->err,kJsonFailAiRC,"Unable to open the audio dsp resource file: '%s'.",cmStringNullGuard(sysJsFn));
goto errLabel;
}
// locate the aud_dsp container object
if( cmJsonNodeMember( cmJsonRoot(jsH), "aud_dsp", &audDspNodePtr ) != kOkJsRC )
{
rc = cmErrMsg(&p->err,kJsonFailAiRC,"The audio DSP system resource file '%s' does not contain an 'aud_dsp' object.",cmStringNullGuard(sysJsFn));
goto errLabel;
}
/*
// locate the read the aud_dsp sub-elements
if( cmJsonMemberValues( audDspNodePtr, &errLabelPtr,
"msgQueueByteCnt", kIntTId, &p->msgQueueByteCnt,
NULL ) != kOkJsRC )
{
rc = cmErrMsg(&p->err,kJsonFailAiRC,"Syntax error while parsing the top level fields in the audio DSP system resource file:%s.",cmStringNullGuard(sysJsFn));
goto errLabel;
}
*/
errLabel:
if( cmJsonFinalize(&jsH) != kOkJsRC )
rc = cmErrMsg(&p->err,kJsonFailAiRC,"JSON finalization failed.");
if( sysJsFn != NULL )
cmFsFreeFn(sysJsFn);
return rc;
}
cmAiRC_t _cmAdIfSendIntMsg(cmAiH_t h, unsigned selId, unsigned asSubIdx, unsigned flags, unsigned iv, double dv, const cmChar_t* str )
{
cmAi_t* p = _cmAiHandleToPtr( h );
cmDspValue_t v;
if(str != NULL )
cmDsvSetStrcz(&v,str);
else
if(iv == cmInvalidIdx )
cmDsvSetDouble(&v,dv);
else
cmDsvSetUInt(&v,iv);
if( cmMsgSend(&p->err,asSubIdx,kUiSelAsId,selId,flags,cmInvalidId,cmInvalidId,&v,p->parms.audDspFunc,p->parms.audDspFuncDataPtr) != kOkMsgRC )
return cmErrMsg(&p->err,kSendFailAiRC,"The integer message sel id:%i value:%i transmission failed.",selId,iv);
return kOkAiRC;
}
cmAiRC_t _cmAdIfFree( cmAi_t* p )
{
cmAiRC_t rc = kOkAiRC;
if( cmJsonFinalize(&p->jsH) != kOkJsRC )
{
rc = cmErrMsg(&p->err,kJsonFailAiRC,"JSON finalization failed.");
goto errLabel;
}
cmMemFree(p);
errLabel:
return rc;
}
cmAiRC_t cmAdIfAllocate( cmCtx_t* ctx, cmAiH_t* hp, const cmAdIfParm_t* parms )
{
cmAiRC_t rc;
if((rc = cmAdIfFree(hp)) != kOkAiRC )
return rc;
cmAi_t* p = cmMemAllocZ(cmAi_t,1);
cmErrSetup(&p->err,&ctx->rpt,"Audio DSP Interface");
p->parms = *parms;
// read the system configuration file
if((rc = _cmAdIfReadCfgFile(p, ctx )) != kOkAiRC )
goto errLabel;
// initialize a JSON tree for use in deserializing JSON messages
if((rc = cmJsonInitialize( &p->jsH, ctx )) != kOkJsRC )
{
rc = cmErrMsg(&p->err,kJsonFailAiRC,"JSON initialization failed.");
goto errLabel;
}
hp->h = p;
errLabel:
if( rc != kOkAiRC )
_cmAdIfFree(p);
return rc;
}
cmAiRC_t cmAdIfFree( cmAiH_t* hp )
{
cmAiRC_t rc = kOkAiRC;
if( hp==NULL || cmAdIfIsValid(*hp)==false )
return kOkAiRC;
cmAi_t* p = _cmAiHandleToPtr(*hp);
if((rc = _cmAdIfFree(p)) != kOkAiRC )
return rc;
hp->h = NULL;
return rc;
}
bool cmAdIfIsValid( cmAiH_t h )
{ return h.h != NULL; }
cmAiRC_t cmAdIfRecvAudDspMsg( cmAiH_t h, unsigned msgByteCnt, const void* msg )
{
cmAi_t* p = _cmAiHandleToPtr(h);
cmAiRC_t rc = kOkAiRC;
_cmAiDispatchMsgToClient(p,msgByteCnt,msg);
return rc;
}
cmAiRC_t cmAdIfDeviceReport( cmAiH_t h )
{ return _cmAdIfSendIntMsg(h,kDevReportDuiId,cmInvalidIdx,0,cmInvalidIdx,0.0,NULL); }
cmAiRC_t cmAdIfSetAudioSysCfg( cmAiH_t h, unsigned asCfgIdx )
{ return _cmAdIfSendIntMsg(h,kSetAudioCfgDuiId,cmInvalidIdx,0,asCfgIdx,0.0,NULL); }
cmAiRC_t cmAdIfSetAudioDevice( cmAiH_t h, unsigned asSubIdx, bool inputFl, unsigned devIdx )
{ return _cmAdIfSendIntMsg(h,kSetAudioDevDuiId,asSubIdx,inputFl,devIdx,0.0,NULL); }
cmAiRC_t cmAdIfSetSampleRate( cmAiH_t h, unsigned asSubIdx, double srate )
{ return _cmAdIfSendIntMsg(h,kSetSampleRateDuiId,asSubIdx,0,cmInvalidIdx,srate,NULL); }
cmAiRC_t cmAdIfLoadProgram( cmAiH_t h, unsigned asSubIdx, unsigned pgmIdx )
{ return _cmAdIfSendIntMsg(h,kSetPgmDuiId,asSubIdx,0,pgmIdx,0.0,NULL); }
cmAiRC_t cmAdIfPrintPgm( cmAiH_t h,unsigned asSubIdx, const cmChar_t* fn )
{ return _cmAdIfSendIntMsg(h,kPrintPgmDuiId,asSubIdx,0,cmInvalidIdx,0.0,fn); }
cmAiRC_t cmAdIfEnableAudio( cmAiH_t h, bool enableFl )
{ return _cmAdIfSendIntMsg(h,kEnableDuiId,cmInvalidIdx,enableFl,cmInvalidIdx,0.0,NULL); }
cmAiRC_t cmAdIfEnableStatusNotify( cmAiH_t h, bool enableFl )
{ return _cmAdIfSendIntMsg(h,kSetNotifyEnableDuiId,cmInvalidIdx,enableFl,cmInvalidIdx,0.0,NULL); }
cmAiRC_t cmAdIfSendMsgToAudioDSP(
cmAiH_t h,
unsigned asSubIdx,
unsigned msgTypeId,
unsigned selId,
unsigned flags,
unsigned instId,
unsigned instVarId,
const cmDspValue_t* valPtr )
{
cmAiRC_t rc = kOkAiRC;
cmAi_t* p = _cmAiHandleToPtr(h);
if( cmMsgSend( &p->err, asSubIdx, msgTypeId,selId,flags,instId,instVarId,valPtr, p->parms.audDspFunc, p->parms.audDspFuncDataPtr ) != kOkMsgRC )
rc = cmErrMsg(&p->err, kSendFailAiRC, "A UI message intened for the the audio DSP system was not successfully delivered.");
return rc;
}
cmAiRC_t cmAdIfDispatchMsgToHost( cmAiH_t h )
{ return _cmAdIfSendIntMsg(h,kClientMsgPollDuiId,cmInvalidIdx,0,cmInvalidIdx,0.0,NULL); }