cwMidiAlsa.h/cpp,cwMidiPort.h : Updated MIDI system to remove global manager variable.
This commit is contained in:
parent
68b8a15714
commit
59507913e0
350
cwMidiAlsa.cpp
350
cwMidiAlsa.cpp
@ -29,43 +29,35 @@ namespace cw
|
|||||||
// MIDI devices
|
// MIDI devices
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char* nameStr; // string label for this device
|
char* nameStr; // string label for this device
|
||||||
unsigned iPortCnt; // input ports on this device
|
unsigned iPortCnt; // input ports on this device
|
||||||
port_t* iPortArray;
|
port_t* iPortArray; //
|
||||||
unsigned oPortCnt; // output ports on this device
|
unsigned oPortCnt; // output ports on this device
|
||||||
port_t* oPortArray;
|
port_t* oPortArray; //
|
||||||
unsigned char clientId; // ALSA client id (all ports on this device use use this client id in their address)
|
unsigned char clientId; // ALSA client id (all ports on this device use use this client id in their address)
|
||||||
|
|
||||||
} dev_t;
|
} dev_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct device_str
|
||||||
{
|
{
|
||||||
unsigned devCnt; // MIDI devices attached to this computer
|
unsigned devCnt; // MIDI devices attached to this computer
|
||||||
dev_t* devArray;
|
dev_t* devArray;
|
||||||
|
cbFunc_t cbFunc; // MIDI input application callback
|
||||||
|
void* cbDataPtr;
|
||||||
|
snd_seq_t* h; // ALSA system sequencer handle
|
||||||
|
snd_seq_addr_t alsa_addr; // ALSA client/port address representing the application
|
||||||
|
int alsa_queue; // ALSA device queue
|
||||||
|
thread::handle_t thH; // MIDI input listening thread
|
||||||
|
int alsa_fdCnt; // MIDI input driver file descriptor array
|
||||||
|
struct pollfd* alsa_fd;
|
||||||
|
dev_t* prvRcvDev; // the last device and port to rcv MIDI
|
||||||
|
port_t* prvRcvPort;
|
||||||
|
unsigned prvTimeMicroSecs; // time of last recognized event in microseconds
|
||||||
|
unsigned eventCnt; // count of recognized events
|
||||||
|
time::spec_t baseTimeStamp;
|
||||||
|
} device_t;
|
||||||
|
|
||||||
cbFunc_t cbFunc; // MIDI input application callback
|
device_t* _handleToPtr( handle_t h ){ return handleToPtr<handle_t,device_t>(h); }
|
||||||
void* cbDataPtr;
|
|
||||||
|
|
||||||
snd_seq_t* h; // ALSA system sequencer handle
|
|
||||||
|
|
||||||
snd_seq_addr_t alsa_addr; // ALSA client/port address representing the application
|
|
||||||
int alsa_queue; // ALSA device queue
|
|
||||||
thread::handle_t thH; // MIDI input listening thread
|
|
||||||
|
|
||||||
int alsa_fdCnt; // MIDI input driver file descriptor array
|
|
||||||
struct pollfd* alsa_fd;
|
|
||||||
|
|
||||||
dev_t* prvRcvDev; // the last device and port to rcv MIDI
|
|
||||||
port_t* prvRcvPort;
|
|
||||||
|
|
||||||
unsigned prvTimeMicroSecs; // time of last recognized event in microseconds
|
|
||||||
unsigned eventCnt; // count of recognized events
|
|
||||||
|
|
||||||
time::spec_t baseTimeStamp;
|
|
||||||
|
|
||||||
} cmMpRoot_t;
|
|
||||||
|
|
||||||
cmMpRoot_t* _cmMpRoot = NULL;
|
|
||||||
|
|
||||||
rc_t _cmMpErrMsgV(rc_t rc, int alsaRc, const char* fmt, va_list vl )
|
rc_t _cmMpErrMsgV(rc_t rc, int alsaRc, const char* fmt, va_list vl )
|
||||||
{
|
{
|
||||||
@ -97,9 +89,8 @@ namespace cw
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_t* _cmMpClientIdToDev( int clientId )
|
dev_t* _cmMpClientIdToDev( device_t* p, int clientId )
|
||||||
{
|
{
|
||||||
cmMpRoot_t* p = _cmMpRoot;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for(i=0; i<p->devCnt; ++i)
|
for(i=0; i<p->devCnt; ++i)
|
||||||
if( p->devArray[i].clientId == clientId )
|
if( p->devArray[i].clientId == clientId )
|
||||||
@ -126,11 +117,10 @@ namespace cw
|
|||||||
*d1 = v & 0x7f;
|
*d1 = v & 0x7f;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_t cmMpPoll()
|
rc_t _cmMpPoll(device_t* p)
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
cmMpRoot_t* p = _cmMpRoot;
|
int timeOutMs = 50;
|
||||||
int timeOutMs = 50;
|
|
||||||
|
|
||||||
snd_seq_event_t *ev;
|
snd_seq_event_t *ev;
|
||||||
|
|
||||||
@ -152,7 +142,7 @@ namespace cw
|
|||||||
|
|
||||||
// get the device this event arrived from
|
// get the device this event arrived from
|
||||||
if( p->prvRcvDev==NULL || p->prvRcvDev->clientId != ev->source.client )
|
if( p->prvRcvDev==NULL || p->prvRcvDev->clientId != ev->source.client )
|
||||||
p->prvRcvDev = _cmMpClientIdToDev(ev->source.client);
|
p->prvRcvDev = _cmMpClientIdToDev(p,ev->source.client);
|
||||||
|
|
||||||
// get the port this event arrived from
|
// get the port this event arrived from
|
||||||
if( p->prvRcvDev != NULL && (p->prvRcvPort==NULL || p->prvRcvPort->alsa_addr.port != ev->source.port) )
|
if( p->prvRcvDev != NULL && (p->prvRcvPort==NULL || p->prvRcvPort->alsa_addr.port != ev->source.port) )
|
||||||
@ -281,15 +271,16 @@ namespace cw
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool _threadCbFunc(void* param)
|
bool _threadCbFunc(void* arg)
|
||||||
{
|
{
|
||||||
cmMpPoll();
|
device_t* p = static_cast<device_t*>(arg);
|
||||||
|
_cmMpPoll(p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_t _cmMpAllocStruct( cmMpRoot_t* p, const char* appNameStr, cbFunc_t cbFunc, void* cbDataPtr, unsigned parserBufByteCnt )
|
rc_t _cmMpAllocStruct( device_t* p, const char* appNameStr, cbFunc_t cbFunc, void* cbDataPtr, unsigned parserBufByteCnt )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
snd_seq_client_info_t* cip = NULL;
|
snd_seq_client_info_t* cip = NULL;
|
||||||
snd_seq_port_info_t* pip = NULL;
|
snd_seq_port_info_t* pip = NULL;
|
||||||
snd_seq_port_subscribe_t *subs = NULL;
|
snd_seq_port_subscribe_t *subs = NULL;
|
||||||
@ -498,28 +489,100 @@ namespace cw
|
|||||||
textBuf::print( tbH,")\n");
|
textBuf::print( tbH,")\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc_t _destroy( device_t* p )
|
||||||
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
|
if( p != NULL )
|
||||||
|
{
|
||||||
|
int arc;
|
||||||
|
|
||||||
|
// stop the thread first
|
||||||
|
if((rc = thread::destroy(p->thH)) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = _cmMpErrMsg(rc,0,"Thread destroy failed.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop the queue
|
||||||
|
if( p->h != NULL )
|
||||||
|
if((arc = snd_seq_stop_queue(p->h,p->alsa_queue, NULL)) < 0 )
|
||||||
|
{
|
||||||
|
rc = _cmMpErrMsg(kOpFailRC,arc,"ALSA queue stop failed.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// release the alsa queue
|
||||||
|
if( p->alsa_queue != -1 )
|
||||||
|
{
|
||||||
|
if((arc = snd_seq_free_queue(p->h,p->alsa_queue)) < 0 )
|
||||||
|
rc = _cmMpErrMsg(kOpFailRC,arc,"ALSA queue release failed.");
|
||||||
|
else
|
||||||
|
p->alsa_queue = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// release the alsa system handle
|
||||||
|
if( p->h != NULL )
|
||||||
|
{
|
||||||
|
if( (arc = snd_seq_close(p->h)) < 0 )
|
||||||
|
rc = _cmMpErrMsg(kOpFailRC,arc,"ALSA sequencer close failed.");
|
||||||
|
else
|
||||||
|
p->h = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned i,j;
|
||||||
|
for(i=0; i<p->devCnt; ++i)
|
||||||
|
{
|
||||||
|
for(j=0; j<p->devArray[i].iPortCnt; ++j)
|
||||||
|
{
|
||||||
|
parser::destroy(p->devArray[i].iPortArray[j].parserH);
|
||||||
|
mem::release( p->devArray[i].iPortArray[j].nameStr );
|
||||||
|
}
|
||||||
|
|
||||||
|
for(j=0; j<p->devArray[i].oPortCnt; ++j)
|
||||||
|
{
|
||||||
|
mem::release( p->devArray[i].oPortArray[j].nameStr );
|
||||||
|
}
|
||||||
|
|
||||||
|
mem::release(p->devArray[i].iPortArray);
|
||||||
|
mem::release(p->devArray[i].oPortArray);
|
||||||
|
mem::release(p->devArray[i].nameStr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mem::release(p->devArray);
|
||||||
|
|
||||||
|
mem::free(p->alsa_fd);
|
||||||
|
|
||||||
|
mem::release(p);
|
||||||
|
|
||||||
|
}
|
||||||
|
errLabel:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // device
|
} // device
|
||||||
} // midi
|
} // midi
|
||||||
} // cw
|
} // cw
|
||||||
|
|
||||||
cw::rc_t cw::midi::device::initialize( cbFunc_t cbFunc, void* cbArg, unsigned parserBufByteCnt, const char* appNameStr )
|
|
||||||
{
|
|
||||||
rc_t rc = kOkRC;
|
|
||||||
int arc = 0;
|
|
||||||
cmMpRoot_t* p = NULL;
|
|
||||||
|
|
||||||
if((rc = finalize()) != kOkRC )
|
cw::rc_t cw::midi::device::create( handle_t& h, cbFunc_t cbFunc, void* cbArg, unsigned parserBufByteCnt, const char* appNameStr )
|
||||||
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
int arc = 0;
|
||||||
|
|
||||||
|
if((rc = destroy(h)) != kOkRC )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
// allocate the global root object
|
device_t* p = mem::allocZ<device_t>(1);
|
||||||
_cmMpRoot = p = mem::allocZ<cmMpRoot_t>(1);
|
|
||||||
p->h = NULL;
|
p->h = NULL;
|
||||||
p->alsa_queue = -1;
|
p->alsa_queue = -1;
|
||||||
|
|
||||||
|
|
||||||
// create the listening thread
|
// create the listening thread
|
||||||
if((rc = thread::create( p->thH, _threadCbFunc, NULL)) != kOkRC )
|
if((rc = thread::create( p->thH, _threadCbFunc, p)) != kOkRC )
|
||||||
{
|
{
|
||||||
rc = _cmMpErrMsg(rc,0,"Thread initialization failed.");
|
rc = _cmMpErrMsg(rc,0,"Thread initialization failed.");
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
@ -563,140 +626,95 @@ cw::rc_t cw::midi::device::initialize( cbFunc_t cbFunc, void* cbArg, unsigned p
|
|||||||
if((rc = thread::unpause(p->thH)) != kOkRC )
|
if((rc = thread::unpause(p->thH)) != kOkRC )
|
||||||
rc = _cmMpErrMsg(rc,0,"Thread start failed.");
|
rc = _cmMpErrMsg(rc,0,"Thread start failed.");
|
||||||
|
|
||||||
|
h.set(p);
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
|
|
||||||
if( rc != kOkRC )
|
if( rc != kOkRC )
|
||||||
finalize();
|
_destroy(p);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cw::rc_t cw::midi::device::finalize()
|
|
||||||
|
cw::rc_t cw::midi::device::destroy( handle_t& h )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
cmMpRoot_t* p = _cmMpRoot;
|
|
||||||
|
if( !h.isValid() )
|
||||||
|
return rc;
|
||||||
|
|
||||||
if( _cmMpRoot != NULL )
|
device_t* p = _handleToPtr(h);
|
||||||
{
|
|
||||||
int arc;
|
|
||||||
|
|
||||||
// stop the thread first
|
if((rc = _destroy(p)) != kOkRC )
|
||||||
if((rc = thread::destroy(p->thH)) != kOkRC )
|
return rc;
|
||||||
{
|
|
||||||
rc = _cmMpErrMsg(rc,0,"Thread destroy failed.");
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// stop the queue
|
h.clear();
|
||||||
if( p->h != NULL )
|
|
||||||
if((arc = snd_seq_stop_queue(p->h,p->alsa_queue, NULL)) < 0 )
|
|
||||||
{
|
|
||||||
rc = _cmMpErrMsg(kOpFailRC,arc,"ALSA queue stop failed.");
|
|
||||||
goto errLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// release the alsa queue
|
|
||||||
if( p->alsa_queue != -1 )
|
|
||||||
{
|
|
||||||
if((arc = snd_seq_free_queue(p->h,p->alsa_queue)) < 0 )
|
|
||||||
rc = _cmMpErrMsg(kOpFailRC,arc,"ALSA queue release failed.");
|
|
||||||
else
|
|
||||||
p->alsa_queue = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// release the alsa system handle
|
|
||||||
if( p->h != NULL )
|
|
||||||
{
|
|
||||||
if( (arc = snd_seq_close(p->h)) < 0 )
|
|
||||||
rc = _cmMpErrMsg(kOpFailRC,arc,"ALSA sequencer close failed.");
|
|
||||||
else
|
|
||||||
p->h = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned i,j;
|
|
||||||
for(i=0; i<p->devCnt; ++i)
|
|
||||||
{
|
|
||||||
for(j=0; j<p->devArray[i].iPortCnt; ++j)
|
|
||||||
{
|
|
||||||
parser::destroy(p->devArray[i].iPortArray[j].parserH);
|
|
||||||
mem::release( p->devArray[i].iPortArray[j].nameStr );
|
|
||||||
}
|
|
||||||
|
|
||||||
for(j=0; j<p->devArray[i].oPortCnt; ++j)
|
|
||||||
{
|
|
||||||
mem::release( p->devArray[i].oPortArray[j].nameStr );
|
|
||||||
}
|
|
||||||
|
|
||||||
mem::release(p->devArray[i].iPortArray);
|
|
||||||
mem::release(p->devArray[i].oPortArray);
|
|
||||||
mem::release(p->devArray[i].nameStr);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
mem::release(p->devArray);
|
|
||||||
|
|
||||||
mem::free(p->alsa_fd);
|
|
||||||
|
|
||||||
mem::release(_cmMpRoot);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
errLabel:
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cw::midi::device::isInitialized()
|
bool cw::midi::device::isInitialized(handle_t h)
|
||||||
{ return _cmMpRoot!=NULL; }
|
{ return h.isValid(); }
|
||||||
|
|
||||||
unsigned cw::midi::device::count()
|
unsigned cw::midi::device::count(handle_t h)
|
||||||
{ return _cmMpRoot==NULL ? 0 : _cmMpRoot->devCnt; }
|
{
|
||||||
|
device_t* p = _handleToPtr(h);
|
||||||
const char* cw::midi::device::name( unsigned devIdx )
|
return p->devCnt;
|
||||||
{
|
|
||||||
if( _cmMpRoot==NULL || devIdx>=_cmMpRoot->devCnt)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return _cmMpRoot->devArray[devIdx].nameStr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned cw::midi::device::portCount( unsigned devIdx, unsigned flags )
|
const char* cw::midi::device::name( handle_t h, unsigned devIdx )
|
||||||
|
{
|
||||||
|
device_t* p = _handleToPtr(h);
|
||||||
|
|
||||||
|
if( p==NULL || devIdx>=p->devCnt)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return p->devArray[devIdx].nameStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned cw::midi::device::portCount( handle_t h, unsigned devIdx, unsigned flags )
|
||||||
{
|
{
|
||||||
if( _cmMpRoot==NULL || devIdx>=_cmMpRoot->devCnt)
|
device_t* p = _handleToPtr(h);
|
||||||
|
|
||||||
|
if( p==NULL || devIdx>=p->devCnt)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if( cwIsFlag(flags,kInMpFl) )
|
if( cwIsFlag(flags,kInMpFl) )
|
||||||
return _cmMpRoot->devArray[devIdx].iPortCnt;
|
return p->devArray[devIdx].iPortCnt;
|
||||||
|
|
||||||
return _cmMpRoot->devArray[devIdx].oPortCnt;
|
return p->devArray[devIdx].oPortCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* cw::midi::device::portName( unsigned devIdx, unsigned flags, unsigned portIdx )
|
const char* cw::midi::device::portName( handle_t h, unsigned devIdx, unsigned flags, unsigned portIdx )
|
||||||
{
|
{
|
||||||
if( _cmMpRoot==NULL || devIdx>=_cmMpRoot->devCnt)
|
device_t* p = _handleToPtr(h);
|
||||||
|
|
||||||
|
if( p==NULL || devIdx>=p->devCnt)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if( cwIsFlag(flags,kInMpFl) )
|
if( cwIsFlag(flags,kInMpFl) )
|
||||||
{
|
{
|
||||||
if( portIdx >= _cmMpRoot->devArray[devIdx].iPortCnt )
|
if( portIdx >= p->devArray[devIdx].iPortCnt )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return _cmMpRoot->devArray[devIdx].iPortArray[portIdx].nameStr;
|
return p->devArray[devIdx].iPortArray[portIdx].nameStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( portIdx >= _cmMpRoot->devArray[devIdx].oPortCnt )
|
if( portIdx >= p->devArray[devIdx].oPortCnt )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return _cmMpRoot->devArray[devIdx].oPortArray[portIdx].nameStr;
|
return p->devArray[devIdx].oPortArray[portIdx].nameStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cw::rc_t cw::midi::device::send( unsigned devIdx, unsigned portIdx, byte_t status, byte_t d0, byte_t d1 )
|
cw::rc_t cw::midi::device::send( handle_t h, unsigned devIdx, unsigned portIdx, byte_t status, byte_t d0, byte_t d1 )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
snd_seq_event_t ev;
|
snd_seq_event_t ev;
|
||||||
int arc;
|
int arc;
|
||||||
cmMpRoot_t* p = _cmMpRoot;
|
device_t* p = _handleToPtr(h);
|
||||||
|
|
||||||
assert( p!=NULL && devIdx < p->devCnt && portIdx < p->devArray[devIdx].oPortCnt );
|
assert( p!=NULL && devIdx < p->devCnt && portIdx < p->devArray[devIdx].oPortCnt );
|
||||||
|
|
||||||
@ -779,23 +797,23 @@ cw::rc_t cw::midi::device::send( unsigned devIdx, unsigned portIdx, byte_t stat
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
cw::rc_t cw::midi::device::sendData( unsigned devIdx, unsigned portIdx, const byte_t* dataPtr, unsigned byteCnt )
|
cw::rc_t cw::midi::device::sendData( handle_t h, unsigned devIdx, unsigned portIdx, const byte_t* dataPtr, unsigned byteCnt )
|
||||||
{
|
{
|
||||||
return cwLogError(kInvalidOpRC,"cmMpDeviceSendData() has not yet been implemented for ALSA.");
|
return cwLogError(kInvalidOpRC,"cmMpDeviceSendData() has not yet been implemented for ALSA.");
|
||||||
}
|
}
|
||||||
|
|
||||||
cw::rc_t cw::midi::device::installCallback( unsigned devIdx, unsigned portIdx, cbFunc_t cbFunc, void* cbDataPtr )
|
cw::rc_t cw::midi::device::installCallback( handle_t h, unsigned devIdx, unsigned portIdx, cbFunc_t cbFunc, void* cbDataPtr )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
unsigned di;
|
unsigned di;
|
||||||
unsigned dn = count();
|
unsigned dn = count(h);
|
||||||
cmMpRoot_t* p = _cmMpRoot;
|
device_t* p = _handleToPtr(h);
|
||||||
|
|
||||||
for(di=0; di<dn; ++di)
|
for(di=0; di<dn; ++di)
|
||||||
if( di==devIdx || devIdx == kInvalidIdx )
|
if( di==devIdx || devIdx == kInvalidIdx )
|
||||||
{
|
{
|
||||||
unsigned pi;
|
unsigned pi;
|
||||||
unsigned pn = portCount(di,kInMpFl);
|
unsigned pn = portCount(h,di,kInMpFl);
|
||||||
|
|
||||||
for(pi=0; pi<pn; ++pi)
|
for(pi=0; pi<pn; ++pi)
|
||||||
if( pi==portIdx || portIdx == kInvalidIdx )
|
if( pi==portIdx || portIdx == kInvalidIdx )
|
||||||
@ -807,23 +825,23 @@ cw::rc_t cw::midi::device::installCallback( unsigned devIdx, unsigned portIdx
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
cw::rc_t cw::midi::device::removeCallback( unsigned devIdx, unsigned portIdx, cbFunc_t cbFunc, void* cbDataPtr )
|
cw::rc_t cw::midi::device::removeCallback( handle_t h, unsigned devIdx, unsigned portIdx, cbFunc_t cbFunc, void* cbDataPtr )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
unsigned di;
|
unsigned di;
|
||||||
unsigned dn = count();
|
unsigned dn = count(h);
|
||||||
unsigned remCnt = 0;
|
unsigned remCnt = 0;
|
||||||
cmMpRoot_t* p = _cmMpRoot;
|
device_t* p = _handleToPtr(h);
|
||||||
|
|
||||||
for(di=0; di<dn; ++di)
|
for(di=0; di<dn; ++di)
|
||||||
if( di==devIdx || devIdx == kInvalidIdx )
|
if( di==devIdx || devIdx == kInvalidIdx )
|
||||||
{
|
{
|
||||||
unsigned pi;
|
unsigned pi;
|
||||||
unsigned pn = portCount(di,kInMpFl);
|
unsigned pn = portCount(h,di,kInMpFl);
|
||||||
|
|
||||||
for(pi=0; pi<pn; ++pi)
|
for(pi=0; pi<pn; ++pi)
|
||||||
if( pi==portIdx || portIdx == kInvalidIdx )
|
if( pi==portIdx || portIdx == kInvalidIdx )
|
||||||
if( parser::hasCallback( p->devArray[di].iPortArray[pi].parserH, cbFunc, cbDataPtr ) )
|
if( parser::hasCallback(p->devArray[di].iPortArray[pi].parserH, cbFunc, cbDataPtr ) )
|
||||||
{
|
{
|
||||||
if( parser::removeCallback( p->devArray[di].iPortArray[pi].parserH, cbFunc, cbDataPtr ) != kOkRC )
|
if( parser::removeCallback( p->devArray[di].iPortArray[pi].parserH, cbFunc, cbDataPtr ) != kOkRC )
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
@ -839,17 +857,17 @@ cw::rc_t cw::midi::device::removeCallback( unsigned devIdx, unsigned portIdx
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cw::midi::device::usesCallback( unsigned devIdx, unsigned portIdx, cbFunc_t cbFunc, void* cbDataPtr )
|
bool cw::midi::device::usesCallback( handle_t h, unsigned devIdx, unsigned portIdx, cbFunc_t cbFunc, void* cbDataPtr )
|
||||||
{
|
{
|
||||||
unsigned di;
|
unsigned di;
|
||||||
unsigned dn = count();
|
unsigned dn = count(h);
|
||||||
cmMpRoot_t* p = _cmMpRoot;
|
device_t* p = _handleToPtr(h);
|
||||||
|
|
||||||
for(di=0; di<dn; ++di)
|
for(di=0; di<dn; ++di)
|
||||||
if( di==devIdx || devIdx == kInvalidIdx )
|
if( di==devIdx || devIdx == kInvalidIdx )
|
||||||
{
|
{
|
||||||
unsigned pi;
|
unsigned pi;
|
||||||
unsigned pn = portCount(di,kInMpFl);
|
unsigned pn = portCount(h,di,kInMpFl);
|
||||||
|
|
||||||
for(pi=0; pi<pn; ++pi)
|
for(pi=0; pi<pn; ++pi)
|
||||||
if( pi==portIdx || portIdx == kInvalidIdx )
|
if( pi==portIdx || portIdx == kInvalidIdx )
|
||||||
@ -862,9 +880,9 @@ bool cw::midi::device::usesCallback( unsigned devIdx, unsigned portIdx
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cw::midi::device::report( textBuf::handle_t tbH )
|
void cw::midi::device::report( handle_t h, textBuf::handle_t tbH )
|
||||||
{
|
{
|
||||||
cmMpRoot_t* p = _cmMpRoot;
|
device_t* p = _handleToPtr(h);
|
||||||
unsigned i,j;
|
unsigned i,j;
|
||||||
|
|
||||||
textBuf::print( tbH,"Buffer size bytes in:%i out:%i\n",snd_seq_get_input_buffer_size(p->h),snd_seq_get_output_buffer_size(p->h));
|
textBuf::print( tbH,"Buffer size bytes in:%i out:%i\n",snd_seq_get_input_buffer_size(p->h),snd_seq_get_output_buffer_size(p->h));
|
||||||
|
@ -30,7 +30,7 @@ namespace cw
|
|||||||
|
|
||||||
typedef struct cmMpParserCb_str
|
typedef struct cmMpParserCb_str
|
||||||
{
|
{
|
||||||
cbFunc_t cbFunc;
|
cbFunc_t cbFunc;
|
||||||
void* cbDataPtr;
|
void* cbDataPtr;
|
||||||
struct cmMpParserCb_str* linkPtr;
|
struct cmMpParserCb_str* linkPtr;
|
||||||
} cbRecd_t;
|
} cbRecd_t;
|
||||||
@ -478,23 +478,23 @@ bool cw::midi::parser::hasCallback( handle_t h, cbFunc_t cbFunc, void* cbArg )
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
unsigned cw::midi::device::nameToIndex(const char* deviceName)
|
unsigned cw::midi::device::nameToIndex(handle_t h, const char* deviceName)
|
||||||
{
|
{
|
||||||
assert(deviceName!=NULL);
|
assert(deviceName!=NULL);
|
||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned n = count();
|
unsigned n = count(h);
|
||||||
for(i=0; i<n; ++i)
|
for(i=0; i<n; ++i)
|
||||||
if( strcmp(name(i),deviceName)==0)
|
if( strcmp(name(h,i),deviceName)==0)
|
||||||
return i;
|
return i;
|
||||||
return kInvalidIdx;
|
return kInvalidIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned cw::midi::device::portNameToIndex( unsigned devIdx, unsigned flags, const char* portNameStr )
|
unsigned cw::midi::device::portNameToIndex( handle_t h, unsigned devIdx, unsigned flags, const char* portNameStr )
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned n = portCount(devIdx,flags);
|
unsigned n = portCount(h,devIdx,flags);
|
||||||
for(i=0; i<n; ++i)
|
for(i=0; i<n; ++i)
|
||||||
if( strcmp(portName(devIdx,flags,i),portNameStr)==0)
|
if( strcmp(portName(h,devIdx,flags,i),portNameStr)==0)
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
return kInvalidIdx;
|
return kInvalidIdx;
|
||||||
@ -532,13 +532,14 @@ namespace cw
|
|||||||
|
|
||||||
cw::rc_t cw::midi::device::test()
|
cw::rc_t cw::midi::device::test()
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
char ch;
|
char ch;
|
||||||
unsigned parserBufByteCnt = 1024;
|
unsigned parserBufByteCnt = 1024;
|
||||||
textBuf::handle_t tbH;
|
textBuf::handle_t tbH;
|
||||||
|
handle_t h;
|
||||||
|
|
||||||
// initialie the MIDI system
|
// initialie the MIDI system
|
||||||
if((rc = initialize(testCallback,NULL,parserBufByteCnt,"app")) != kOkRC )
|
if((rc = create(h,testCallback,NULL,parserBufByteCnt,"app")) != kOkRC )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
// create a text buffer to hold the MIDI system report text
|
// create a text buffer to hold the MIDI system report text
|
||||||
@ -546,18 +547,18 @@ cw::rc_t cw::midi::device::test()
|
|||||||
goto errLabel;
|
goto errLabel;
|
||||||
|
|
||||||
// generate and print the MIDI system report
|
// generate and print the MIDI system report
|
||||||
report(tbH);
|
report(h,tbH);
|
||||||
cwLogInfo("%s",textBuf::text(tbH));
|
cwLogInfo("%s",textBuf::text(tbH));
|
||||||
|
|
||||||
cwLogInfo("any key to send note-on (<q>=quit)\n");
|
cwLogInfo("any key to send note-on (<q>=quit)\n");
|
||||||
|
|
||||||
while((ch = getchar()) != 'q')
|
while((ch = getchar()) != 'q')
|
||||||
{
|
{
|
||||||
send(2,0,0x90,60,60);
|
send(h,2,0,0x90,60,60);
|
||||||
}
|
}
|
||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
textBuf::destroy(tbH);
|
textBuf::destroy(tbH);
|
||||||
finalize();
|
destroy(h);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
33
cwMidiPort.h
33
cwMidiPort.h
@ -65,28 +65,31 @@ namespace cw
|
|||||||
|
|
||||||
namespace device
|
namespace device
|
||||||
{
|
{
|
||||||
|
typedef handle< struct device_str> handle_t;
|
||||||
|
|
||||||
// 'cbFunc' and 'cbDataPtr' are optional (they may be set to NULL). In this case
|
// 'cbFunc' and 'cbDataPtr' are optional (they may be set to NULL). In this case
|
||||||
// 'cbFunc' and 'cbDataPtr' may be set in a later call to cmMpInstallCallback().
|
// 'cbFunc' and 'cbDataPtr' may be set in a later call to cmMpInstallCallback().
|
||||||
rc_t initialize( cbFunc_t cbFunc, void* cbDataPtr, unsigned parserBufByteCnt, const char* appNameStr );
|
rc_t create( handle_t& h, cbFunc_t cbFunc, void* cbDataPtr, unsigned parserBufByteCnt, const char* appNameStr );
|
||||||
rc_t finalize();
|
rc_t destroy( handle_t& h);
|
||||||
bool isInitialized();
|
bool isInitialized( handle_t h );
|
||||||
|
|
||||||
unsigned count();
|
unsigned count( handle_t h );
|
||||||
const char* name( unsigned devIdx );
|
const char* name( handle_t h, unsigned devIdx );
|
||||||
unsigned nameToIndex(const char* deviceName);
|
unsigned nameToIndex(handle_t h, const char* deviceName);
|
||||||
unsigned portCount( unsigned devIdx, unsigned flags );
|
unsigned portCount( handle_t h, unsigned devIdx, unsigned flags );
|
||||||
const char* portName( unsigned devIdx, unsigned flags, unsigned portIdx );
|
const char* portName( handle_t h, unsigned devIdx, unsigned flags, unsigned portIdx );
|
||||||
unsigned portNameToIndex( unsigned devIdx, unsigned flags, const char* portName );
|
unsigned portNameToIndex( handle_t h, unsigned devIdx, unsigned flags, const char* portName );
|
||||||
rc_t send( unsigned devIdx, unsigned portIdx, byte_t st, byte_t d0, byte_t d1 );
|
rc_t send( handle_t h, unsigned devIdx, unsigned portIdx, byte_t st, byte_t d0, byte_t d1 );
|
||||||
rc_t sendData( unsigned devIdx, unsigned portIdx, const byte_t* dataPtr, unsigned byteCnt );
|
rc_t sendData( handle_t h, unsigned devIdx, unsigned portIdx, const byte_t* dataPtr, unsigned byteCnt );
|
||||||
|
|
||||||
// Set devIdx to -1 to assign the callback to all devices.
|
// Set devIdx to -1 to assign the callback to all devices.
|
||||||
// Set portIdx to -1 to assign the callback to all ports on the specified devices.
|
// Set portIdx to -1 to assign the callback to all ports on the specified devices.
|
||||||
//
|
//
|
||||||
rc_t installCallback( unsigned devIdx, unsigned portIdx, cbFunc_t cbFunc, void* cbDataPtr );
|
rc_t installCallback( handle_t h, unsigned devIdx, unsigned portIdx, cbFunc_t cbFunc, void* cbDataPtr );
|
||||||
rc_t removeCallback( unsigned devIdx, unsigned portIdx, cbFunc_t cbFunc, void* cbDataPtr );
|
rc_t removeCallback( handle_t h, unsigned devIdx, unsigned portIdx, cbFunc_t cbFunc, void* cbDataPtr );
|
||||||
bool usesCallback( unsigned devIdx, unsigned portIdx, cbFunc_t cbFunc, void* cbDataPtr );
|
bool usesCallback( handle_t h, unsigned devIdx, unsigned portIdx, cbFunc_t cbFunc, void* cbDataPtr );
|
||||||
void report( textBuf::handle_t h);
|
|
||||||
|
void report( handle_t h, textBuf::handle_t tbH);
|
||||||
|
|
||||||
rc_t test();
|
rc_t test();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user