Skip to content

Commit

Permalink
Forward buffer extended for new operation mode with duplex devices
Browse files Browse the repository at this point in the history
  • Loading branch information
hkbinaurics committed Jun 6, 2024
1 parent 20ccbea commit 070d6ef
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,10 @@ CjvxAuNConvert::adapt_output_parameters_forward()
neg_output._update_parameters_fixed(
JVX_SIZE_UNSELECTED,
node_output._common_set_node_params_a_1io.buffersize,
node_output._common_set_node_params_a_1io.samplerate);
node_output._common_set_node_params_a_1io.samplerate,
(jvxDataFormat)node_output._common_set_node_params_a_1io.format,
(jvxDataFormatGroup)node_output._common_set_node_params_a_1io.subformat,
(jvxDataflow)node_output._common_set_node_params_a_1io.data_flow);
}

void
Expand All @@ -190,7 +193,14 @@ CjvxAuNConvert::adapt_output_parameters_backward(jvxSize numChannelsOutDesired,
jvxErrorType
CjvxAuNConvert::transfer_backward_ocon(jvxLinkDataTransferType tp, jvxHandle* data JVX_CONNECTION_FEEDBACK_TYPE_A(fdb))
{
return CjvxBareNode1ioRearrange::transfer_backward_ocon(tp, data JVX_CONNECTION_FEEDBACK_CALL_A(fdb));
// This function involves the default implementation but should end up in <accept_negotiate_output>
// by inheritance
jvxErrorType res = CjvxBareNode1ioRearrange::transfer_backward_ocon(tp, data JVX_CONNECTION_FEEDBACK_CALL_A(fdb));
if (res != JVX_NO_ERROR)
{

}
return res;
}

jvxErrorType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ SECTION PROPERTIES
CONTENT_DECODER_TYPE = "JVX_PROPERTY_DECODER_SINGLE_SELECTION";
CALLBACK_SET_POSTHOOK = "set_buffer_mode";
};

SECTION enable_buffer_profiling
{
TYPE = "JVX_DATAFORMAT_BOOL";
INIT_SET = 0;
READ_WRITE_ACCESS = "JVX_PROPERTY_ACCESS_FULL_READ_AND_WRITE";
};
};

SECTION monitor
Expand All @@ -54,21 +61,44 @@ SECTION PROPERTIES
ALLOWED_STATE_MASK = {"JVX_STATE_SELECTED", "JVX_STATE_ACTIVE", "JVX_STATE_PREPARED", "JVX_STATE_PROCESSING"};
CALLBACKS = {"get_processing_monitor"};
CALLBACK_GET_PREHOOK = "get_processing_monitor";

SECTION buffer_underflow
SECTION number_overflows
{
// On the output side, the module can not deliver audio samples on request!!
DESCRIPTION = "Number of overflows"; // Defaults to NAME if not present
TYPE = "JVX_DATAFORMAT_SIZE";
INIT_SET = 0;
READ_WRITE_ACCESS = "JVX_PROPERTY_ACCESS_FULL_READ_AND_WRITE";
};
SECTION buffer_overflow
INIT_SET = 0;
};
SECTION number_underflows
{
// On the input side, the module can not store incoming data
DESCRIPTION = "Number of overflows"; // Defaults to NAME if not present
TYPE = "JVX_DATAFORMAT_SIZE";
INIT_SET = 0;
};
SECTION number_aborts
{
DESCRIPTION = "Number of aborts"; // Defaults to NAME if not present
TYPE = "JVX_DATAFORMAT_SIZE";
INIT_SET = 0;
READ_WRITE_ACCESS = "JVX_PROPERTY_ACCESS_FULL_READ_AND_WRITE";
};
};

SECTION fillheight_avrg
{
DESCRIPTION = "Current fill height"; // Defaults to NAME if not present
TYPE = "JVX_DATAFORMAT_DATA";
INIT_SET = 0;
};
SECTION fillheight_min
{
DESCRIPTION = "Current min fill height"; // Defaults to NAME if not present
TYPE = "JVX_DATAFORMAT_DATA";
INIT_SET = 0;
};
SECTION fillheight_max
{
DESCRIPTION = "Current max fill height"; // Defaults to NAME if not present
TYPE = "JVX_DATAFORMAT_DATA";
INIT_SET = 0;
};
};

SECTION convert
Expand All @@ -79,7 +109,7 @@ SECTION PROPERTIES

SECTION channel_selection
{
TYPE = "JVX_DATAFORMAT_SELECTION_LIST";
TYPE = "JVX_DATAFORMAT_SELECTION_LIST";
SELECTION_LIST_NAMES = {};
SELECTION_LIST_SELECTED = {"yes", "no", "no", "no", "no"};
SELECTION_LIST_EXCLUSIVE = {"no", "no", "no", "no", "no"};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "CjvxAuNForwardBuffer.h"
#include "jvx-helpers-cpp.h"

#define ALPHA_SMOOTH 0.95

CjvxAuNForwardBuffer::CjvxAuNForwardBuffer(JVX_CONSTRUCTOR_ARGUMENTS_MACRO_DECLARE) :
CjvxBareNode1ioRearrange(JVX_CONSTRUCTOR_ARGUMENTS_MACRO_CALL)
{
Expand Down Expand Up @@ -388,7 +390,8 @@ CjvxAuNForwardBuffer::prepare_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb))
bs,
node_output._common_set_node_params_a_1io.number_channels,
(jvxDataFormat)node_output._common_set_node_params_a_1io.format,
false, withStartThreshold);
genForwardBuffer_node::config.enable_buffer_profiling.value,
withStartThreshold);

assert(node_inout._common_set_node_params_a_1io.buffersize == _common_set_icon.theData_in->con_params.buffersize);
assert(node_output._common_set_node_params_a_1io.buffersize == _common_set_ocon.theData_out.con_params.buffersize);
Expand All @@ -401,20 +404,23 @@ CjvxAuNForwardBuffer::prepare_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb))

if (buffermode == jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_INPUT)
{
if (_common_set_icon.theData_in->con_params.data_flow == jvxDataflow::JVX_DATAFLOW_PUSH_ON_PULL)
if (dataFlowOperation_input == jvxDataflow::JVX_DATAFLOW_PUSH_ON_PULL)
{
// Start the secondary thread
// Start the secondary thread to collect data on input side
resL = refThreads.cpPtr->initialize(
static_cast<IjvxThreads_report*>(this));
assert(resL == JVX_NO_ERROR);
}
}
else
{
// Start the secondary thread
resL = refThreads.cpPtr->initialize(
static_cast<IjvxThreads_report*>(this));
assert(resL == JVX_NO_ERROR);
if (dataFlowOperation_output == JVX_DATAFLOW_PUSH_ASYNC)
{
// Start the secondary thread for output
resL = refThreads.cpPtr->initialize(
static_cast<IjvxThreads_report*>(this));
assert(resL == JVX_NO_ERROR);
}
}
}
else
Expand Down Expand Up @@ -513,8 +519,13 @@ CjvxAuNForwardBuffer::start_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb))
}
}

genForwardBuffer_node::monitor.buffer_underflow.value = 0;
genForwardBuffer_node::monitor.buffer_overflow.value = 0;
genForwardBuffer_node::monitor.number_overflows.value = 0;
genForwardBuffer_node::monitor.number_underflows.value = 0;
genForwardBuffer_node::monitor.number_aborts.value = 0;
genForwardBuffer_node::monitor.fillheight_avrg.value = 0;
genForwardBuffer_node::monitor.fillheight_min.value = 0;
genForwardBuffer_node::monitor.fillheight_max.value = 0;

return res;
}

Expand Down Expand Up @@ -658,9 +669,25 @@ CjvxAuNForwardBuffer::process_buffers_icon(jvxSize mt_mask, jvxSize idx_stage)
0, nullptr, nullptr,
nullptr, nullptr);

if (res != JVX_NO_ERROR)
if (res == JVX_NO_ERROR)
{
genForwardBuffer_node::monitor.buffer_overflow.value++;
if (fHeightEstimator)
{
jvxData out_average = 0;
jvxData out_min = 0;
jvxData out_max = 0;
jvx_audio_stack_sample_dispenser_update_fillheight(
&myAudioDispenser, 0, &out_average,
&out_min, &out_max, NULL, NULL, NULL);

genForwardBuffer_node::monitor.fillheight_avrg.value = genForwardBuffer_node::monitor.fillheight_avrg.value * ALPHA_SMOOTH + out_average * (1 - ALPHA_SMOOTH);
genForwardBuffer_node::monitor.fillheight_min.value = out_min;
genForwardBuffer_node::monitor.fillheight_max.value = out_max;
}
}
else
{
genForwardBuffer_node::monitor.number_overflows.value++;
}

// ========================================================================================================
Expand All @@ -670,7 +697,7 @@ CjvxAuNForwardBuffer::process_buffers_icon(jvxSize mt_mask, jvxSize idx_stage)
// Check function <write_samples_from_buffer>
if (buffermode == jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_OUTPUT)
{
if (_common_set_ocon.theData_out.con_params.data_flow == JVX_DATAFLOW_PUSH_ASYNC)
if (dataFlowOperation_output == JVX_DATAFLOW_PUSH_ASYNC)
{
if (
(res == JVX_NO_ERROR) ||
Expand Down Expand Up @@ -760,7 +787,7 @@ CjvxAuNForwardBuffer::transfer_backward_ocon(jvxLinkDataTransferType tp, jvxHand
if (dataFlowOperation_output == JVX_DATAFLOW_PUSH_ON_PULL)
{
// Immediate write
res = push_on_pull_one_buffer(data, false, false);
res = push_on_pull_one_buffer(data, true, false);
}

// else: this call should not occur in case of a JVX_DATAFLOW_PUSH_ASYNC or JVX_DATAFLOW_PUSH
Expand Down Expand Up @@ -830,7 +857,7 @@ CjvxAuNForwardBuffer::push_on_pull_one_buffer(jvxHandle* data, jvxBool runStartS
break;
case JVX_DSP_ERROR_BUFFER_OVERFLOW:
// Count the underflow events - even if the chan -- but not if not yet ready.
genForwardBuffer_node::monitor.buffer_underflow.value++;
genForwardBuffer_node::monitor.number_overflows.value++;

[[fallthrough]];

Expand Down Expand Up @@ -1304,6 +1331,12 @@ JVX_PROPERTIES_FORWARD_C_CALLBACK_EXECUTE_FULL(CjvxAuNForwardBuffer, set_buffer_

CjvxAudioStackBuffer::CjvxAudioStackBuffer()
{
// Provide a default setup for the fillheight estimator
numberEventsConsidered_perMinMaxSection = 10;
num_MinMaxSections = 5;
recSmoothFactor = 0.95;
numOperations = 0;

JVX_INITIALIZE_MUTEX(safeAccess_lock);
}

Expand Down Expand Up @@ -1414,7 +1447,7 @@ CjvxAudioStackBuffer::start_audiostack(
NULL, NULL);
assert(resL == JVX_DSP_NO_ERROR);

jvx_audio_stack_sample_dispenser_cont_prepare(&myAudioDispenser, nullptr);
jvx_audio_stack_sample_dispenser_cont_prepare(&myAudioDispenser, fHeightEstimator);
assert(resL == JVX_DSP_NO_ERROR);
}

Expand Down Expand Up @@ -1449,6 +1482,7 @@ CjvxAudioStackBuffer::stop_audiostack()
{
resL = jvx_estimate_buffer_fillheight_terminate(fHeightEstimator);
assert(resL == JVX_DSP_NO_ERROR);
fHeightEstimator = nullptr;
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@ SECTION PROPERTIES
TYPE = "JVX_DATAFORMAT_SELECTION_LIST";
CONTENT_DECODER_TYPE = "JVX_PROPERTY_DECODER_SINGLE_SELECTION";
ONLY_SELECTION_TO_CONFIG = "yes";
SELECTION_LIST_NAMES = {"UNBUFFERED_PULL", "UNBUFFERED", "BUFFERED"};
SELECTION_LIST_SELECTED = {"yes", "no", "no"};
SELECTION_LIST_EXCLUSIVE = {"yes", "yes", "yes"};
SELECTION_LIST_NAMES = {"UNBUFFERED_PUSH", "BUFFERED_PULL"};
SELECTION_LIST_SELECTED = {"yes", "no"};
SELECTION_LIST_EXCLUSIVE = {"yes", "yes"};
SELECTION_LIST_TRANSLATORS = {
"jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED_PULL",
"jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED",
"jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_BUFFERED"};
"jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED_PUSH",
"jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_BUFFERED_PULL"};
SELECTION_TRANSLATOR_TYPE = "jvxSynchronizeBufferMode";
READ_WRITE_ACCESS = "JVX_PROPERTY_ACCESS_READ_AND_WRITE_CONTENT";
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,12 @@ jvxErrorType CjvxSpNSynchronize::test_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(
jvxErrorType res = CjvxBareNode1ioRearrange::test_connect_icon(JVX_CONNECTION_FEEDBACK_CALL(fdb));
jvxConstraintSetResult resS = jvxConstraintSetResult::JVX_NEGOTIATE_CONSTRAINT_NO_CHANGE;
jvxBool triggerUpdate = false;
jvxDataflow flow_sec = JVX_DATAFLOW_PUSH_ACTIVE;
jvxDataflow flow_sec = JVX_DATAFLOW_PUSH_ON_PULL;
if (res == JVX_NO_ERROR)
{
switch (bufferMode)
{
case jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED_PULL:
case jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED:
case jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED_PUSH:

node_output._common_set_node_params_a_1io.data_flow = JVX_DATAFLOW_PUSH_ACTIVE;
node_inout._common_set_node_params_a_1io.data_flow = JVX_DATAFLOW_PUSH_ACTIVE;
Expand All @@ -119,11 +118,7 @@ jvxErrorType CjvxSpNSynchronize::test_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(
(jvxDataFormatGroup)node_inout._common_set_node_params_a_1io.subformat,
JVX_DATAFLOW_PUSH_ACTIVE);
triggerUpdate &= (resS == jvxConstraintSetResult::JVX_NEGOTIATE_CONSTRAINT_CHANGE);

if (bufferMode == jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED_PULL)
{
flow_sec = jvxDataflow::JVX_DATAFLOW_PUSH_ON_PULL;
}

resS = sec_master.neg_input._update_parameters_fixed(
node_output._common_set_node_params_a_1io.number_channels,
node_output._common_set_node_params_a_1io.buffersize,
Expand All @@ -134,10 +129,10 @@ jvxErrorType CjvxSpNSynchronize::test_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(
//(jvxDataflow)node_output._common_set_node_params_a_1io.data_flow);
triggerUpdate &= (resS == jvxConstraintSetResult::JVX_NEGOTIATE_CONSTRAINT_CHANGE);
break;
case jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_BUFFERED:
case jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_BUFFERED_PULL:

node_inout._common_set_node_params_a_1io.data_flow = JVX_DATAFLOW_PUSH_ACTIVE;
node_output._common_set_node_params_a_1io.data_flow = JVX_DATAFLOW_PUSH_ACTIVE;
node_inout._common_set_node_params_a_1io.data_flow = JVX_DATAFLOW_PUSH_ASYNC;
node_output._common_set_node_params_a_1io.data_flow = JVX_DATAFLOW_PUSH_ON_PULL;

// Update the processing parameters on the synchronized side
resS = sec_master.neg_output._update_parameters_fixed(
Expand Down Expand Up @@ -194,12 +189,13 @@ CjvxSpNSynchronize::process_buffers_icon(jvxSize mt_mask, jvxSize idx_stage)
jvxErrorType res = JVX_NO_ERROR;
switch (bufferMode)
{
case jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED:
case jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED_PULL:
case jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED_PUSH:
sec_master.trigger_process_immediate(_common_set_icon.theData_in, idx_stage, & _common_set_ocon.theData_out);
break;
case jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_BUFFERED:
sec_master.audio_primary(_common_set_icon.theData_in, idx_stage, &_common_set_ocon.theData_out);
case jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_BUFFERED_PULL:

assert(0);
// sec_master.audio_primary(_common_set_icon.theData_in, idx_stage, &_common_set_ocon.theData_out);
break;
}
return fwd_process_buffers_icon(mt_mask, idx_stage);
Expand Down Expand Up @@ -249,6 +245,22 @@ CjvxSpNSynchronize::return_hidden_interface(jvxInterfaceType tp, jvxHandle* hdl)
return(res);
}

void
CjvxSpNSynchronize::fwd_report_process_buffers(jvxHandle** bufferPtrs, const jvxLinkDataDescriptor_con_params& params)
{
jvxSize i;
jvxData** bufsOut = jvx_process_icon_extract_output_buffers<jvxData>(_common_set_ocon.theData_out);

assert(_common_set_ocon.theData_out.con_params.buffersize == params.buffersize);
assert(_common_set_ocon.theData_out.con_params.rate == params.rate);
assert(_common_set_ocon.theData_out.con_params.number_channels == params.number_channels);
assert(_common_set_ocon.theData_out.con_params.format == params.format);

for (i = 0; i < params.number_channels; i++)
{
memcpy(bufsOut[i], bufferPtrs[i], jvxDataFormat_getsize(params.format) * params.buffersize);
}
}
/*
jvxErrorType
CjvxSpNMixChainEnterLeave::select(IjvxObject* owner)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class CjvxSpNSynchronize : public CjvxBareNode1ioRearrange, public genSynchroniz
protected:

CjvxSpNSynchronize_sec sec_master;
jvxSynchronizeBufferMode bufferMode = jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED_PULL;
jvxSynchronizeBufferMode bufferMode = jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED_PUSH;

public:
JVX_CALLINGCONVENTION CjvxSpNSynchronize(JVX_CONSTRUCTOR_ARGUMENTS_MACRO_DECLARE);
Expand Down Expand Up @@ -41,6 +41,7 @@ class CjvxSpNSynchronize : public CjvxBareNode1ioRearrange, public genSynchroniz
jvxErrorType stop_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb)) override;
jvxErrorType process_buffers_icon(jvxSize mt_mask, jvxSize idx_stage)override;

void fwd_report_process_buffers(jvxHandle** bufferPtrs, const jvxLinkDataDescriptor_con_params& params);
/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,18 @@ CjvxSpNSynchronize_sec::test_chain_master(JVX_CONNECTION_FEEDBACK_TYPE(fdb))
jvxErrorType res = JVX_NO_ERROR;

// Copy the current parameter from primary chain
JVX_LINKDATA_LOAD_FROM(& _common_set_ocon.theData_out, referencePtr->node_inout._common_set_node_params_a_1io, JVX_DATAFLOW_PUSH_ON_PULL);

switch (referencePtr->bufferMode)
{
case jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED_PUSH:
JVX_LINKDATA_LOAD_FROM(&_common_set_ocon.theData_out, referencePtr->node_inout._common_set_node_params_a_1io, JVX_DATAFLOW_PUSH_ACTIVE);
break;
case jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_BUFFERED_PULL:
JVX_LINKDATA_LOAD_FROM(&_common_set_ocon.theData_out, referencePtr->node_inout._common_set_node_params_a_1io, JVX_DATAFLOW_PUSH_ON_PULL);
break;
default:
assert(0);
break;
}
res = _test_chain_master(JVX_CONNECTION_FEEDBACK_CALL(fdb));

if (res == JVX_NO_ERROR)
Expand Down
Loading

0 comments on commit 070d6ef

Please sign in to comment.