Added audio_meter and cwIo and flow support for metering.
Also updated spec_dist,pv_anl, pv_syn to use fd_real_t.
This commit is contained in:
parent
9782c1b3c9
commit
11636a3f43
@ -289,11 +289,8 @@ cw::rc_t cw::dsp::recorder::destroy( obj_t*& pRef)
|
||||
{
|
||||
obj_t* p = pRef;
|
||||
|
||||
if( p != nullptr )
|
||||
{
|
||||
mem::release(p->buf);
|
||||
mem::release(p);
|
||||
}
|
||||
mem::release(p->buf);
|
||||
mem::release(p);
|
||||
|
||||
pRef = nullptr;
|
||||
return kOkRC;
|
||||
@ -363,3 +360,132 @@ cw::rc_t cw::dsp::recorder::write( obj_t* p, const char* fname )
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
// Audio Meter
|
||||
//
|
||||
namespace cw {
|
||||
namespace dsp {
|
||||
namespace audio_meter {
|
||||
sample_t _sum_square( const sample_t* v, unsigned vn, bool& clipFlRef )
|
||||
{
|
||||
sample_t sum = 0;
|
||||
for(unsigned i=0; i<vn; ++i)
|
||||
{
|
||||
sample_t x = v[i]*v[i];
|
||||
sum += x;
|
||||
clipFlRef = x > 1.0;
|
||||
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cw::rc_t cw::dsp::audio_meter::create( obj_t*& p, real_t srate, real_t maxWndMs, real_t wndMs, real_t peakThreshDb )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
if( maxWndMs < wndMs )
|
||||
{
|
||||
cwLogWarning("Audio meter Max. window length (%f ms) is less than requested window length (%f ms). Setting max window length to %f ms.",maxWndMs,wndMs,wndMs);
|
||||
maxWndMs = wndMs;
|
||||
}
|
||||
|
||||
p = mem::allocZ<obj_t>();
|
||||
p->maxWndMs = maxWndMs;
|
||||
p->maxWndSmpN = (unsigned)((maxWndMs * srate)/1000.0);
|
||||
p->wndV = mem::allocZ<sample_t>(p->maxWndSmpN);
|
||||
p->srate = srate;
|
||||
p->peakThreshDb = peakThreshDb;
|
||||
p->wi = 0;
|
||||
|
||||
set_window_ms( p, wndMs );
|
||||
reset(p);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
cw::rc_t cw::dsp::audio_meter::destroy( obj_t*& pp )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
mem::release(pp->wndV);
|
||||
mem::release(pp);
|
||||
return rc;
|
||||
}
|
||||
|
||||
cw::rc_t cw::dsp::audio_meter::exec( obj_t* p, const sample_t* xV, unsigned xN )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
unsigned n = 0;
|
||||
|
||||
// copy the incoming audio samples to the buffer
|
||||
while( xN )
|
||||
{
|
||||
unsigned n0 = std::min( p->maxWndSmpN - p->wi, xN );
|
||||
|
||||
vop::copy(p->wndV + p->wi, xV + n, n0 );
|
||||
|
||||
n += n0;
|
||||
xN -= n0;
|
||||
|
||||
p->wi = (p->wi + n0) % p->maxWndSmpN;
|
||||
}
|
||||
|
||||
// get the starting and ending locations of the RMS sub-buffers
|
||||
|
||||
unsigned i0 = 0, i1 = 0;
|
||||
unsigned n0 = 0, n1 = 0;
|
||||
|
||||
if( p->wi >= p->wndSmpN )
|
||||
{
|
||||
i0 = p->wi - p->wndSmpN;
|
||||
n0 = p->wndSmpN;
|
||||
}
|
||||
else
|
||||
{
|
||||
i1 = 0;
|
||||
n1 = p->wi;
|
||||
n0 = p->wndSmpN - n1;
|
||||
i0 = p->maxWndSmpN - n0;
|
||||
}
|
||||
|
||||
// calc the squared-sum of the RMS buffers
|
||||
sample_t sum = _sum_square(p->wndV + i0, n0, p->clipFl);
|
||||
if( n1 )
|
||||
sum += _sum_square(p->wndV + i1, n1, p->clipFl );
|
||||
|
||||
p->outLin = std::sqrt( sum / (n0+n1) ); // linear RMS
|
||||
p->outDb = ampl_to_db(p->outLin); // RMS dB
|
||||
|
||||
p->peakFl = p->outDb > p->peakThreshDb; // set peak flag
|
||||
p->clipFl = vop::max(xV,xN) >= 1.0; // set clip flag
|
||||
|
||||
p->peakCnt += p->peakFl ? 1 : 0; // count peak violations
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void cw::dsp::audio_meter::reset( obj_t* p )
|
||||
{
|
||||
p->peakFl = false;
|
||||
p->clipFl = false;
|
||||
p->peakCnt = 0;
|
||||
p->clipCnt = 0;
|
||||
}
|
||||
|
||||
void cw::dsp::audio_meter::set_window_ms( obj_t* p, real_t wndMs )
|
||||
{
|
||||
unsigned wndSmpN = (unsigned)((wndMs * p->srate)/1000.0);
|
||||
|
||||
if( wndSmpN <= p->maxWndSmpN )
|
||||
p->wndSmpN = wndSmpN;
|
||||
else
|
||||
{
|
||||
cwLogWarning("The audio meter window length (%f ms) exceeds the max. window length (%f ms). The window length was reduced to (%f ms).",wndMs,p->maxWndMs,p->maxWndMs);
|
||||
p->wndSmpN = p->maxWndSmpN;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -96,9 +96,35 @@ namespace cw
|
||||
|
||||
rc_t exec( obj_t* p, const sample_t* buf, unsigned chN, unsigned frameN );
|
||||
rc_t exec( obj_t* p, const sample_t* chA[], unsigned chN, unsigned frameN );
|
||||
rc_t write( obj_t* p, const char* fname );
|
||||
rc_t write( obj_t* p, const char* fname );
|
||||
}
|
||||
|
||||
namespace audio_meter
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
unsigned maxWndMs;
|
||||
unsigned maxWndSmpN;
|
||||
unsigned wndSmpN;
|
||||
sample_t* wndV;
|
||||
real_t srate;
|
||||
real_t peakThreshDb;
|
||||
real_t outLin;
|
||||
real_t outDb;
|
||||
bool peakFl;
|
||||
bool clipFl;
|
||||
unsigned peakCnt;
|
||||
unsigned clipCnt;
|
||||
unsigned wi;
|
||||
} obj_t;
|
||||
|
||||
}
|
||||
rc_t create( obj_t*& p, real_t srate, real_t maxWndMs, real_t wndMs, real_t peakThreshDb );
|
||||
rc_t destroy( obj_t*& pp );
|
||||
rc_t exec( obj_t* p, const sample_t* x, unsigned n );
|
||||
void reset( obj_t* p );
|
||||
void set_window_ms( obj_t* p, real_t wndMs );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
183
cwFlowProc.cpp
183
cwFlowProc.cpp
@ -1437,7 +1437,7 @@ namespace cw
|
||||
//
|
||||
namespace pv_analysis
|
||||
{
|
||||
typedef struct dsp::pv_anl::obj_str<sample_t> pv_t;
|
||||
typedef struct dsp::pv_anl::obj_str<sample_t,fd_real_t> pv_t;
|
||||
|
||||
enum {
|
||||
kInPId,
|
||||
@ -1477,9 +1477,9 @@ namespace cw
|
||||
inst->pvN = srcBuf->chN;
|
||||
inst->pvA = mem::allocZ<pv_t*>( inst->pvN ); // allocate pv channel array
|
||||
|
||||
const sample_t* magV[ srcBuf->chN ];
|
||||
const sample_t* phsV[ srcBuf->chN ];
|
||||
const sample_t* hzV[ srcBuf->chN ];
|
||||
const fd_real_t* magV[ srcBuf->chN ];
|
||||
const fd_real_t* phsV[ srcBuf->chN ];
|
||||
const fd_real_t* hzV[ srcBuf->chN ];
|
||||
unsigned maxBinNV[ srcBuf->chN ];
|
||||
unsigned binNV[ srcBuf->chN ];
|
||||
unsigned hopNV[ srcBuf->chN ];
|
||||
@ -1625,7 +1625,7 @@ namespace cw
|
||||
//
|
||||
namespace pv_synthesis
|
||||
{
|
||||
typedef struct dsp::pv_syn::obj_str<sample_t> pv_t;
|
||||
typedef struct dsp::pv_syn::obj_str<sample_t,fd_real_t> pv_t;
|
||||
|
||||
enum {
|
||||
kInPId,
|
||||
@ -1751,7 +1751,7 @@ namespace cw
|
||||
//
|
||||
namespace spec_dist
|
||||
{
|
||||
typedef struct dsp::spec_dist::obj_str<sample_t,sample_t> spec_dist_t;
|
||||
typedef struct dsp::spec_dist::obj_str<fd_real_t,fd_real_t> spec_dist_t;
|
||||
|
||||
enum
|
||||
{
|
||||
@ -1794,9 +1794,9 @@ namespace cw
|
||||
inst->sdN = srcBuf->chN;
|
||||
inst->sdA = mem::allocZ<spec_dist_t*>( inst->sdN );
|
||||
|
||||
const sample_t* magV[ srcBuf->chN ];
|
||||
const sample_t* phsV[ srcBuf->chN ];
|
||||
const sample_t* hzV[ srcBuf->chN ];
|
||||
const fd_real_t* magV[ srcBuf->chN ];
|
||||
const fd_real_t* phsV[ srcBuf->chN ];
|
||||
const fd_real_t* hzV[ srcBuf->chN ];
|
||||
|
||||
//if((rc = var_register(ctx, kAnyChIdx, kInPId, "in")) != kOkRC )
|
||||
// goto errLabel;
|
||||
@ -1864,6 +1864,7 @@ namespace cw
|
||||
double val = 0;
|
||||
spec_dist_t* sd = inst->sdA[ var->chIdx ];
|
||||
|
||||
|
||||
switch( var->vid )
|
||||
{
|
||||
case kBypassPId: rc = var_get( var, val ); sd->bypassFl = val; break;
|
||||
@ -1877,8 +1878,8 @@ namespace cw
|
||||
cwLogWarning("Unhandled variable id '%i' on instance: %s.", var->vid, ctx->label );
|
||||
}
|
||||
|
||||
//printf("%i sd: ceil:%f expo:%f thresh:%f upr:%f lwr:%f mix:%f : rc:%i val:%f\n",
|
||||
// var->chIdx,sd->ceiling, sd->expo, sd->thresh, sd->uprSlope, sd->lwrSlope, sd->mix, rc, val );
|
||||
//printf("%i sd: ceil:%f expo:%f thresh:%f upr:%f lwr:%f mix:%f : rc:%i val:%f var:%s \n",
|
||||
// var->chIdx,sd->ceiling, sd->expo, sd->thresh, sd->uprSlope, sd->lwrSlope, sd->mix, rc, val, var->label );
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -2596,8 +2597,164 @@ namespace cw
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// audio_meter
|
||||
//
|
||||
namespace audio_meter
|
||||
{
|
||||
|
||||
enum
|
||||
{
|
||||
kInPId,
|
||||
kDbFlPId,
|
||||
kWndMsPId,
|
||||
kPeakDbPId,
|
||||
kOutPId,
|
||||
kPeakFlPId,
|
||||
kClipFlPId
|
||||
};
|
||||
|
||||
|
||||
typedef dsp::audio_meter::obj_t audio_meter_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
audio_meter_t** mtrA;
|
||||
unsigned mtrN;
|
||||
} inst_t;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
rc_t create( instance_t* ctx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
const abuf_t* srcBuf = nullptr; //
|
||||
inst_t* inst = mem::allocZ<inst_t>();
|
||||
|
||||
ctx->userPtr = inst;
|
||||
|
||||
// verify that a source buffer exists
|
||||
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",srcBuf )) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"The instance '%s' does not have a valid input connection.",ctx->label);
|
||||
goto errLabel;
|
||||
}
|
||||
else
|
||||
{
|
||||
// allocate channel array
|
||||
inst->mtrN = srcBuf->chN;
|
||||
inst->mtrA = mem::allocZ<audio_meter_t*>( inst->mtrN );
|
||||
|
||||
// create a audio_meter object for each input channel
|
||||
for(unsigned i=0; i<srcBuf->chN; ++i)
|
||||
{
|
||||
real_t wndMs, peakThreshDb;
|
||||
bool dbFl;
|
||||
|
||||
// get the audio_meter variable values
|
||||
if((rc = var_register_and_get( ctx, i,
|
||||
kDbFlPId, "dbFl", dbFl,
|
||||
kWndMsPId, "wndMs", wndMs,
|
||||
kPeakDbPId, "peakDb", peakThreshDb )) != kOkRC )
|
||||
{
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// get the audio_meter variable values
|
||||
if((rc = var_register( ctx, i,
|
||||
kOutPId, "out",
|
||||
kPeakFlPId, "peakFl",
|
||||
kClipFlPId, "clipFl" )) != kOkRC )
|
||||
{
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
unsigned maxWndMs = std::max(wndMs,1000.0f);
|
||||
|
||||
// create the audio_meter instance
|
||||
if((rc = dsp::audio_meter::create( inst->mtrA[i], srcBuf->srate, maxWndMs, wndMs, peakThreshDb)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(kOpFailRC,"The 'audio_meter' object create failed on the instance '%s'.",ctx->label);
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t destroy( instance_t* ctx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
inst_t* inst = (inst_t*)ctx->userPtr;
|
||||
for(unsigned i=0; i<inst->mtrN; ++i)
|
||||
destroy(inst->mtrA[i]);
|
||||
|
||||
mem::release(inst->mtrA);
|
||||
mem::release(inst);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t value( instance_t* ctx, variable_t* var )
|
||||
{
|
||||
return kOkRC;
|
||||
}
|
||||
|
||||
rc_t exec( instance_t* ctx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
inst_t* inst = (inst_t*)ctx->userPtr;
|
||||
const abuf_t* srcBuf = nullptr;
|
||||
unsigned chN = 0;
|
||||
|
||||
// get the src buffer
|
||||
if((rc = var_get(ctx,kInPId, kAnyChIdx, srcBuf )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
chN = std::min(srcBuf->chN,inst->mtrN);
|
||||
|
||||
for(unsigned i=0; i<chN; ++i)
|
||||
{
|
||||
dsp::audio_meter::exec( inst->mtrA[i], srcBuf->buf + i*srcBuf->frameN, srcBuf->frameN );
|
||||
var_set(ctx, kOutPId, i, inst->mtrA[i]->outDb );
|
||||
var_set(ctx, kPeakFlPId, i, inst->mtrA[i]->peakFl );
|
||||
var_set(ctx, kClipFlPId, i, inst->mtrA[i]->clipFl );
|
||||
}
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t report( instance_t* ctx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
inst_t* inst = (inst_t*)ctx->userPtr;
|
||||
for(unsigned i=0; i<inst->mtrN; ++i)
|
||||
{
|
||||
audio_meter_t* c = inst->mtrA[i];
|
||||
cwLogInfo("%s ch:%i : %f %f db : pk:%i %i clip:%i %i ",
|
||||
ctx->label,i,c->outLin,c->outDb,c->peakFl,c->peakCnt,c->clipFl,c->clipCnt );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
class_members_t members = {
|
||||
.create = create,
|
||||
.destroy = destroy,
|
||||
.value = value,
|
||||
.exec = exec,
|
||||
.report = report
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
} // flow
|
||||
} // cw
|
||||
|
||||
|
||||
|
@ -20,5 +20,6 @@ namespace cw
|
||||
namespace audio_delay { extern class_members_t members; }
|
||||
namespace dc_filter { extern class_members_t members; }
|
||||
namespace balance { extern class_members_t members; }
|
||||
namespace audio_meter { extern class_members_t members; }
|
||||
}
|
||||
}
|
||||
|
183
cwIo.cpp
183
cwIo.cpp
@ -82,6 +82,7 @@ namespace cw
|
||||
typedef struct audioDev_str
|
||||
{
|
||||
bool enableFl; // True if this device was enabled by the user
|
||||
bool meterFl; // True if meters are enabled on this device
|
||||
const char* label; // User label
|
||||
unsigned userId; // User id
|
||||
char* devName; // System device name
|
||||
@ -827,6 +828,8 @@ namespace cw
|
||||
// Audio
|
||||
//
|
||||
|
||||
|
||||
|
||||
// Start or stop all the audio devices in p->audioDevA[]
|
||||
rc_t _audioDeviceStartStop( io_t* p, bool startFl )
|
||||
{
|
||||
@ -1123,6 +1126,68 @@ namespace cw
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rc_t _audioDeviceParams( io_t* p, unsigned devIdx, unsigned flags, audioDev_t*& adRef, unsigned& audioBufFlagsRef )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
if((adRef = _audioDeviceIndexToRecd(p,devIdx)) == nullptr )
|
||||
rc = kInvalidArgRC;
|
||||
else
|
||||
{
|
||||
audioBufFlagsRef = 0;
|
||||
if( cwIsFlag(flags,kInFl) )
|
||||
audioBufFlagsRef += audio::buf::kInFl;
|
||||
|
||||
if( cwIsFlag(flags,kOutFl) )
|
||||
audioBufFlagsRef += audio::buf::kOutFl;
|
||||
|
||||
if( cwIsFlag(flags,kEnableFl) )
|
||||
audioBufFlagsRef += audio::buf::kEnableFl;
|
||||
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _audioDeviceEnableMeter( io_t* p, unsigned devIdx, unsigned inOutEnaFlags )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
audioDev_t* ad = nullptr;
|
||||
unsigned audioBufFlags = 0;
|
||||
|
||||
if((rc = _audioDeviceParams( p, devIdx, inOutEnaFlags, ad, audioBufFlags )) != kOkRC )
|
||||
rc = cwLogError(rc,"Enable tone failed.");
|
||||
else
|
||||
{
|
||||
bool enaFl = inOutEnaFlags & kEnableFl;
|
||||
bool enaState0Fl = _audioDeviceIsMeterEnabled(ad, kInFl | kOutFl);
|
||||
|
||||
audioBufFlags += audio::buf::kMeterFl;
|
||||
|
||||
if( inOutEnaFlags & kInFl )
|
||||
ad->iagd->flags = cwEnaFlag(ad->iagd->flags,kMeterFl,enaFl);
|
||||
|
||||
if( inOutEnaFlags & kOutFl )
|
||||
ad->oagd->flags = cwEnaFlag(ad->oagd->flags,kMeterFl,enaFl);
|
||||
|
||||
audio::buf::setFlag( p->audioBufH, devIdx, kInvalidIdx, audioBufFlags );
|
||||
|
||||
bool enaState1Fl= _audioDeviceIsMeterEnabled(ad, kInFl | kOutFl);
|
||||
|
||||
if( enaState1Fl and !enaState0Fl )
|
||||
p->audioMeterDevEnabledN += 1;
|
||||
else
|
||||
if( p->audioMeterDevEnabledN > 0 && !enaState1Fl && enaState0Fl )
|
||||
p->audioMeterDevEnabledN -= 1;
|
||||
|
||||
}
|
||||
|
||||
if( rc != kOkRC )
|
||||
rc = cwLogError(rc,"Enable meters failed.");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Add an audioGroup pointer to groupA[] and return the new count of elements in the array.
|
||||
unsigned _audioDeviceUpdateGroupArray( audioGroup_t** groupA, unsigned groupN, unsigned curGroupN, audioGroup_t* ag )
|
||||
@ -1438,6 +1503,7 @@ namespace cw
|
||||
{
|
||||
audioDev_t* ad = nullptr; //p->audioDevA + i;
|
||||
bool enableFl = false;
|
||||
bool meterFl = false;
|
||||
char* userLabel = nullptr;
|
||||
unsigned userId = kInvalidId;
|
||||
char* devName = nullptr;
|
||||
@ -1477,6 +1543,7 @@ namespace cw
|
||||
|
||||
if((rc = node->getv_opt(
|
||||
"userId", userId,
|
||||
"meterFl", meterFl,
|
||||
"inGroup", inGroupLabel,
|
||||
"outGroup", outGroupLabel )) != kOkRC )
|
||||
{
|
||||
@ -1575,14 +1642,15 @@ namespace cw
|
||||
if((rc = _audioGroupAddDevice( oag, false, ad, oChCnt )) != kOkRC )
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
|
||||
// set the device group pointers
|
||||
ad->enableFl = enableFl;
|
||||
ad->meterFl = meterFl;
|
||||
ad->label = userLabel;
|
||||
ad->userId = userId;
|
||||
ad->iGroup = iag;
|
||||
ad->oGroup = oag;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1590,6 +1658,23 @@ namespace cw
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _audioDeviceEnableMeters( io_t* p )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
for(unsigned i=0; i<p->audioDevN; ++i)
|
||||
if( p->audioDevA[i].enableFl && p->audioDevA[i].meterFl )
|
||||
if((rc = _audioDeviceEnableMeter(p, p->audioDevA[i].devIdx, kEnableFl | kInFl | kOutFl )) != kOkRC )
|
||||
{
|
||||
cwLogError(rc,"Audio enable on device '%s' failed.",p->audioDevA[i].label);
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
// Allocate the sample ptr buffers for each audio group.
|
||||
rc_t _audioGroupAllocBuffer( io_t* p )
|
||||
{
|
||||
@ -1656,6 +1741,13 @@ namespace cw
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// initialize enabled audio meters
|
||||
if((rc = _audioDeviceEnableMeters(p)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Audio device enabled failed.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
@ -1839,31 +1931,7 @@ namespace cw
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _audioDeviceParams( handle_t h, unsigned devIdx, unsigned flags, io_t*& pRef, audioDev_t*& adRef, unsigned& audioBufFlagsRef )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
pRef = _handleToPtr(h);
|
||||
|
||||
if((adRef = _audioDeviceIndexToRecd(pRef,devIdx)) == nullptr )
|
||||
rc = kInvalidArgRC;
|
||||
else
|
||||
{
|
||||
audioBufFlagsRef = 0;
|
||||
if( cwIsFlag(flags,kInFl) )
|
||||
audioBufFlagsRef += audio::buf::kInFl;
|
||||
|
||||
if( cwIsFlag(flags,kOutFl) )
|
||||
audioBufFlagsRef += audio::buf::kOutFl;
|
||||
|
||||
if( cwIsFlag(flags,kEnableFl) )
|
||||
audioBufFlagsRef += audio::buf::kEnableFl;
|
||||
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -2386,43 +2454,8 @@ unsigned cw::io::audioDeviceChannelCount( handle_t h, unsigned devIdx, unsigne
|
||||
|
||||
cw::rc_t cw::io::audioDeviceEnableMeters( handle_t h, unsigned devIdx, unsigned inOutEnaFlags )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
io_t* p = nullptr;
|
||||
audioDev_t* ad = nullptr;
|
||||
unsigned audioBufFlags = 0;
|
||||
|
||||
if((rc = _audioDeviceParams( h, devIdx, inOutEnaFlags, p, ad, audioBufFlags )) != kOkRC )
|
||||
rc = cwLogError(rc,"Enable tone failed.");
|
||||
else
|
||||
{
|
||||
bool enaFl = inOutEnaFlags & kEnableFl;
|
||||
bool enaState0Fl = _audioDeviceIsMeterEnabled(ad, kInFl | kOutFl);
|
||||
|
||||
audioBufFlags += audio::buf::kMeterFl;
|
||||
|
||||
|
||||
if( inOutEnaFlags & kInFl )
|
||||
ad->iagd->flags = cwEnaFlag(ad->iagd->flags,kMeterFl,enaFl);
|
||||
|
||||
if( inOutEnaFlags & kOutFl )
|
||||
ad->oagd->flags = cwEnaFlag(ad->oagd->flags,kMeterFl,enaFl);
|
||||
|
||||
audio::buf::setFlag( p->audioBufH, devIdx, kInvalidIdx, audioBufFlags );
|
||||
|
||||
bool enaState1Fl= _audioDeviceIsMeterEnabled(ad, kInFl | kOutFl);
|
||||
|
||||
if( enaState1Fl and !enaState0Fl )
|
||||
p->audioMeterDevEnabledN += 1;
|
||||
else
|
||||
if( p->audioMeterDevEnabledN > 0 && !enaState1Fl && enaState0Fl )
|
||||
p->audioMeterDevEnabledN -= 1;
|
||||
|
||||
}
|
||||
|
||||
if( rc != kOkRC )
|
||||
rc = cwLogError(rc,"Enable meters failed.");
|
||||
|
||||
return rc;
|
||||
io_t* p = _handleToPtr(h);
|
||||
return _audioDeviceEnableMeter(p, devIdx, inOutEnaFlags );
|
||||
}
|
||||
|
||||
|
||||
@ -2460,11 +2493,11 @@ const cw::io::sample_t* cw::io::audioDeviceMeters( handle_t h, unsigned devIdx,
|
||||
cw::rc_t cw::io::audioDeviceEnableTone( handle_t h, unsigned devIdx, unsigned inOutEnaFlags )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
io_t* p = nullptr;
|
||||
io_t* p = _handleToPtr(h);
|
||||
audioDev_t* ad = nullptr;
|
||||
unsigned audioBufFlags = 0;
|
||||
|
||||
if((rc = _audioDeviceParams( h, devIdx, inOutEnaFlags, p, ad, audioBufFlags )) != kOkRC )
|
||||
if((rc = _audioDeviceParams( p, devIdx, inOutEnaFlags, ad, audioBufFlags )) != kOkRC )
|
||||
rc = cwLogError(rc,"Enable tone failed.");
|
||||
else
|
||||
{
|
||||
@ -2479,11 +2512,11 @@ cw::rc_t cw::io::audioDeviceToneFlags( handle_t h, unsigned devIdx, unsigned inO
|
||||
{
|
||||
|
||||
rc_t rc = kOkRC;
|
||||
io_t* p = nullptr;
|
||||
io_t* p = _handleToPtr(h);
|
||||
audioDev_t* ad = nullptr;
|
||||
unsigned audioBufFlags = 0;
|
||||
|
||||
if((rc = _audioDeviceParams( h, devIdx, inOrOutFlag, p, ad, audioBufFlags )) != kOkRC )
|
||||
if((rc = _audioDeviceParams( p, devIdx, inOrOutFlag, ad, audioBufFlags )) != kOkRC )
|
||||
rc = cwLogError(rc,"Get tone flags failed.");
|
||||
else
|
||||
{
|
||||
@ -2497,11 +2530,11 @@ cw::rc_t cw::io::audioDeviceToneFlags( handle_t h, unsigned devIdx, unsigned inO
|
||||
cw::rc_t cw::io::audioDeviceEnableMute( handle_t h, unsigned devIdx, unsigned inOutEnaFlags )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
io_t* p = nullptr;
|
||||
io_t* p = _handleToPtr(h);
|
||||
audioDev_t* ad = nullptr;
|
||||
unsigned audioBufFlags = 0;
|
||||
|
||||
if((rc = _audioDeviceParams( h, devIdx, inOutEnaFlags, p, ad, audioBufFlags )) != kOkRC )
|
||||
if((rc = _audioDeviceParams( p, devIdx, inOutEnaFlags, ad, audioBufFlags )) != kOkRC )
|
||||
rc = cwLogError(rc,"Enable mute failed.");
|
||||
else
|
||||
{
|
||||
@ -2515,11 +2548,11 @@ cw::rc_t cw::io::audioDeviceEnableMute( handle_t h, unsigned devIdx, unsigned in
|
||||
cw::rc_t cw::io::audioDeviceMuteFlags( handle_t h, unsigned devIdx, unsigned inOrOutFlag, bool* muteFlA, unsigned chCnt )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
io_t* p = nullptr;
|
||||
io_t* p = _handleToPtr(h);
|
||||
audioDev_t* ad = nullptr;
|
||||
unsigned audioBufFlags = 0;
|
||||
|
||||
if((rc = _audioDeviceParams( h, devIdx, inOrOutFlag, p, ad, audioBufFlags )) != kOkRC )
|
||||
if((rc = _audioDeviceParams( p, devIdx, inOrOutFlag, ad, audioBufFlags )) != kOkRC )
|
||||
rc = cwLogError(rc,"Get mute flags failed.");
|
||||
else
|
||||
{
|
||||
@ -2534,11 +2567,11 @@ cw::rc_t cw::io::audioDeviceMuteFlags( handle_t h, unsigned devIdx, unsigned inO
|
||||
cw::rc_t cw::io::audioDeviceSetGain( handle_t h, unsigned devIdx, unsigned inOrOutFlag, double gain )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
io_t* p = nullptr;
|
||||
io_t* p = _handleToPtr(h);
|
||||
audioDev_t* ad = nullptr;
|
||||
unsigned audioBufFlags = 0;
|
||||
|
||||
if((rc = _audioDeviceParams( h, devIdx, inOrOutFlag, p, ad, audioBufFlags )) != kOkRC )
|
||||
if((rc = _audioDeviceParams( p, devIdx, inOrOutFlag, ad, audioBufFlags )) != kOkRC )
|
||||
rc = cwLogError(rc,"Set gain failed.");
|
||||
else
|
||||
{
|
||||
@ -2551,11 +2584,11 @@ cw::rc_t cw::io::audioDeviceSetGain( handle_t h, unsigned devIdx, unsigned inOrO
|
||||
cw::rc_t cw::io::audioDeviceGain( handle_t h, unsigned devIdx, unsigned inOrOutFlag, double* gainA, unsigned chCnt )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
io_t* p = nullptr;
|
||||
io_t* p = _handleToPtr(h);
|
||||
audioDev_t* ad = nullptr;
|
||||
unsigned audioBufFlags = 0;
|
||||
|
||||
if((rc = _audioDeviceParams( h, devIdx, inOrOutFlag, p, ad, audioBufFlags )) != kOkRC )
|
||||
if((rc = _audioDeviceParams( p, devIdx, inOrOutFlag, ad, audioBufFlags )) != kOkRC )
|
||||
rc = cwLogError(rc,"Get gain failed.");
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user