Merge branch 'master' of wf:webapps/gitweb/repos/libcm

This commit is contained in:
kevin.larke 2020-02-21 15:51:29 -05:00
commit 0cc1cefe19
28 changed files with 946 additions and 14 deletions

View File

@ -33,6 +33,9 @@ cmSRC += src/libcm/cmAudioPort.c src/libcm/cmApBuf.c src/libcm/cmAudioAggDev.c s
cmHDR += src/libcm/cmMidiFilePlay.h src/libcm/cmMidiPort.h src/libcm/cmMidiFile.h src/libcm/cmMidi.h
cmSRC += src/libcm/cmMidiFilePlay.c src/libcm/cmMidiPort.c src/libcm/cmMidiFile.c src/libcm/cmMidi.c
cmHDR += src/libcm/cmSerialPort.h
cmSRC += src/libcm/cmSerialPort.c
cmHDR += src/libcm/cmAudioFile.h src/libcm/cmAudioFileMgr.h src/libcm/cmMsgProtocol.h src/libcm/cmAudioSys.h src/libcm/cmAudioPortFile.h src/libcm/cmAudioFileDev.h
cmSRC += src/libcm/cmAudioFile.c src/libcm/cmAudioFileMgr.c src/libcm/cmMsgProtocol.c src/libcm/cmAudioSys.c src/libcm/cmAudioPortFile.c src/libcm/cmAudioFileDev.c

View File

@ -815,6 +815,7 @@ void cmApBufInputToOutput( unsigned iDevIdx, unsigned oDevIdx )
unsigned byteCnt = ip->dspFrameCnt * sizeof(cmApSample_t);
if( oBufPtrArray[i] != NULL )
{
// the input channel is not disabled
@ -846,17 +847,19 @@ void cmApBufReport( cmRpt_t* rpt )
unsigned ii = 0;
unsigned oi = 0;
unsigned fn = 0;
cmApSample_t mtr = 0;
for(k=0; k<ip->chCnt; ++k)
{
cmApCh* cp = ip->chArray + i;
ii += cp->ii;
oi += cp->oi;
fn += cp->fn;
mtr += _cmApMeterValue(cp);
}
cmRptPrintf(rpt,"%s - i:%7i o:%7i f:%7i n:%7i err %s:%7i ",
cmRptPrintf(rpt,"%s - i:%7i o:%7i f:%7i n:%7i err %s:%7i mtr:%5.4f ",
j==0?"IN":"OUT",
ii,oi,fn,ip->n, (j==0?"over":"under"), ip->faultCnt);
ii,oi,fn,ip->n, (j==0?"over":"under"), ip->faultCnt, mtr);
}

View File

@ -19,6 +19,7 @@
#include "cmApBuf.h"
#include "cmMidi.h"
#include "cmMidiPort.h"
#include "cmSerialPort.h"
#include "dsp/cmDspValue.h"
#include "cmMsgProtocol.h"
#include "cmThread.h"
@ -91,6 +92,12 @@ typedef struct
unsigned msgsPerClientPoll;
const cmChar_t* dfltProgramLabel;
char* serialDeviceStr;
unsigned serialBaud;
unsigned serialCfgFlags;
unsigned serialPollPeriodMs;
cmSeH_t serialPortH;
cmAdAggDev_t* aggDevArray;
unsigned aggDevCnt;
@ -169,6 +176,7 @@ cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p )
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;
@ -190,12 +198,28 @@ cmAdRC_t _cmAdParseSysJsonTree( cmAd_t* p )
"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)
{
@ -382,6 +406,22 @@ cmAdRC_t _cmAdSetup( cmAd_t* p )
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;
@ -570,6 +610,15 @@ cmAdRC_t _cmAudDspFree( cmAd_t* p )
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 )
{
@ -695,6 +744,13 @@ cmAdRC_t cmAudDspAlloc( cmCtx_t* ctx, cmAdH_t* hp, cmMsgSendFuncPtr_t cbFunc, vo
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 )
{
@ -713,7 +769,7 @@ cmAdRC_t cmAudDspAlloc( cmCtx_t* ctx, cmAdH_t* hp, cmMsgSendFuncPtr_t cbFunc, vo
goto errLabel;
// initialize the DSP system
if( cmDspSysInitialize(ctx,&p->dsH,p->netH) )
if( cmDspSysInitialize(ctx,&p->dsH,p->netH,p->serialPortH) )
{
rc = cmErrMsg(&p->err,kDspSysFailAdRC,"The DSP system initialization failed.");
goto errLabel;
@ -1143,7 +1199,7 @@ cmAdRC_t _cmAudDspLoadAudioSys( cmAd_t* p, unsigned asCfgIdx )
{
// ... 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) != kOkDspRC )
if( cmDspSysInitialize(&p->ctx,&dsH,p->netH,p->serialPortH) != kOkDspRC )
{
rc = cmErrMsg(&p->err,kDspSysFailAdRC,"Unable to initialize an additional DSP system.");
goto errLabel;

View File

@ -13,6 +13,7 @@ extern "C" {
kAudioPortFailAdRC,
kAudioSysFailAdRC,
kMidiSysFailAdRC,
kSerialPortFailAdRC,
kDspSysFailAdRC,
kFileSysFailAdRC,
kJsonFailAdRC,
@ -21,6 +22,7 @@ extern "C" {
kNoPgmLoadedAdRC,
kInvalidSubSysIdxAdRC,
kUnknownMsgTypeAdRC,
kSerialDevCreateFailAdRC,
kAggDevSysFailAdRC,
kAggDevCreateFailAdRC,
kNrtDevSysFailAdRC,

View File

@ -743,6 +743,8 @@ int cmApPortTest( bool runFl, cmRpt_t* rpt, int argc, const char* argv[] )
if( r.inDevIdx != r.outDevIdx )
cmApBufSetup( r.inDevIdx, r.srate, r.framesPerCycle, r.bufCnt, cmApDeviceChannelCount(r.inDevIdx,true), r.framesPerCycle, cmApDeviceChannelCount(r.inDevIdx,false), r.framesPerCycle );
cmApBufEnableMeter( r.inDevIdx, -1, kEnableApFl );
// setup an output device
if(cmApDeviceSetup(r.outDevIdx,r.srate,r.framesPerCycle,_cmApPortCb2,&r) != kOkApRC )
cmRptPrintf(rpt,"Out device setup failed.\n");

View File

@ -15,6 +15,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmAudioSysMsg.h"
#include "cmAudioSys.h"
#include "cmMidi.h"
@ -37,6 +38,7 @@ typedef struct
cmTsMp1cH_t htdQueueH; // host-to-dsp thread safe msg queue
cmThreadMutexH_t engMutexH; // thread mutex and condition variable
cmUdpNetH_t netH;
cmSeH_t serialPortH;
bool enableFl; // application controlled pause flag
bool runFl; // false during finalization otherwise true
bool statusFl; // true if regular status notifications should be sent
@ -507,6 +509,13 @@ void _cmAudioSysMidiCallback( const cmMidiPacket_t* pktArray, unsigned pktCnt )
}
void _cmAudioSysSerialPortCallback( void* cbArg, const void* byteA, unsigned byteN )
{
//_cmAsCfg_t* p (_cmAsCfg_t*)cbArg;
// TODO: handle serial receive
}
cmAsRC_t cmAudioSysAllocate( cmAudioSysH_t* hp, cmRpt_t* rpt, const cmAudioSysCfg_t* cfg )
{
cmAsRC_t rc;
@ -832,6 +841,7 @@ cmAsRC_t cmAudioSysInitialize( cmAudioSysH_t h, const cmAudioSysCfg_t* cfg )
cp->iMeterArray = cmMemAllocZ( double, cp->status.iMeterCnt );
cp->oMeterArray = cmMemAllocZ( double, cp->status.oMeterCnt );
cp->netH = cfg->netH;
cp->serialPortH = cfg->serialPortH;
// create the audio System thread
if((rc = cmThreadCreate( &cp->threadH, _cmAsThreadCallback, cp, ss->args.rpt )) != kOkThRC )
@ -874,6 +884,16 @@ cmAsRC_t cmAudioSysInitialize( cmAudioSysH_t h, const cmAudioSysCfg_t* cfg )
goto errLabel;
}
// install the serial port
if( cmSeIsOpen(cp->serialPortH) )
{
if( cmSeSetCallback(cp->serialPortH, _cmAudioSysSerialPortCallback, cp ) != kOkSeRC )
{
rc = _cmAsError(p,kSerialPortFailAsRC,"Serial port callback installation failed.");
goto errLabel;
}
}
// setup the sub-system status notification
cp->statusUpdateSmpCnt = floor(cmApBufMeterMs() * cp->ss.args.srate / 1000.0 );
cp->statusUpdateSmpIdx = 0;
@ -886,6 +906,16 @@ cmAsRC_t cmAudioSysInitialize( cmAudioSysH_t h, const cmAudioSysCfg_t* cfg )
rc = _cmAsError(p,kThreadErrAsRC,"Thread start failed.");
goto errLabel;
}
if( cmSeIsOpen(cp->serialPortH) )
{
if( cmSeStart( cp->serialPortH ) != kOkSeRC )
{
rc = _cmAsError(p,kSerialPortFailAsRC,"Serial port start failed.");
goto errLabel;
}
}
}

View File

@ -73,6 +73,7 @@ extern "C" {
kBufTooSmallAsRC,
kNoMsgWaitingAsRC,
kMidiSysFailAsRC,
kSerialPortFailAsRC,
kMsgSerializeFailAsRC,
kStateBufFailAsRC,
kInvalidArgAsRC,
@ -197,6 +198,7 @@ extern "C" {
cmTsQueueCb_t clientCbFunc; // Called by cmAudioSysReceiveMsg() to deliver internally generated msg's to the host.
// Set to NULL if msg's will be directly returned by buffers passed to cmAudioSysReceiveMsg().
cmUdpNetH_t netH;
cmSeH_t serialPortH;
} cmAudioSysCfg_t;
extern cmAudioSysH_t cmAudioSysNullHandle;

View File

@ -92,6 +92,12 @@ extern "C" {
//< If 'b' == 0 then return 'f' with the bits in 'm' cleared.
//< otherwise return 'f' with the bits in 'm' set.
// In-place assignment version of the above bit operations
#define cmSetBits(f,m) ((f) |= (m)) // Set 'f' with the bits in 'm' set.
#define cmClrBits(f,m) ((f) &= (~(m))) // Set 'f' with the bits in 'm' cleared.
#define cmTogBits(f,m) ((f)^=(m)) // Return 'f' with the bits in 'm' toggled.
#define cmEnaBits(f,m,b) ((b) ? cmSetBits(f,m) : cmClrBits(f,m)) // Set or clear bits in 'f' based on bits in 'm' and the state of 'b'.
#define cmMin(v0,v1) ((v0)<(v1) ? (v0) : (v1)) //< Return the minimum arg.
#define cmMax(v0,v1) ((v0)>(v1) ? (v0) : (v1)) //< Return the maximum arg.

579
cmSerialPort.c Normal file
View File

@ -0,0 +1,579 @@
#include "cmPrefix.h"
#include "cmGlobal.h"
#include "cmRpt.h"
#include "cmErr.h"
#include "cmCtx.h"
#include "cmMem.h"
#include "cmMallocDebug.h"
#include "cmSerialPort.h"
#include "cmThread.h"
#include <poll.h>
#include <termios.h>
#include <unistd.h> // close()
#include <fcntl.h> // O_RDWR
#include <sys/ioctl.h> // TIOCEXCL
typedef struct cmSerialPort_str
{
cmErr_t _err;
cmThreadH_t _thH;
const char* _deviceStr;
int _deviceH;
unsigned _baudRate;
unsigned _cfgFlags;
cmSeCallbackFunc_t _cbFunc;
void* _cbArg;
struct termios _ttyAttrs;
struct pollfd _pollfd;
unsigned _pollPeriodMs;
} cmSerialPort_t;
cmSerialPort_t* _cmSePtrFromHandle( cmSeH_t h )
{
cmSerialPort_t* p = (cmSerialPort_t*)h.h;
assert(p!=NULL);
return p;
}
void _cmSeSetClosedState( cmSerialPort_t* p )
{
if( p->_deviceStr != NULL )
cmMemFree((char*)(p->_deviceStr));
p->_deviceH = -1;
p->_deviceStr = NULL;
p->_baudRate = 0;
p->_cfgFlags = 0;
p->_cbFunc = NULL;
p->_cbArg = NULL;
}
cmSeRC_t _cmSeGetAttributes( cmSerialPort_t* p, struct termios* attr )
{
if( tcgetattr(p->_deviceH, attr) == -1 )
return cmErrSysMsg(&p->_err,kGetAttrFailSeRC,errno,"Error getting tty attributes from %s.",p->_deviceStr);
return kOkSeRC;
}
cmSeRC_t _cmSePoll( cmSerialPort_t* p, unsigned timeOutMs )
{
cmSeRC_t rc = kOkSeRC;
int sysRC;
if((sysRC = poll(&p->_pollfd,1,timeOutMs)) == 0)
rc = kTimeOutSeRC;
else
{
if( sysRC < 0 )
rc = cmErrSysMsg(&p->_err,kReadFailSeRC,errno,"Poll failed on serial port.");
}
return rc;
}
bool _cmSeThreadFunc(void* param)
{
cmSerialPort_t* p = (cmSerialPort_t*)param;
cmSeH_t h;
h.h = p;
unsigned readN;
if( cmSeIsOpen(h) )
cmSeReceiveCbTimeOut(h,p->_pollPeriodMs,&readN);
return true;
}
cmSeRC_t _cmSeDestroy( cmSerialPort_t* p )
{
cmSeRC_t rc = kOkSeRC;
// stop the thread first
if( cmThreadDestroy(&p->_thH) != kOkThRC )
{
rc = cmErrMsg(&p->_err,kThreadErrSeRC,"Thread destroy failed.");
goto errLabel;
}
// Block until all written output has been sent from the device.
// Note that this call is simply passed on to the serial device driver.
// See tcsendbreak(3) ("man 3 tcsendbreak") for details.
if (tcdrain(p->_deviceH) == -1)
{
rc = cmErrSysMsg(&p->_err,kFlushFailSeRC,errno,"Error waiting for serial device '%s' to drain.", p->_deviceStr );
goto errLabel;
}
// It is good practice to reset a serial port back to the state in
// which you found it. This is why we saved the original termios struct
// The constant TCSANOW (defined in termios.h) indicates that
// the change should take effect immediately.
if (tcsetattr(p->_deviceH, TCSANOW, &p->_ttyAttrs) == -1)
{
rc = cmErrSysMsg(&p->_err,kSetAttrFailSeRC,errno,"Error resetting tty attributes on serial device '%s'.",p->_deviceStr);
goto errLabel;
}
if( p->_deviceH != -1 )
{
if( close(p->_deviceH ) != 0 )
{
rc = cmErrSysMsg(&p->_err,kCloseFailSeRC,errno,"Port close failed on serial dvice '%s'.", p->_deviceStr);
goto errLabel;
}
_cmSeSetClosedState(p);
}
cmMemPtrFree(&p);
errLabel:
return rc;
}
cmSeH_t cmSeCreate( cmCtx_t* ctx, cmSeH_t* hp, const char* deviceStr, unsigned baudRate, unsigned cfgFlags, cmSeCallbackFunc_t cbFunc, void* cbArg, unsigned pollPeriodMs )
{
cmSeRC_t rc = kOkSeRC;
struct termios options;
cmSeH_t h;
// if the port is already open then close it
if((rc = cmSeDestroy(hp)) != kOkSeRC )
return *hp;
cmSerialPort_t* p = cmMemAllocZ(cmSerialPort_t,1);
cmErrSetup(&p->_err,&ctx->rpt,"Serial Port");
p->_deviceH = -1;
// open the port
if( (p->_deviceH = open(deviceStr, O_RDWR | O_NOCTTY | O_NONBLOCK)) == -1 )
{
rc = cmErrSysMsg(&p->_err,kOpenFailSeRC,errno,"Error opening serial '%s'",cmStringNullGuard(deviceStr));
goto errLabel;;
}
// Note that open() follows POSIX semantics: multiple open() calls to
// the same file will succeed unless the TIOCEXCL ioctl is issued.
// This will prevent additional opens except by root-owned processes.
// See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details.
if( ioctl(p->_deviceH, TIOCEXCL) == -1 )
{
rc = cmErrSysMsg(&p->_err,kResourceNotAvailableSeRC,errno,"The serial device '%s' is already in use.", cmStringNullGuard(deviceStr));
goto errLabel;
}
// Now that the device is open, clear the O_NONBLOCK flag so
// subsequent I/O will block.
// See fcntl(2) ("man 2 fcntl") for details.
/*
if (fcntl(_deviceH, F_SETFL, 0) == -1)
{
_error("Error clearing O_NONBLOCK %s - %s(%d).", pr.devFilePath.c_str(), strerror(errno), errno);
goto errLabel;
}
*/
// Get the current options and save them so we can restore the
// default settings later.
if (tcgetattr(p->_deviceH, &p->_ttyAttrs) == -1)
{
rc = cmErrSysMsg(&p->_err,kGetAttrFailSeRC,errno,"Error getting tty attributes from the device '%s'.",deviceStr);
goto errLabel;
}
// The serial port attributes such as timeouts and baud rate are set by
// modifying the termios structure and then calling tcsetattr to
// cause the changes to take effect. Note that the
// changes will not take effect without the tcsetattr() call.
// See tcsetattr(4) ("man 4 tcsetattr") for details.
options = p->_ttyAttrs;
// Set raw input (non-canonical) mode, with reads blocking until either
// a single character has been received or a 100ms timeout expires.
// See tcsetattr(4) ("man 4 tcsetattr") and termios(4) ("man 4 termios")
// for details.
cfmakeraw(&options);
options.c_cc[VMIN] = 1;
options.c_cc[VTIME] = 1;
// The baud rate, word length, and handshake options can be set as follows:
// set baud rate
cfsetspeed(&options, baudRate);
options.c_cflag |= CREAD | CLOCAL; // ignore modem controls
// set data word size
cmClrBits(options.c_cflag, CSIZE); // clear the word size bits
cmEnaBits(options.c_cflag, CS5, cmIsFlag(cfgFlags, kDataBits5SeFl));
cmEnaBits(options.c_cflag, CS6, cmIsFlag(cfgFlags, kDataBits6SeFl));
cmEnaBits(options.c_cflag, CS7, cmIsFlag(cfgFlags, kDataBits7SeFl));
cmEnaBits(options.c_cflag, CS8, cmIsFlag(cfgFlags, kDataBits8SeFl));
cmClrBits(options.c_cflag, PARENB); // assume no-parity
// if the odd or even parity flag is set
if( cmIsFlag( cfgFlags, kEvenParitySeFl) || cmIsFlag( cfgFlags, kOddParitySeFl ) )
{
cmSetBits(options.c_cflag, PARENB);
if( cmIsFlag(cfgFlags, kOddParitySeFl ) )
cmSetBits( options.c_cflag, PARODD);
}
// set two stop bits
cmEnaBits( options.c_cflag, CSTOPB, cmIsFlag(cfgFlags, k2StopBitSeFl));
// set hardware flow control
//cmEnaBits(options.c_cflag, CCTS_OFLOW, cmIsFlag(cfgFlags, kCTS_OutFlowCtlFl));
//cmEnaBits(options.c_cflag, CRTS_IFLOW, cmIsFlag(cfgFlags, kRTS_InFlowCtlFl));
//cmEnaBits(options.c_cflag, CDTR_IFLOW, cmIsFlag(cfgFlags, kDTR_InFlowCtlFl));
//cmEnaBits(options.c_cflag, CDSR_OFLOW, cmIsFlag(cfgFlags, kDSR_OutFlowCtlFl));
//cmEnaBits(options.c_cflag, CCAR_OFLOW, cmIsFlag(cfgFlags, kDCD_OutFlowCtlFl));
cmClrBits(options.c_cflag,CRTSCTS); // turn-off hardware flow control
// 7 bit words, enable even parity, CTS out ctl flow, RTS in ctl flow
// note: set PARODD and PARENB to enable odd parity)
//options.c_cflag |= (CS7 | PARENB | CCTS_OFLOW | CRTS_IFLOW );
// Cause the new options to take effect immediately.
if (tcsetattr(p->_deviceH, TCSANOW, &options) == -1)
{
rc = cmErrSysMsg(&p->_err,kSetAttrFailSeRC,errno,"Error setting tty attributes on serial device %.", deviceStr);
goto errLabel;
}
memset(&p->_pollfd,0,sizeof(p->_pollfd));
p->_pollfd.fd = p->_deviceH;
p->_pollfd.events = POLLIN;
p->_deviceStr = cmMemAllocStr( deviceStr );
p->_baudRate = baudRate;
p->_cfgFlags = cfgFlags;
p->_cbFunc = cbFunc;
p->_cbArg = cbArg;
p->_pollPeriodMs = pollPeriodMs;
// create the listening thread
if( cmThreadCreate( &p->_thH, _cmSeThreadFunc, p, &ctx->rpt) != kOkThRC )
{
rc = cmErrMsg(&p->_err,kThreadErrSeRC,"Thread initialization failed.");
goto errLabel;
}
if( hp != NULL )
hp->h = p;
else
h.h = p;
errLabel:
if( rc != kOkSeRC )
{
_cmSeDestroy(p);
h.h = NULL;
}
return hp != NULL ? *hp : h;
}
cmSeRC_t cmSeDestroy(cmSeH_t* hp )
{
cmSeRC_t rc = kOkSeRC;
if( hp==NULL || !cmSeIsOpen(*hp) )
return kOkSeRC;
cmSerialPort_t* p = _cmSePtrFromHandle(*hp);
if((rc = _cmSeDestroy(p)) != kOkSeRC )
return rc;
hp->h = NULL;
return rc;
}
cmSeRC_t cmSeSetCallback( cmSeH_t h, cmSeCallbackFunc_t cbFunc, void* cbArg )
{
cmSerialPort_t* p = _cmSePtrFromHandle(h);
p->_cbFunc = cbFunc;
p->_cbArg = cbArg;
return kOkSeRC;
}
cmSeRC_t cmSeStart( cmSeH_t h )
{
cmSerialPort_t* p = _cmSePtrFromHandle(h);
if( cmThreadPause(p->_thH,0) != kOkThRC )
return cmErrMsg(&p->_err,kThreadErrSeRC,0,"Thread start failed.");
return kOkSeRC;
}
bool cmSeIsOpen( cmSeH_t h)
{
if( h.h == NULL )
return false;
cmSerialPort_t* p = _cmSePtrFromHandle(h);
return p->_deviceH != -1;
}
cmSeRC_t cmSeSend( cmSeH_t h, const void* byteA, unsigned byteN )
{
cmSeRC_t rc = kOkSeRC;
cmSerialPort_t* p = _cmSePtrFromHandle(h);
if( !cmSeIsOpen(h) )
return cmErrWarnMsg( &p->_err, kResourceNotAvailableSeRC, "An attempt was made to transmit from a closed serial port.");
if( byteN == 0 )
return rc;
// implement a non blocking write - if less than all the bytes were written then iterate
unsigned i = 0;
do
{
int n = 0;
if((n = write( p->_deviceH, ((char*)byteA)+i, byteN-i )) == -1 )
{
rc = cmErrSysMsg(&p->_err,kWriteFailSeRC,errno,"Write failed on serial port '%s'.", p->_deviceStr );
break;
}
i += n;
}while( i<byteN );
return rc;
}
cmSeRC_t cmSeReceiveCbNb( cmSeH_t h, unsigned* readN_Ref)
{
cmSeRC_t rc = kOkSeRC;
cmSerialPort_t* p = _cmSePtrFromHandle(h);
const unsigned bufN = 512;
char buf[ bufN ];
if( readN_Ref != NULL)
*readN_Ref = 0;
if((rc = cmSeReceiveNb(h,buf,bufN,readN_Ref)) == kOkSeRC )
if( readN_Ref > 0 && p->_cbFunc != NULL )
p->_cbFunc( p->_cbArg, buf, *readN_Ref );
return rc;
}
cmSeRC_t cmSeReceiveCbTimeOut( cmSeH_t h, unsigned timeOutMs, unsigned* readN_Ref)
{
cmSeRC_t rc;
cmSerialPort_t* p = _cmSePtrFromHandle(h);
if((rc = _cmSePoll(p,timeOutMs)) == kOkSeRC )
rc = cmSeReceiveCbNb(h,readN_Ref);
return rc;
}
cmSeRC_t cmSeReceiveNb( cmSeH_t h, void* buf, unsigned bufN, unsigned* readN_Ref)
{
cmSeRC_t rc = kOkSeRC;
cmSerialPort_t* p = _cmSePtrFromHandle(h);
if( readN_Ref != NULL )
*readN_Ref = 0;
if( !cmSeIsOpen(h) )
return cmErrWarnMsg(&p->_err, kResourceNotAvailableSeRC, "An attempt was made to read from a closed serial port.");
int n = 0;
// if attempt to read the port succeeded ...
if((n =read( p->_deviceH, buf, bufN )) != -1 )
*readN_Ref = n;
else
{
// ... or failed and it wasn't because the port was empty
if( errno != EAGAIN)
rc = cmErrSysMsg(&p->_err,kReadFailSeRC,errno,"An attempt to read the serial port '%s' failed.", p->_deviceStr );
}
return rc;
}
cmSeRC_t cmSeReceive( cmSeH_t h, void* buf, unsigned bufByteN, unsigned timeOutMs, unsigned* readN_Ref )
{
cmSeRC_t rc = kOkSeRC;
cmSerialPort_t* p = _cmSePtrFromHandle(h);
if((rc = _cmSePoll(p,timeOutMs)) == kOkSeRC )
rc = cmSeReceiveNb(h,buf,bufByteN,readN_Ref);
return rc;
}
const char* cmSeDevice( cmSeH_t h)
{
cmSerialPort_t* p = _cmSePtrFromHandle(h);
return p->_deviceStr;
}
unsigned cmSeBaudRate( cmSeH_t h)
{
cmSerialPort_t* p = _cmSePtrFromHandle(h);
return p->_baudRate;
}
unsigned cmSeCfgFlags( cmSeH_t h)
{
cmSerialPort_t* p = _cmSePtrFromHandle(h);
return p->_cfgFlags;
}
unsigned cmSeReadInBaudRate( cmSeH_t h )
{
struct termios attr;
cmSerialPort_t* p = _cmSePtrFromHandle(h);
if((_cmSeGetAttributes(p,&attr)) != kOkSeRC )
return 0;
return cfgetispeed(&attr);
}
unsigned cmSeReadOutBaudRate( cmSeH_t h)
{
struct termios attr;
cmSerialPort_t* p = _cmSePtrFromHandle(h);
if((_cmSeGetAttributes(p,&attr)) != kOkSeRC )
return 0;
return cfgetospeed(&attr);
}
unsigned cmSeReadCfgFlags( cmSeH_t h)
{
struct termios attr;
unsigned result = 0;
cmSerialPort_t* p = _cmSePtrFromHandle(h);
if((_cmSeGetAttributes(p,&attr)) == false )
return 0;
switch( attr.c_cflag & CSIZE )
{
case CS5:
cmSetBits( result, kDataBits5SeFl);
break;
case CS6:
cmSetBits( result, kDataBits6SeFl );
break;
case CS7:
cmSetBits( result, kDataBits7SeFl);
break;
case CS8:
cmSetBits( result, kDataBits8SeFl);
break;
}
cmEnaBits( result, k2StopBitSeFl, cmIsFlag( attr.c_cflag, CSTOPB ));
cmEnaBits( result, k1StopBitSeFl, !cmIsFlag( attr.c_cflag, CSTOPB ));
if( cmIsFlag( attr.c_cflag, PARENB ) )
{
cmEnaBits( result, kOddParitySeFl, cmIsFlag( attr.c_cflag, PARODD ));
cmEnaBits( result, kEvenParitySeFl, !cmIsFlag( attr.c_cflag, PARODD ));
}
return result;
}
//====================================================================================================
//
//
void _cmSePortTestCb( void* arg, const void* byteA, unsigned byteN )
{
const char* text = (const char*)byteA;
for(unsigned i=0; i<byteN; ++i)
printf("%c:%i ",text[i],(int)text[i]);
if( byteN )
fflush(stdout);
}
cmSeRC_t cmSePortTest(cmCtx_t* ctx)
{
// Use this test an Arduino running study/serial/arduino_xmt_rcv/main.c
cmSeRC_t rc = kOkSeRC;
const char* device = "/dev/ttyACM0";
unsigned baud = 38400;
unsigned serialCfgFlags = kDefaultCfgSeFlags;
unsigned pollPeriodMs = 50;
cmSeH_t h;
h.h = NULL;
h = cmSeCreate(ctx,&h,device,baud,serialCfgFlags,_cmSePortTestCb,NULL,pollPeriodMs);
if( cmSeIsOpen(h) )
cmSeStart(h);
bool quitFl = false;
printf("q=quit\n");
while(!quitFl)
{
char c = getchar();
if( c == 'q')
quitFl = true;
else
if( '0' <= c && c <= 'z' )
cmSeSend(h,&c,1);
}
cmSeDestroy(&h);
return rc;
}

93
cmSerialPort.h Normal file
View File

@ -0,0 +1,93 @@
#ifndef cmSerialPort_h
#define cmSerialPort_h
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned cmSeRC_t;
enum
{
kOkSeRC = cmOkRC,
kFlushFailSeRC,
kSetAttrFailSeRC,
kCloseFailSeRC,
kOpenFailSeRC,
kResourceNotAvailableSeRC,
kGetAttrFailSeRC,
kWriteFailSeRC,
kReadFailSeRC,
kTimeOutSeRC,
kThreadErrSeRC
};
enum
{
kDataBits5SeFl = 0x0001,
kDataBits6SeFl = 0x0002,
kDataBits7SeFl = 0x0004,
kDataBits8SeFl = 0x0008,
kDataBitsSeMask = 0x000f,
k1StopBitSeFl = 0x0010,
k2StopBitSeFl = 0x0020,
kEvenParitySeFl = 0x0040,
kOddParitySeFl = 0x0080,
kNoParitySeFl = 0x0000,
kDefaultCfgSeFlags = kDataBits8SeFl | k1StopBitSeFl | kNoParitySeFl
};
typedef void (*cmSeCallbackFunc_t)( void* cbArg, const void* byteA, unsigned byteN );
typedef cmHandle_t cmSeH_t;
cmSeH_t cmSeCreate( cmCtx_t* ctx, cmSeH_t* hp, const char* device, unsigned baudRate, unsigned cfgFlags, cmSeCallbackFunc_t cbFunc, void* cbArg, unsigned pollPeriodMs );
cmSeRC_t cmSeDestroy(cmSeH_t* hp );
cmSeRC_t cmSeSetCallback( cmSeH_t h, cmSeCallbackFunc_t cbFunc, void* cbArg );
cmSeRC_t cmSeStart( cmSeH_t h );
bool cmSeIsOpen( cmSeH_t h);
cmSeRC_t cmSeSend( cmSeH_t h, const void* byteA, unsigned byteN );
// Make callback to listener with result of read - Non-blocking
cmSeRC_t cmSeReceiveCbNb( cmSeH_t h, unsigned* readN_Ref);
// Make callback to listener with result of read - Block for up to timeOutMs.
cmSeRC_t cmSeReceiveCbTimeOut( cmSeH_t h, unsigned timeOutMs, unsigned* readN_Ref);
// Return result of read in buf[bufByteN] - Non-blocking.
cmSeRC_t cmSeReceiveNb( cmSeH_t h, void* buf, unsigned bufByteN, unsigned* readN_Ref);
// Return result of read in buf[bufByteN] - Block for up to timeOutMs.
cmSeRC_t cmSeReceive( cmSeH_t h, void* buf, unsigned bufByteN, unsigned timeOutMs, unsigned* readN_Ref );
const char* cmSeDevice( cmSeH_t h);
// Get the baud rate and cfgFlags used to initialize the port
unsigned cmSeBaudRate( cmSeH_t h);
unsigned cmSeCfgFlags( cmSeH_t h);
// Get the baud rate and cfg flags by reading the device.
// Note the the returned buad rate is a system id rather than the actual baud rate,
// however the cfgFlags are converted to the same kXXXFl defined in this class.
unsigned cmSeReadInBaudRate( cmSeH_t h );
unsigned cmSeReadOutBaudRate( cmSeH_t h);
unsigned cmSeReadCfgFlags( cmSeH_t h);
cmSeRC_t cmSePortTest(cmCtx_t* ctx);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -27,6 +27,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"
#include "cmDspSys.h"
@ -5564,6 +5565,7 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
cmActiveMeasClassCons,
cmAmSyncClassCons,
cmNanoMapClassCons,
cmPicadaeClassCons,
cmRecdPlayClassCons,
cmGoertzelClassCons,
cmSyncRecdClassCons,

View File

@ -15,6 +15,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"
@ -128,7 +129,7 @@ void* cmDspInstAllocate(
}
// determine the space needed for matrices of known size
if( cmIsFlag(flags,kMtxDsvFl) && (rn*argV[i].cn) )
if( cmIsFlag(flags,kMtxDsvFl) && (rn*argV[i].cn)>0 )
{
unsigned n = cmDsvByteCount( flags, rn, argV[i].cn );
varDataByteCnt += n;
@ -238,7 +239,7 @@ void* cmDspInstAllocate(
}
// assign memory to the matrix types of known size
if( cmIsFlag(flags,kMtxDsvFl) && (rn*argV[i].cn) )
if( cmIsFlag(flags,kMtxDsvFl) && (rn*argV[i].cn)>0 )
{
cmDsvSetMtx( &ip->varArray[i].value, flags, varDataPtr, rn, argV[i].cn );
unsigned n = cmDsvByteCount( flags, rn, argV[i].cn );

View File

@ -22,6 +22,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"

View File

@ -18,6 +18,8 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
//( { file_desc:"'snap' audio effects performance analysis units." kw:[snap]}
#include "cmTime.h"
@ -2801,6 +2803,134 @@ cmDspClass_t* cmNanoMapClassCons( cmDspCtx_t* ctx )
return &_cmNanoMapDC;
}
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmDspPicadae file_desc:"Control a MIDI synth." kw:[sunit] }
enum
{
kPgmPcId,
kStatusPcId,
kD0PcId,
kD1PcId,
kThruPcId
};
cmDspClass_t _cmPicadaeDC;
typedef struct
{
cmDspInst_t inst;
} cmDspPicadae_t;
cmDspRC_t _cmDspPicadaeSend( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned st, unsigned d0, unsigned d1 )
{
cmDspSetUInt(ctx,inst,kD1PcId,d1);
cmDspSetUInt(ctx,inst,kD0PcId,d0);
cmDspSetUInt(ctx,inst,kStatusPcId,st);
return kOkDspRC;
}
void _cmDspPicadaePgm( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned pgm )
{
//cmDspPicadae_t* p = (cmDspPicadae_t*)inst;
unsigned i;
for(i=0; i<kMidiChCnt; ++i)
{
_cmDspPicadaeSend(ctx,inst,kCtlMdId+i,121,0); // reset all controllers
_cmDspPicadaeSend(ctx,inst,kCtlMdId+i,123,0); // turn all notes off
_cmDspPicadaeSend(ctx,inst,kCtlMdId+i,0,0); // switch to bank 0
_cmDspPicadaeSend(ctx,inst,kPgmMdId+i,pgm,0); // send pgm change
cmSleepMs(15);
}
}
cmDspInst_t* _cmDspPicadaeAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
{
cmDspVarArg_t args[] =
{
{ "pgm", kPgmPcId, 0, 0, kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "Reprogram all channels to this pgm." },
{ "status", kStatusPcId, 0, 0, kOutDsvFl | kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "MIDI status" },
{ "d0", kD0PcId, 0, 0, kOutDsvFl | kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "MIDI channel message d0" },
{ "d1", kD1PcId, 0, 0, kOutDsvFl | kInDsvFl | kUIntDsvFl | kOptArgDsvFl, "MIDI channel message d1" },
{ "thru", kThruPcId, 0, 0, kInDsvFl | kBoolDsvFl | kOptArgDsvFl, "Enable pass through."},
{ NULL, 0, 0, 0, 0 }
};
cmDspPicadae_t* p = cmDspInstAlloc(cmDspPicadae_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
cmDspSetDefaultUInt(ctx,&p->inst, kPgmPcId, 0, 0 );
return &p->inst;
}
cmDspRC_t _cmDspPicadaeReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
{
cmDspRC_t rc = kOkDspRC;
cmDspApplyAllDefaults(ctx,inst);
_cmDspPicadaePgm(ctx,inst,cmDspUInt(inst,kPgmPcId));
return rc;
}
cmDspRC_t _cmDspPicadaeRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
{
//cmDspPicadae_t* p = (cmDspPicadae_t*)inst;
switch( evt->dstVarId )
{
case kPgmPcId:
cmDspSetEvent(ctx,inst,evt);
_cmDspPicadaePgm(ctx,inst,cmDspUInt(inst,kPgmPcId));
break;
case kStatusPcId:
{
unsigned status = cmDsvGetUInt(evt->valuePtr);
unsigned stat_no_ch = status & 0xf0;
if( stat_no_ch == kNoteOnMdId || stat_no_ch == kNoteOffMdId || stat_no_ch == kCtlMdId )
{
//unsigned d0 = cmDspUInt(inst,kD0PcId);
unsigned ch = 0; //d0 % 8;
status = (status & 0xf0) + ch;
cmDspSetUInt(ctx,inst,kStatusPcId,status);
}
}
break;
default:
cmDspSetEvent(ctx,inst,evt);
break;
}
return kOkDspRC;
}
cmDspClass_t* cmPicadaeClassCons( cmDspCtx_t* ctx )
{
cmDspClassSetup(&_cmPicadaeDC,ctx,"Picadae",
NULL,
_cmDspPicadaeAlloc,
NULL,
_cmDspPicadaeReset,
NULL,
_cmDspPicadaeRecv,
NULL,
NULL,
"Picadaesynth Mapper");
return &_cmPicadaeDC;
}
//------------------------------------------------------------------------------------------------------------
//)
//( { label:cmDspRecdPlay file_desc:"Record audio segments from a live perfromance and play them back at a later time" kw:[sunit] }

View File

@ -17,6 +17,7 @@ extern "C" {
struct cmDspClass_str* cmActiveMeasClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmAmSyncClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmNanoMapClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmPicadaeClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmRecdPlayClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmGoertzelClassCons( cmDspCtx_t* ctx );
struct cmDspClass_str* cmSyncRecdClassCons( cmDspCtx_t* ctx );

View File

@ -16,6 +16,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"

View File

@ -72,6 +72,7 @@ extern "C" {
cmDspPresetMgr_t pm;
unsigned nextInstId;
unsigned pgmIdx;
cmSeH_t serialPortH;
cmUdpNetH_t netH; //

View File

@ -17,6 +17,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"

View File

@ -19,6 +19,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"

View File

@ -18,6 +18,7 @@
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmTime.h"
#include "cmSerialPort.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"
#include "cmDspCtx.h"

View File

@ -17,6 +17,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"

View File

@ -19,6 +19,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"
@ -61,7 +62,7 @@ cmDspRC_t _cmDspSysPgm_TimeLineLite(cmDspSysH_t h, void** userPtrPtr )
cmDspInst_t* ai0 = cmDspSysAllocInst(h,"AudioIn", NULL, 1, 0);
cmDspInst_t* ai1 = cmDspSysAllocInst(h,"AudioIn", NULL, 1, 1);
//cmDspInst_t* mip = cmDspSysAllocInst(h,"MidiIn", NULL, 2, "MOTU - Traveler mk3", "MIDI Port");
cmDspInst_t* mip = cmDspSysAllocInst(h,"MidiIn", NULL, 2, "Apple Inc. - IAC Driver", "Bus 1");
//cmDspInst_t* mip = cmDspSysAllocInst(h,"MidiIn", NULL, 2, "Apple Inc. - IAC Driver", "Bus 1");
cmDspInst_t* tlp = cmDspSysAllocInst(h,"TimeLine", "tl", 2, r.tlFn, r.tlPrefixPath );
cmDspInst_t* scp = cmDspSysAllocInst(h,"Score", "sc", 1, r.scFn );

View File

@ -17,6 +17,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"

View File

@ -17,6 +17,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"

View File

@ -17,6 +17,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"

View File

@ -19,6 +19,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmAudioSys.h"
#include "cmProcObj.h"
#include "cmDspCtx.h"
@ -165,7 +166,7 @@ cmDspRC_t _cmDspSysFinalize( cmDsp_t* p )
return rc;
}
cmDspRC_t cmDspSysInitialize( cmCtx_t* ctx, cmDspSysH_t* hp, cmUdpNetH_t netH )
cmDspRC_t cmDspSysInitialize( cmCtx_t* ctx, cmDspSysH_t* hp, cmUdpNetH_t netH, cmSeH_t serialPortH )
{
unsigned i;
cmDspRC_t rc = kOkDspRC;
@ -178,9 +179,10 @@ cmDspRC_t cmDspSysInitialize( cmCtx_t* ctx, cmDspSysH_t* hp, cmUdpNetH_t netH )
cmErrSetup(&p->err,&ctx->rpt,"DSP System");
//p->ctx.ctx = asCtx;
p->cmCtx = *ctx;
p->netH = netH;
p->pgmIdx = cmInvalidIdx;
p->cmCtx = *ctx;
p->netH = netH;
p->serialPortH = serialPortH;
p->pgmIdx = cmInvalidIdx;
// create the DSP class linked heap
if(cmLHeapIsValid( p->lhH = cmLHeapCreate(1024,ctx)) == false)
@ -1560,6 +1562,13 @@ cmSymTblH_t cmDspSysSymbolTable( cmDspSysH_t h )
return p->ctx.stH;
}
cmSeH_t cmDspSysSerialPort( cmDspSysH_t h )
{
cmDsp_t* p = _cmDspHandleToPtr(h);
return p->serialPortH;
}
unsigned cmDspSysRegisterStaticSymbol( cmDspSysH_t h, const cmChar_t* symLabel )
{ return cmSymTblRegisterStaticSymbol( cmDspSysSymbolTable(h), symLabel ); }

View File

@ -23,7 +23,7 @@ extern "C" {
// Control Functions
//
cmDspRC_t cmDspSysInitialize( cmCtx_t* ctx, cmDspSysH_t* hp, cmUdpNetH_t netH );
cmDspRC_t cmDspSysInitialize( cmCtx_t* ctx, cmDspSysH_t* hp, cmUdpNetH_t netH, cmSeH_t serialPortH );
cmDspRC_t cmDspSysFinalize( cmDspSysH_t* hp );
bool cmDspSysIsValid( cmDspSysH_t h );
@ -156,6 +156,7 @@ extern "C" {
double cmDspSysSampleRate( cmDspSysH_t h );
cmJsonH_t cmDspSysPgmRsrcHandle( cmDspSysH_t h );
cmSymTblH_t cmDspSysSymbolTable( cmDspSysH_t h );
cmSeH_t cmDspSysSerialPort( cmDspSysH_t h );
unsigned cmDspSysRegisterStaticSymbol( cmDspSysH_t h, const cmChar_t* symLabel );
unsigned cmDspSysRegisterSymbol( cmDspSysH_t h, const cmChar_t* symLabel );

View File

@ -19,6 +19,7 @@
#include "cmThread.h"
#include "cmUdpPort.h"
#include "cmUdpNet.h"
#include "cmSerialPort.h"
#include "cmTime.h"
#include "cmAudioSys.h"