cwIo.h/cpp,cwIoTest.cpp : Audio interface updates.
This commit is contained in:
parent
77c5026f14
commit
9f2ccef9aa
@ -58,7 +58,7 @@ namespace cw
|
|||||||
handle_t h,
|
handle_t h,
|
||||||
unsigned devIdx, //< device to setup
|
unsigned devIdx, //< device to setup
|
||||||
double srate, //< device sample rate (only required for synthesizing the correct test-tone frequency)
|
double srate, //< device sample rate (only required for synthesizing the correct test-tone frequency)
|
||||||
unsigned dspFrameCnt, // dspFrameCnt - count of samples in channel buffers returned via get()
|
unsigned dspFrameCnt, //< dspFrameCnt - count of samples in channel buffers returned via get()
|
||||||
unsigned cycleCnt, //< number of audio port cycles to store
|
unsigned cycleCnt, //< number of audio port cycles to store
|
||||||
unsigned inChCnt, //< input channel count on this device
|
unsigned inChCnt, //< input channel count on this device
|
||||||
unsigned inFramesPerCycle, //< maximum number of incoming sample frames on an audio port cycle
|
unsigned inFramesPerCycle, //< maximum number of incoming sample frames on an audio port cycle
|
||||||
|
133
cwIo.cpp
133
cwIo.cpp
@ -34,6 +34,17 @@ namespace cw
|
|||||||
unsigned pollPeriodMs;
|
unsigned pollPeriodMs;
|
||||||
serialPortSrv::handle_t serialH;
|
serialPortSrv::handle_t serialH;
|
||||||
} serialPort_t;
|
} serialPort_t;
|
||||||
|
|
||||||
|
typedef struct audioCfg_str
|
||||||
|
{
|
||||||
|
unsigned enableFl;
|
||||||
|
char* name;
|
||||||
|
char* device;
|
||||||
|
double srate;
|
||||||
|
unsigned dspFrameCnt;
|
||||||
|
unsigned cycleCnt;
|
||||||
|
unsigned devIdx;
|
||||||
|
} audioCfg_t;
|
||||||
|
|
||||||
typedef struct io_str
|
typedef struct io_str
|
||||||
{
|
{
|
||||||
@ -50,6 +61,9 @@ namespace cw
|
|||||||
audio::device::handle_t audioH;
|
audio::device::handle_t audioH;
|
||||||
audio::device::alsa::handle_t alsaH;
|
audio::device::alsa::handle_t alsaH;
|
||||||
|
|
||||||
|
unsigned audioCfgN;
|
||||||
|
audioCfg_t* audioCfgA;
|
||||||
|
|
||||||
} io_t;
|
} io_t;
|
||||||
|
|
||||||
|
|
||||||
@ -226,14 +240,78 @@ namespace cw
|
|||||||
|
|
||||||
void _audioDeviceCallback( void* cbArg, audio::device::audioPacket_t* inPktArray, unsigned inPktCnt, audio::device::audioPacket_t* outPktArray, unsigned outPktCnt )
|
void _audioDeviceCallback( void* cbArg, audio::device::audioPacket_t* inPktArray, unsigned inPktCnt, audio::device::audioPacket_t* outPktArray, unsigned outPktCnt )
|
||||||
{
|
{
|
||||||
|
//io_t* p = (io_t*)cbArg;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_t _audioDeviceConfig( io_t* p, const object_t* c )
|
rc_t _audioDeviceConfig( io_t* p, const object_t* c )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
|
unsigned meterMs = 50;
|
||||||
|
const object_t* node = nullptr;
|
||||||
|
const object_t* deviceL = nullptr;
|
||||||
|
|
||||||
|
// get the audio port node
|
||||||
|
if((node = c->find("audio")) == nullptr )
|
||||||
|
return cwLogError(kSyntaxErrorRC,"Unable to locate the 'audio' configuration node.");
|
||||||
|
|
||||||
|
// get the meterMs value
|
||||||
|
if((rc = node->get("meterMs", meterMs )) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = cwLogError(kSyntaxErrorRC,"Audio 'meterMs' parse failed.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the audio device list
|
||||||
|
if((deviceL = node->find("deviceL")) == nullptr )
|
||||||
|
{
|
||||||
|
rc = cwLogError(kSyntaxErrorRC,"Audio 'deviceL' failed.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create an audio device cfg list
|
||||||
|
p->audioCfgN = deviceL->child_count();
|
||||||
|
p->audioCfgA = mem::allocZ<audioCfg_t>(p->audioCfgN);
|
||||||
|
|
||||||
|
// fill in the audio device cfg list
|
||||||
|
for(unsigned i=0; i<p->audioCfgN; ++i)
|
||||||
|
{
|
||||||
|
audioCfg_t* r = p->audioCfgA + i;
|
||||||
|
if((node = deviceL->list_ele(i)) == nullptr )
|
||||||
|
{
|
||||||
|
if(( rc = node->getv(
|
||||||
|
"enableFl", r->enableFl,
|
||||||
|
"name", r->name,
|
||||||
|
"device", r->device,
|
||||||
|
"srate", r->srate,
|
||||||
|
"dspFrameCnt", r->dspFrameCnt,
|
||||||
|
"cycleCnt", r->cycleCnt )) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = cwLogError(rc,"Error parsing audio cfg record at index:%i",i);
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the configuration is enabled
|
||||||
|
if( r->enableFl )
|
||||||
|
{
|
||||||
|
// get the hardware device index
|
||||||
|
if((r->devIdx = audio::device::deviceLabelToIndex( p->audioH, r->device)) == kInvalidIdx )
|
||||||
|
{
|
||||||
|
rc = cwLogError(rc,"Unable to locate the audio hardware device:'%s'.", r->device);
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup the device based on the configuration
|
||||||
|
if((rc = audio::device::deviceSetup(p->audioH,r->devIdx,r->srate,r->dspFrameCnt,_audioDeviceCallback,p)) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = cwLogError(rc,"Unable to setup the audio hardware device:'%s'.", r->device);
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errLabel:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +342,7 @@ namespace cw
|
|||||||
goto errLabel;
|
goto errLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// read the configuration information and setup the audio hardware
|
||||||
if((rc = _audioDeviceConfig( p, c )) != kOkRC )
|
if((rc = _audioDeviceConfig( p, c )) != kOkRC )
|
||||||
{
|
{
|
||||||
cwLogInfo("Audio device configuration failed.");
|
cwLogInfo("Audio device configuration failed.");
|
||||||
@ -301,7 +379,7 @@ cw::rc_t cw::io::create( handle_t& h, const char* cfgStr, cbFunc_t cbFunc, void*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the main io cfg object.
|
// get the main io cfg object.
|
||||||
if((o = obj_base->find(cfgLabel)) != nullptr )
|
if((o = obj_base->find(cfgLabel)) == nullptr )
|
||||||
{
|
{
|
||||||
rc = cwLogError(kSyntaxErrorRC,"Unable to locate the I/O cfg. label:%s.",cfgLabel);
|
rc = cwLogError(kSyntaxErrorRC,"Unable to locate the I/O cfg. label:%s.",cfgLabel);
|
||||||
goto errLabel;
|
goto errLabel;
|
||||||
@ -440,3 +518,48 @@ cw::rc_t cw::io::midiDeviceSend( handle_t h, unsigned devIdx, unsigned portIdx,
|
|||||||
//return midi::device::send( p->midiH, devIdx, portIdx, status, d0, d1 );
|
//return midi::device::send( p->midiH, devIdx, portIdx, status, d0, d1 );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned cw::io::audioDeviceCount( handle_t h )
|
||||||
|
{
|
||||||
|
io_t* p = _handleToPtr(h);
|
||||||
|
return p->audioCfgN;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned cw::io::audioDeviceLabelToIndex( handle_t h, const char* label )
|
||||||
|
{
|
||||||
|
io_t* p = _handleToPtr(h);
|
||||||
|
for(unsigned i=0; i<p->audioCfgN; ++i)
|
||||||
|
if( strcmp(p->audioCfgA[i].name,label) == 0 )
|
||||||
|
return i;
|
||||||
|
|
||||||
|
return kInvalidIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* cw::io::audioDeviceLabel( handle_t h, unsigned devIdx )
|
||||||
|
{
|
||||||
|
io_t* p = _handleToPtr(h);
|
||||||
|
assert( devIdx < p->audioCfgN );
|
||||||
|
return p->audioCfgA[ devIdx ].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::io::audioDeviceStart( handle_t h, unsigned devIdx )
|
||||||
|
{
|
||||||
|
io_t* p = _handleToPtr(h);
|
||||||
|
assert( devIdx < p->audioCfgN );
|
||||||
|
return audio::device::deviceStart( p->audioH, p->audioCfgA[ devIdx ].devIdx );
|
||||||
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::io::audioDeviceStop( handle_t h, unsigned devIdx )
|
||||||
|
{
|
||||||
|
io_t* p = _handleToPtr(h);
|
||||||
|
assert( devIdx < p->audioCfgN );
|
||||||
|
return audio::device::deviceStop( p->audioH, p->audioCfgA[ devIdx ].devIdx );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cw::io::audioDeviceIsStarted( handle_t h, unsigned devIdx )
|
||||||
|
{
|
||||||
|
io_t* p = _handleToPtr(h);
|
||||||
|
assert( devIdx < p->audioCfgN );
|
||||||
|
return audio::device::deviceIsStarted( p->audioH, p->audioCfgA[ devIdx ].devIdx );
|
||||||
|
}
|
||||||
|
13
cwIo.h
13
cwIo.h
@ -29,6 +29,10 @@ namespace cw
|
|||||||
midi::packet_t* pkt;
|
midi::packet_t* pkt;
|
||||||
} midi_msg_t;
|
} midi_msg_t;
|
||||||
|
|
||||||
|
typedef struct audio_msg_str
|
||||||
|
{
|
||||||
|
} audio_msg_t;
|
||||||
|
|
||||||
typedef struct msg_str
|
typedef struct msg_str
|
||||||
{
|
{
|
||||||
unsigned tid;
|
unsigned tid;
|
||||||
@ -67,6 +71,15 @@ namespace cw
|
|||||||
rc_t midiDeviceSend( handle_t h, unsigned devIdx, unsigned portIdx, midi::byte_t status, midi::byte_t d0, midi::byte_t d1 );
|
rc_t midiDeviceSend( handle_t h, unsigned devIdx, unsigned portIdx, midi::byte_t status, midi::byte_t d0, midi::byte_t d1 );
|
||||||
|
|
||||||
|
|
||||||
|
unsigned audioDeviceCount( handle_t h );
|
||||||
|
unsigned audioDeviceLabelToIndex( handle_t h, const char* label );
|
||||||
|
const char* audioDeviceLabel( handle_t h, unsigned devIdx );
|
||||||
|
unsigned audioDeviceChannelCount( handle_t h, unsigned devIdx, bool inputFl );
|
||||||
|
double audioDeviceSampleRate( handle_t h, unsigned devIdx );
|
||||||
|
unsigned audioDeviceFramesPerCycle( handle_t h, unsigned devIdx, bool inputFl );
|
||||||
|
rc_t audioDeviceStart( handle_t h, unsigned devIdx );
|
||||||
|
rc_t audioDeviceStop( handle_t h, unsigned devIdx );
|
||||||
|
bool audioDeviceIsStarted( handle_t h, unsigned devIdx );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
21
cwIoTest.cpp
21
cwIoTest.cpp
@ -39,14 +39,19 @@ cw::rc_t cw::io::test()
|
|||||||
parserBufByteN: 1024,
|
parserBufByteN: 1024,
|
||||||
}
|
}
|
||||||
|
|
||||||
audio: [
|
audio: {
|
||||||
{
|
meterMs: 50,
|
||||||
name: "default",
|
|
||||||
device: "HDA Intel PCH CS4208 Analog",
|
deviceL: [
|
||||||
srate: 48000,
|
{
|
||||||
framesPerCycle: 64
|
enableFl: true,
|
||||||
}
|
name: "Default",
|
||||||
]
|
device: "HDA Intel PCH CS4208 Analog",
|
||||||
|
srate: 48000,
|
||||||
|
dspFrameCnt: 64,
|
||||||
|
cycleCnt: 3
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
})";
|
})";
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user