218 lines
5.0 KiB
C++
218 lines
5.0 KiB
C++
|
#include "cwCommon.h"
|
||
|
#include "cwLog.h"
|
||
|
#include "cwCommonImpl.h"
|
||
|
#include "cwMem.h"
|
||
|
#include "cwTime.h"
|
||
|
#include "cwAudioDevice.h"
|
||
|
#include "cwText.h"
|
||
|
|
||
|
namespace cw
|
||
|
{
|
||
|
namespace audio
|
||
|
{
|
||
|
namespace device
|
||
|
{
|
||
|
typedef struct drv_str
|
||
|
{
|
||
|
unsigned begIdx;
|
||
|
unsigned endIdx;
|
||
|
driver_t* drv;
|
||
|
struct drv_str* link;
|
||
|
} drv_t;
|
||
|
|
||
|
typedef struct device_str
|
||
|
{
|
||
|
drv_t* drvList = nullptr;
|
||
|
unsigned nextDrvIdx = 0;
|
||
|
} device_t;
|
||
|
|
||
|
inline device_t* _handleToPtr( handle_t h ){ return handleToPtr<handle_t,device_t>(h); }
|
||
|
|
||
|
cw::rc_t _destroy( device_t* p )
|
||
|
{
|
||
|
drv_t* d = p->drvList;
|
||
|
while( d != nullptr )
|
||
|
{
|
||
|
drv_t* d0 = d->link;
|
||
|
memRelease(d);
|
||
|
d = d0;
|
||
|
}
|
||
|
|
||
|
memRelease(p);
|
||
|
|
||
|
return kOkRC;
|
||
|
}
|
||
|
|
||
|
drv_t* _indexToDriver( device_t* p, unsigned idx )
|
||
|
{
|
||
|
drv_t* l = p->drvList;
|
||
|
for(; l != nullptr; l=l->link )
|
||
|
if( l->begIdx <= idx && idx <= l->endIdx )
|
||
|
return l;
|
||
|
|
||
|
cwLogError(kInvalidArgRC,"An invalid audio device index (%) was requested.",idx);
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
drv_t* _indexToDriver( handle_t h, unsigned idx )
|
||
|
{
|
||
|
device_t* p = _handleToPtr(h);
|
||
|
return _indexToDriver(p,idx);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
cw::rc_t cw::audio::device::create( handle_t& hRef )
|
||
|
{
|
||
|
rc_t rc;
|
||
|
if((rc = destroy(hRef)) != kOkRC)
|
||
|
return rc;
|
||
|
|
||
|
device_t* p = memAllocZ<device_t>();
|
||
|
hRef.set(p);
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
cw::rc_t cw::audio::device::destroy( handle_t& hRef )
|
||
|
{
|
||
|
rc_t rc = kOkRC;
|
||
|
if( !hRef.isValid() )
|
||
|
return rc;
|
||
|
|
||
|
device_t* p = _handleToPtr(hRef);
|
||
|
|
||
|
if((rc = _destroy(p)) != kOkRC )
|
||
|
return rc;
|
||
|
|
||
|
hRef.clear();
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
cw::rc_t cw::audio::device::registerDriver( handle_t h, driver_t* drv )
|
||
|
{
|
||
|
device_t* p = _handleToPtr(h);
|
||
|
|
||
|
unsigned n = drv->deviceCount( drv );
|
||
|
if( n > 0 )
|
||
|
{
|
||
|
drv_t* d = memAllocZ<drv_t>();
|
||
|
|
||
|
d->begIdx = p->nextDrvIdx;
|
||
|
p->nextDrvIdx += n;
|
||
|
d->endIdx = p->nextDrvIdx-1;
|
||
|
d->drv = drv;
|
||
|
d->link = p->drvList;
|
||
|
p->drvList = d;
|
||
|
}
|
||
|
|
||
|
return kOkRC;
|
||
|
}
|
||
|
|
||
|
unsigned cw::audio::device::deviceCount( handle_t h )
|
||
|
{
|
||
|
device_t* p = _handleToPtr(h);
|
||
|
return p->nextDrvIdx;
|
||
|
}
|
||
|
|
||
|
unsigned cw::audio::device::deviceLabelToIndex( handle_t h, const char* label )
|
||
|
{
|
||
|
unsigned n = deviceCount(h);
|
||
|
unsigned i;
|
||
|
for(i=0; i<n; ++i)
|
||
|
{
|
||
|
const char* s = deviceLabel(h,i);
|
||
|
if( textCompare(s,label)==0)
|
||
|
return i;
|
||
|
}
|
||
|
return kInvalidIdx;
|
||
|
}
|
||
|
|
||
|
|
||
|
const char* cw::audio::device::deviceLabel( handle_t h, unsigned devIdx )
|
||
|
{
|
||
|
drv_t* d;
|
||
|
if((d = _indexToDriver(h,devIdx)) != nullptr )
|
||
|
return d->drv->deviceLabel( d->drv, devIdx - d->begIdx );
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
unsigned cw::audio::device::deviceChannelCount( handle_t h, unsigned devIdx, bool inputFl )
|
||
|
{
|
||
|
drv_t* d;
|
||
|
if((d = _indexToDriver(h,devIdx)) != nullptr )
|
||
|
return d->drv->deviceChannelCount( d->drv, devIdx - d->begIdx, inputFl );
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
double cw::audio::device::deviceSampleRate( handle_t h, unsigned devIdx )
|
||
|
{
|
||
|
drv_t* d;
|
||
|
if((d = _indexToDriver(h,devIdx)) != nullptr )
|
||
|
return d->drv->deviceSampleRate( d->drv, devIdx - d->begIdx );
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
unsigned cw::audio::device::deviceFramesPerCycle( handle_t h, unsigned devIdx, bool inputFl )
|
||
|
{
|
||
|
drv_t* d;
|
||
|
if((d = _indexToDriver(h,devIdx)) != nullptr )
|
||
|
return d->drv->deviceFramesPerCycle( d->drv, devIdx - d->begIdx, inputFl );
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
cw::rc_t cw::audio::device::deviceSetup( handle_t h, unsigned devIdx, double sr, unsigned frmPerCycle, cbFunc_t cb, void* cbData )
|
||
|
{
|
||
|
drv_t* d;
|
||
|
if((d = _indexToDriver(h,devIdx)) != nullptr )
|
||
|
return d->drv->deviceSetup( d->drv, devIdx - d->begIdx, sr, frmPerCycle, cb, cbData );
|
||
|
return kInvalidArgRC;
|
||
|
}
|
||
|
|
||
|
cw::rc_t cw::audio::device::deviceStart( handle_t h, unsigned devIdx )
|
||
|
{
|
||
|
drv_t* d;
|
||
|
if((d = _indexToDriver(h,devIdx)) != nullptr )
|
||
|
return d->drv->deviceStart( d->drv, devIdx - d->begIdx );
|
||
|
return kInvalidArgRC;
|
||
|
}
|
||
|
|
||
|
cw::rc_t cw::audio::device::deviceStop( handle_t h, unsigned devIdx )
|
||
|
{
|
||
|
drv_t* d;
|
||
|
if((d = _indexToDriver(h,devIdx)) != nullptr )
|
||
|
return d->drv->deviceStop( d->drv, devIdx - d->begIdx );
|
||
|
return kInvalidArgRC;
|
||
|
}
|
||
|
|
||
|
bool cw::audio::device::deviceIsStarted(handle_t h, unsigned devIdx )
|
||
|
{
|
||
|
drv_t* d;
|
||
|
if((d = _indexToDriver(h,devIdx)) != nullptr )
|
||
|
return d->drv->deviceIsStarted( d->drv, devIdx - d->begIdx );
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void cw::audio::device::deviceRealTimeReport( handle_t h, unsigned devIdx )
|
||
|
{
|
||
|
drv_t* d;
|
||
|
if((d = _indexToDriver(h,devIdx)) != nullptr )
|
||
|
d->drv->deviceRealTimeReport( d->drv, devIdx - d->begIdx );
|
||
|
}
|
||
|
|
||
|
void cw::audio::device::report( handle_t h )
|
||
|
{
|
||
|
for(unsigned i=0; i<deviceCount(h); ++i)
|
||
|
{
|
||
|
cwLogInfo( "%8.1f in:%i (%i) out:%i (%i) %s",
|
||
|
deviceSampleRate(h,i),
|
||
|
deviceChannelCount(h,i,true), deviceFramesPerCycle(h,i,true),
|
||
|
deviceChannelCount(h,i,false), deviceFramesPerCycle(h,i,false),
|
||
|
deviceLabel(h,i));
|
||
|
}
|
||
|
|
||
|
}
|