cwFlowProc.h/cpp : Added 'audio_duplicate' and 'balance'.
This commit is contained in:
parent
babda9b32d
commit
667570f513
349
cwFlowProc.cpp
349
cwFlowProc.cpp
@ -83,6 +83,72 @@ namespace cw
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// balance
|
||||
//
|
||||
namespace balance
|
||||
{
|
||||
enum
|
||||
{
|
||||
kInPId,
|
||||
kOutPId,
|
||||
kInvOutPId
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
} inst_t;
|
||||
|
||||
|
||||
rc_t create( instance_t* ctx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
real_t in_value = 0.5;
|
||||
|
||||
if((rc = var_register_and_get( ctx, kAnyChIdx, kInPId, "in", in_value )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
if((rc = var_register_and_set( ctx, kAnyChIdx,
|
||||
kOutPId, "out", in_value,
|
||||
kInvOutPId, "inv_out", (real_t)(1.0-in_value) )) != kOkRC )
|
||||
{
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t destroy( instance_t* ctx )
|
||||
{ return kOkRC; }
|
||||
|
||||
rc_t value( instance_t* ctx, variable_t* var )
|
||||
{ return kOkRC; }
|
||||
|
||||
rc_t exec( instance_t* ctx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
real_t value = 1;
|
||||
|
||||
var_get(ctx, kInPId, kAnyChIdx, value);
|
||||
var_set(ctx, kOutPId, kAnyChIdx, value);
|
||||
var_set(ctx, kInvOutPId, kAnyChIdx, (real_t)(1.0 - value) );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
class_members_t members = {
|
||||
.create = create,
|
||||
.destroy = destroy,
|
||||
.value = value,
|
||||
.exec = exec,
|
||||
.report = nullptr
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
@ -500,9 +566,9 @@ namespace cw
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// gain
|
||||
// audio_gain
|
||||
//
|
||||
namespace gain
|
||||
namespace audio_gain
|
||||
{
|
||||
enum
|
||||
{
|
||||
@ -718,6 +784,143 @@ namespace cw
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// audio_duplicate
|
||||
//
|
||||
namespace audio_duplicate
|
||||
{
|
||||
enum {
|
||||
kInPId,
|
||||
kDuplicatePId,
|
||||
kGainPId,
|
||||
kOutPId,
|
||||
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned* chDuplMap; // [ inChN ] duplicate channel map
|
||||
unsigned outChN;
|
||||
} inst_t;
|
||||
|
||||
|
||||
rc_t create( instance_t* ctx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
const abuf_t* abuf = nullptr; //
|
||||
inst_t* inst = mem::allocZ<inst_t>();
|
||||
|
||||
ctx->userPtr = inst;
|
||||
|
||||
// get the source audio buffer
|
||||
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",abuf )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
if( abuf->chN )
|
||||
{
|
||||
inst->chDuplMap = mem::allocZ<unsigned>(abuf->chN);
|
||||
|
||||
// register the gain
|
||||
for(unsigned i=0; i<abuf->chN; ++i)
|
||||
{
|
||||
if((rc = var_register_and_get( ctx, i, kDuplicatePId, "duplicate", inst->chDuplMap[i] )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
if( inst->chDuplMap[i] )
|
||||
{
|
||||
// register an input gain control
|
||||
if((rc = var_register( ctx, inst->outChN, kGainPId, "gain")) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
// count the number of selected channels to determine the count of output channels
|
||||
inst->outChN += inst->chDuplMap[i];
|
||||
}
|
||||
}
|
||||
|
||||
// create the output audio buffer
|
||||
if( inst->outChN == 0 )
|
||||
cwLogWarning("The audio split instance '%s' has no selected channels.",ctx->label);
|
||||
else
|
||||
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, abuf->srate, inst->outChN, abuf->frameN );
|
||||
}
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t destroy( instance_t* ctx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
inst_t* inst = (inst_t*)ctx->userPtr;
|
||||
|
||||
mem::release(inst->chDuplMap);
|
||||
|
||||
mem::release(inst);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t value( instance_t* ctx, variable_t* var )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t exec( instance_t* ctx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
const abuf_t* ibuf = nullptr;
|
||||
abuf_t* obuf = nullptr;
|
||||
inst_t* inst = (inst_t*)ctx->userPtr;
|
||||
unsigned outChIdx = 0;
|
||||
|
||||
if( inst->outChN )
|
||||
{
|
||||
// get the src buffer
|
||||
if((rc = var_get(ctx,kInPId, kAnyChIdx, ibuf )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
// get the dst buffer
|
||||
if((rc = var_get(ctx,kOutPId, kAnyChIdx, obuf)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
// for each input channel
|
||||
for(unsigned i=0; i<ibuf->chN && outChIdx<obuf->chN; ++i)
|
||||
{
|
||||
sample_t* isig = ibuf->buf + i * ibuf->frameN;
|
||||
sample_t gain = 1;
|
||||
|
||||
var_get(ctx,kGainPId,i,gain);
|
||||
|
||||
for(unsigned j=0; j<inst->chDuplMap[i]; ++j )
|
||||
{
|
||||
sample_t* osig = obuf->buf + j * obuf->frameN;
|
||||
|
||||
// apply the gain
|
||||
for(unsigned k=0; k<ibuf->frameN; ++k)
|
||||
osig[k] = gain * isig[k];
|
||||
|
||||
outChIdx += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
class_members_t members = {
|
||||
.create = create,
|
||||
.destroy = destroy,
|
||||
.value = value,
|
||||
.exec = exec,
|
||||
.report = nullptr
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// audio_merge
|
||||
@ -831,6 +1034,126 @@ namespace cw
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// audio_mix
|
||||
//
|
||||
namespace audio_mix
|
||||
{
|
||||
enum {
|
||||
kIn0PId,
|
||||
kIn1PId,
|
||||
kGain0PId,
|
||||
kGain1PId,
|
||||
kOutPId,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
} inst_t;
|
||||
|
||||
|
||||
rc_t create( instance_t* ctx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
const abuf_t* abuf0 = nullptr; //
|
||||
const abuf_t* abuf1 = nullptr;
|
||||
unsigned outChN = 0;
|
||||
|
||||
// get the source audio buffer
|
||||
if((rc = var_register_and_get(ctx, kAnyChIdx,
|
||||
kIn0PId,"in0",abuf0,
|
||||
kIn1PId,"in1",abuf1 )) != kOkRC )
|
||||
{
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
assert( abuf0->frameN == abuf1->frameN );
|
||||
|
||||
outChN = std::max(abuf0->chN, abuf1->chN);
|
||||
|
||||
// register the gain
|
||||
var_register( ctx, kAnyChIdx, kGain0PId, "gain0" );
|
||||
var_register( ctx, kAnyChIdx, kGain1PId, "gain1" );
|
||||
|
||||
// create the output audio buffer
|
||||
rc = var_register_and_set( ctx, "out", kOutPId, kAnyChIdx, abuf0->srate, outChN, abuf0->frameN );
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t destroy( instance_t* ctx )
|
||||
{ return kOkRC; }
|
||||
|
||||
rc_t value( instance_t* ctx, variable_t* var )
|
||||
{ return kOkRC; }
|
||||
|
||||
rc_t _mix( instance_t* ctx, unsigned inPId, unsigned gainPId, abuf_t* obuf )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
const abuf_t* ibuf = nullptr;
|
||||
|
||||
if((rc = var_get(ctx, inPId, kAnyChIdx, ibuf )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
|
||||
if(rc == kOkRC )
|
||||
{
|
||||
unsigned chN = std::min(ibuf->chN, obuf->chN );
|
||||
|
||||
for(unsigned i=0; i<chN; ++i)
|
||||
{
|
||||
const sample_t* isig = ibuf->buf + i*ibuf->frameN;
|
||||
sample_t* osig = obuf->buf + i*obuf->frameN;
|
||||
real_t gain = 1;
|
||||
|
||||
if((rc = var_get(ctx, gainPId, i, gain)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
for(unsigned j=0; j<obuf->frameN; ++j)
|
||||
osig[j] += gain * isig[j];
|
||||
}
|
||||
}
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
rc_t exec( instance_t* ctx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
abuf_t* obuf = nullptr;
|
||||
const abuf_t* ibuf0 = nullptr;
|
||||
const abuf_t* ibuf1 = nullptr;
|
||||
|
||||
if((rc = var_get(ctx,kOutPId, kAnyChIdx, obuf)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
if((rc = var_get(ctx,kIn0PId, kAnyChIdx, ibuf0 )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
if((rc = var_get(ctx,kIn1PId, kAnyChIdx, ibuf1 )) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
_mix( ctx, kIn0PId, kGain0PId, obuf );
|
||||
_mix( ctx, kIn1PId, kGain1PId, obuf );
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
class_members_t members = {
|
||||
.create = create,
|
||||
.destroy = destroy,
|
||||
.value = value,
|
||||
.exec = exec,
|
||||
.report = nullptr
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
@ -1614,6 +1937,8 @@ namespace cw
|
||||
real_t delayMs = 0;
|
||||
real_t maxDelayMs = 0;
|
||||
|
||||
ctx->userPtr = inst;
|
||||
|
||||
// get the source audio buffer
|
||||
if((rc = var_register_and_get(ctx, kAnyChIdx,kInPId,"in",abuf )) != kOkRC )
|
||||
goto errLabel;
|
||||
@ -1632,7 +1957,9 @@ namespace cw
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
inst->maxDelayFrameN = std::max(inst->maxDelayFrameN, (unsigned)(maxDelayMs * abuf->srate / 1000.0) );
|
||||
inst->maxDelayFrameN = std::max(inst->maxDelayFrameN, (unsigned)(fabs(maxDelayMs) * abuf->srate / 1000.0) );
|
||||
|
||||
inst->cntV[i] = (unsigned)(fabs(delayMs) * abuf->srate / 1000.0);
|
||||
|
||||
}
|
||||
|
||||
@ -1683,14 +2010,24 @@ namespace cw
|
||||
sample_t* osig = obuf->buf + i*obuf->frameN;
|
||||
unsigned di = inst->idxV[i];
|
||||
|
||||
// if the delay is set to zero samples
|
||||
if( inst->cntV[i] == 0 )
|
||||
memcpy(osig,isig,ibuf->frameN * sizeof(sample_t));
|
||||
else
|
||||
{
|
||||
// otherwise the delay is non-zero positive sample count
|
||||
for(unsigned j=0; j<ibuf->frameN; ++j)
|
||||
{
|
||||
osig[j] = inst->delayBuf->buf[di];
|
||||
inst->delayBuf->buf[di] = isig[j];
|
||||
di = (di+1) % inst->cntV[i];
|
||||
osig[j] = inst->delayBuf->buf[di]; // read delay output
|
||||
inst->delayBuf->buf[di] = isig[j]; // set delay input
|
||||
di = (di+1) % inst->cntV[i]; // update the delay index
|
||||
}
|
||||
}
|
||||
|
||||
// store the delay index for the next cycle
|
||||
inst->idxV[i] = di;
|
||||
}
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
@ -6,14 +6,17 @@ namespace cw
|
||||
namespace audio_out { extern class_members_t members; }
|
||||
namespace audioFileIn { extern class_members_t members; }
|
||||
namespace audioFileOut { extern class_members_t members; }
|
||||
namespace gain { extern class_members_t members; }
|
||||
namespace audio_gain { extern class_members_t members; }
|
||||
namespace audio_split { extern class_members_t members; }
|
||||
namespace audio_merge { extern class_members_t members; }
|
||||
namespace audio_duplicate { extern class_members_t members; }
|
||||
namespace audio_mix { extern class_members_t members; }
|
||||
namespace sine_tone { extern class_members_t members; }
|
||||
namespace pv_analysis { extern class_members_t members; }
|
||||
namespace pv_synthesis { extern class_members_t members; }
|
||||
namespace spec_dist { extern class_members_t members; }
|
||||
namespace compressor { extern class_members_t members; }
|
||||
namespace audio_delay { extern class_members_t members; }
|
||||
namespace balance { extern class_members_t members; }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user