cwFlow.h/cpp,cwFlowTypes.h : Split create() into two functions create() and intitialize() to allow the

audio device to be reconfigured after the sample rate and dspFrameCnt are parsed
from the program cfg.
This commit is contained in:
kevin 2024-06-10 20:40:41 -04:00
parent c3e46696cf
commit 607447e84c
3 changed files with 69 additions and 36 deletions

View File

@ -666,15 +666,10 @@ cw::rc_t cw::flow::create( handle_t& hRef,
const object_t* classCfg, const object_t* classCfg,
const object_t* flowCfg, const object_t* flowCfg,
const object_t* subnetCfg, const object_t* subnetCfg,
const char* proj_dir, const char* proj_dir )
external_device_t* deviceA,
unsigned deviceN )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
const object_t* networkCfg = nullptr;
bool printClassDictFl = false; bool printClassDictFl = false;
bool printNetworkFl = false;
variable_t* proxyVarL = nullptr;
unsigned maxCycleCount = kInvalidCnt; unsigned maxCycleCount = kInvalidCnt;
double durLimitSecs = 0; double durLimitSecs = 0;
@ -682,9 +677,6 @@ cw::rc_t cw::flow::create( handle_t& hRef,
return rc; return rc;
flow_t* p = mem::allocZ<flow_t>(); flow_t* p = mem::allocZ<flow_t>();
p->flowCfg = flowCfg; // TODO: duplicate cfg?
p->deviceA = deviceA;
p->deviceN = deviceN;
// parse the class description array // parse the class description array
if((rc = _parse_class_cfg(p,classCfg)) != kOkRC ) if((rc = _parse_class_cfg(p,classCfg)) != kOkRC )
@ -702,13 +694,14 @@ cw::rc_t cw::flow::create( handle_t& hRef,
} }
p->flowCfg = flowCfg;
p->framesPerCycle = kDefaultFramesPerCycle; p->framesPerCycle = kDefaultFramesPerCycle;
p->sample_rate = kDefaultSampleRate; p->sample_rate = kDefaultSampleRate;
p->maxCycleCount = kInvalidCnt; p->maxCycleCount = kInvalidCnt;
p->proj_dir = proj_dir; p->proj_dir = proj_dir;
// parse the optional args // parse the optional args
if((rc = flowCfg->readv("network", 0, networkCfg, if((rc = flowCfg->readv("network", 0, p->networkCfg,
"non_real_time_fl", kOptFl, p->non_real_time_fl, "non_real_time_fl", kOptFl, p->non_real_time_fl,
"framesPerCycle", kOptFl, p->framesPerCycle, "framesPerCycle", kOptFl, p->framesPerCycle,
"sample_rate", kOptFl, p->sample_rate, "sample_rate", kOptFl, p->sample_rate,
@ -716,7 +709,7 @@ cw::rc_t cw::flow::create( handle_t& hRef,
"durLimitSecs", kOptFl, durLimitSecs, "durLimitSecs", kOptFl, durLimitSecs,
"preset", kOptFl, p->init_net_preset_label, "preset", kOptFl, p->init_net_preset_label,
"printClassDictFl", kOptFl, printClassDictFl, "printClassDictFl", kOptFl, printClassDictFl,
"printNetworkFl", kOptFl, printNetworkFl, "printNetworkFl", kOptFl, p->printNetworkFl,
"multiPriPresetProbFl", kOptFl, p->multiPriPresetProbFl, "multiPriPresetProbFl", kOptFl, p->multiPriPresetProbFl,
"multiSecPresetProbFl", kOptFl, p->multiSecPresetProbFl, "multiSecPresetProbFl", kOptFl, p->multiSecPresetProbFl,
"multiPresetInterpFl", kOptFl, p->multiPresetInterpFl)) != kOkRC ) "multiPresetInterpFl", kOptFl, p->multiPresetInterpFl)) != kOkRC )
@ -736,6 +729,31 @@ cw::rc_t cw::flow::create( handle_t& hRef,
p->maxCycleCount = (unsigned)((durLimitSecs * p->sample_rate) / p->framesPerCycle); p->maxCycleCount = (unsigned)((durLimitSecs * p->sample_rate) / p->framesPerCycle);
} }
// print the class dict
if( printClassDictFl )
class_dict_print( p );
hRef.set(p);
errLabel:
if( rc != kOkRC )
_destroy(p);
return rc;
}
cw::rc_t cw::flow::initialize( handle_t h,
external_device_t* deviceA,
unsigned deviceN )
{
rc_t rc = kOkRC;
variable_t* proxyVarL = nullptr;
flow_t* p = _handleToPtr(h);
p->deviceA = deviceA;
p->deviceN = deviceN;
for(unsigned i=0; i<deviceN; ++i) for(unsigned i=0; i<deviceN; ++i)
if( deviceA[i].typeId == kAudioDevTypeId ) if( deviceA[i].typeId == kAudioDevTypeId )
{ {
@ -749,18 +767,14 @@ cw::rc_t cw::flow::create( handle_t& hRef,
cwLogWarning("The audio frame count (%i) for audio device '%s' does not match the Flow framesPerCycle (%i).",deviceA[i].u.a.abuf->frameN,p->framesPerCycle); cwLogWarning("The audio frame count (%i) for audio device '%s' does not match the Flow framesPerCycle (%i).",deviceA[i].u.a.abuf->frameN,p->framesPerCycle);
} }
// print the class dict
if( printClassDictFl )
class_dict_print( p );
// instantiate the network // instantiate the network
if((rc = network_create(p,networkCfg,p->net,proxyVarL)) != kOkRC ) if((rc = network_create(p,p->networkCfg,p->net,proxyVarL)) != kOkRC )
{ {
rc = cwLogError(rc,"Network creation failed."); rc = cwLogError(rc,"Network creation failed.");
goto errLabel; goto errLabel;
} }
if( printNetworkFl ) if( p->printNetworkFl )
network_print(p->net); network_print(p->net);
if( p->init_net_preset_label != nullptr ) if( p->init_net_preset_label != nullptr )
@ -769,17 +783,15 @@ cw::rc_t cw::flow::create( handle_t& hRef,
p->isInRuntimeFl = true; p->isInRuntimeFl = true;
cwLogInfo("Entering runtime."); cwLogInfo("Entering runtime.");
hRef.set(p);
errLabel: errLabel:
if( rc != kOkRC ) if( rc != kOkRC )
_destroy(p); _destroy(p);
return rc; return rc;
} }
cw::rc_t cw::flow::destroy( handle_t& hRef ) cw::rc_t cw::flow::destroy( handle_t& hRef )
{ {
rc_t rc = kOkRC; rc_t rc = kOkRC;
@ -803,6 +815,19 @@ bool cw::flow::is_non_real_time( handle_t h )
return p->non_real_time_fl; return p->non_real_time_fl;
} }
double cw::flow::sample_rate( handle_t h )
{
flow_t* p = _handleToPtr(h);
return p->sample_rate;
}
unsigned cw::flow::frames_per_cycle( handle_t h )
{
flow_t* p = _handleToPtr(h);
return p->framesPerCycle;
}
unsigned cw::flow::preset_cfg_flags( handle_t h ) unsigned cw::flow::preset_cfg_flags( handle_t h )
{ {
flow_t* p = _handleToPtr(h); flow_t* p = _handleToPtr(h);

View File

@ -8,23 +8,30 @@ namespace cw
typedef handle<struct flow_str> handle_t; typedef handle<struct flow_str> handle_t;
void print_abuf( const struct abuf_str* abuf ); void print_abuf( const struct abuf_str* abuf );
void print_external_device( const external_device_t* dev ); void print_external_device( const external_device_t* dev );
// Parse the cfg's but don't yet instantiate the network.
// Upon completion of this function the caller can
// query the network for configuration information which can
// be used to setup the extern_device_t array.
rc_t create(handle_t& hRef,
const object_t* classCfg,
const object_t* networkCfg,
const object_t* subnetCfg = nullptr,
const char* projDir = nullptr);
rc_t create( handle_t& hRef, // Instantiate the network and prepare for runtime.
const object_t* classCfg, rc_t initialize( handle_t handle,
const object_t* networkCfg, external_device_t* deviceA = nullptr,
const object_t* subnetCfg = nullptr, unsigned deviceN = 0);
const char* projDir = nullptr,
external_device_t* deviceA = nullptr,
unsigned deviceN = 0);
rc_t destroy( handle_t& hRef ); rc_t destroy( handle_t& hRef );
bool is_non_real_time( handle_t h ); // Network cfg. information which is available following configure().
bool is_non_real_time( handle_t h );
double sample_rate( handle_t h );
unsigned frames_per_cycle( handle_t h );
unsigned preset_cfg_flags( handle_t h ); unsigned preset_cfg_flags( handle_t h );

View File

@ -323,14 +323,17 @@ namespace cw
// Preset pair table used by network_apply_dual_preset() // Preset pair table used by network_apply_dual_preset()
network_preset_pair_t* preset_pairA; network_preset_pair_t* preset_pairA;
unsigned preset_pairN; unsigned preset_pairN;
} network_t; } network_t;
typedef struct flow_str typedef struct flow_str
{ {
const object_t* flowCfg; // complete cfg used to create this flow const object_t* flowCfg; // complete cfg used to create this flow
const object_t* networkCfg; // 'network' cfg from flowCfg
bool printNetworkFl;
bool non_real_time_fl; // set if this is a non-real-time program bool non_real_time_fl; // set if this is a non-real-time program
unsigned framesPerCycle; // sample frames per cycle (64) unsigned framesPerCycle; // sample frames per cycle (64)
srate_t sample_rate; // default sample rate (48000.0) srate_t sample_rate; // default sample rate (48000.0)
@ -339,9 +342,7 @@ namespace cw
bool isInRuntimeFl; // Set when compile-time is complete bool isInRuntimeFl; // Set when compile-time is complete
unsigned cycleIndex; // Incremented with each processing cycle unsigned cycleIndex; // Incremented with each processing cycle
bool multiPriPresetProbFl; // If set then probability is used to choose presets on multi-preset application bool multiPriPresetProbFl; // If set then probability is used to choose presets on multi-preset application
bool multiSecPresetProbFl; // bool multiSecPresetProbFl; //