cwIo.h/cpp,cwIoTest.cpp : Audio interface updates.

This commit is contained in:
kpl 2020-02-29 00:12:57 -05:00
parent 77c5026f14
commit 9f2ccef9aa
4 changed files with 155 additions and 14 deletions

View File

@ -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
View File

@ -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
View File

@ -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 );

View File

@ -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
}
]
} }
})"; })";