From 3d7744c141085c0decc8b875cb2547ae9c7f88a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hauke=20Kr=C3=BCger?= Date: Mon, 8 Jul 2024 16:14:05 +0200 Subject: [PATCH] 1) Added option in forward buffer to allow buffer underrun without reporting errors via processing chain. This was and actually is the default setting 2) Extended MixChainEnterLeave to allow or disallow divergence of i/o relation. That is, if the input does not provide any data, the output will not produce either --- .../codeGen/exports_node.pcg | 7 ++++ .../src/CjvxAuNForwardBuffer.cpp | 20 ++++++++--- .../codeGen/exports_node.pcg | 13 +++++++ .../src/CjvxSpNMixChainEnterLeave.cpp | 32 ++++++++++++----- .../src/CjvxSpNMixChainEnterLeave.h | 7 ++-- .../src/CjvxSpNMixChainEnterLeave_input.cpp | 2 +- .../src/CjvxSpNMixChainEnterLeave_output.cpp | 2 +- .../src/CjvxSpNMixChainEnterLeave_props.cpp | 35 ++++++++++++++----- .../common/CjvxSingleConnectorCommon.h | 1 + .../src/common/CjvxSingleInputConnector.cpp | 8 +++-- 10 files changed, 100 insertions(+), 27 deletions(-) diff --git a/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/codeGen/exports_node.pcg b/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/codeGen/exports_node.pcg index 6e2cf7bf..f6a0c9ec 100644 --- a/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/codeGen/exports_node.pcg +++ b/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/codeGen/exports_node.pcg @@ -59,6 +59,13 @@ SECTION PROPERTIES INIT_SET = 0; READ_WRITE_ACCESS = "JVX_PROPERTY_ACCESS_FULL_READ_AND_WRITE"; }; + + SECTION out_fail_no_report + { + TYPE = "JVX_DATAFORMAT_BOOL"; + INIT_SET = 1; + READ_WRITE_ACCESS = "JVX_PROPERTY_ACCESS_FULL_READ_AND_WRITE"; + }; }; SECTION monitor diff --git a/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/src/CjvxAuNForwardBuffer.cpp b/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/src/CjvxAuNForwardBuffer.cpp index e185fff9..755878da 100644 --- a/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/src/CjvxAuNForwardBuffer.cpp +++ b/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/src/CjvxAuNForwardBuffer.cpp @@ -866,12 +866,11 @@ CjvxAuNForwardBuffer::push_on_pull_one_buffer(jvxHandle* data, jvxBool runStartS case JVX_DSP_ERROR_BUFFER_OVERFLOW: // Count the underflow events - even if the chan -- but not if not yet ready. genForwardBuffer_node::monitor.number_overflows.value++; - [[fallthrough]]; case JVX_DSP_ERROR_ABORT: - + res = resL; // No output from buffer, copy silence for (i = 0; i < _common_set_ocon.theData_out.con_params.number_channels; i++) { @@ -883,14 +882,27 @@ CjvxAuNForwardBuffer::push_on_pull_one_buffer(jvxHandle* data, jvxBool runStartS // If the sample buffer does not deliver we need to wakeup the thread!! refThreads.cpPtr->trigger_wakeup(); } - res = JVX_NO_ERROR; + + if (genForwardBuffer_node::config.out_fail_no_report.value) + { + // We see an error at this place, and here, we do not report this error + res = JVX_NO_ERROR; + } + else + { + // We see an error at this place, and here, we report this error + // res = JVX_NO_ERROR; + } break; default: break; } - _common_set_ocon.theData_out.con_link.connect_to->process_buffers_icon(); + if (res == JVX_NO_ERROR) + { + _common_set_ocon.theData_out.con_link.connect_to->process_buffers_icon(); + } if (runStartStop) { diff --git a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/codeGen/exports_node.pcg b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/codeGen/exports_node.pcg index 87ed6582..127a00b2 100644 --- a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/codeGen/exports_node.pcg +++ b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/codeGen/exports_node.pcg @@ -118,4 +118,17 @@ SECTION PROPERTIES READ_WRITE_ACCESS = "JVX_PROPERTY_ACCESS_READ_ONLY"; }; }; + + SECTION monitor + { + GENERATE_ENTRIES_CONFIG_FILE = "no"; // Defaults to "no" if not present + ALLOWED_STATE_MASK = {"JVX_STATE_ACTIVE", "JVX_STATE_PREPARED", "JVX_STATE_PROCESSING"}; + + SECTION ioLinkActiveCnt + { + TYPE = "JVX_DATAFORMAT_SIZE"; + INIT_SET = 0; + READ_WRITE_ACCESS = "JVX_PROPERTY_ACCESS_READ_ONLY"; + }; + }; }; \ No newline at end of file diff --git a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave.cpp b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave.cpp index c9134ec6..b6e50bcc 100644 --- a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave.cpp +++ b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave.cpp @@ -33,6 +33,10 @@ CjvxSpNMixChainEnterLeave::select(IjvxObject* owner) genMixChain::allocate__config(); genMixChain::register__config(this); + genMixChain::init__monitor(); + genMixChain::allocate__monitor(); + genMixChain::register__monitor(this); + genMixChain::init__sources_channel_routing(); genMixChain::allocate__sources_channel_routing(); genMixChain::register__sources_channel_routing(this); @@ -57,6 +61,9 @@ CjvxSpNMixChainEnterLeave::unselect() genMixChain::unregister__sources_channel_routing(this); genMixChain::deallocate__sources_channel_routing(); + genMixChain::unregister__monitor(this); + genMixChain::deallocate__monitor(); + genMixChain::unregister__config(this); genMixChain::deallocate__config(); @@ -257,7 +264,7 @@ CjvxSpNMixChainEnterLeave::test_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb)) cnt++; } - for (auto& elm : presets_channel_routing) + for (auto& elm : presets_io_routing) { for (i = 0; i < elm.second.channel_num; i++) { @@ -286,7 +293,7 @@ CjvxSpNMixChainEnterLeave::test_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb)) cnt++; } - for (auto& elm : presets_channel_routing) + for (auto& elm : presets_io_routing) { for (i = 0; i < elm.second.channel_num; i++) { @@ -368,6 +375,8 @@ CjvxSpNMixChainEnterLeave::prepare_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb // Lock some of the properties _update_properties_on_start(); + genMixChain::monitor.ioLinkActiveCnt.value = 0; + if (operationMode != jvxOperationModeMixChain::JVX_OPERTION_MODE_MIX_CHAIN_TALKTHROUGH) { // Here, we have seen the following copy before: @@ -564,11 +573,17 @@ CjvxSpNMixChainEnterLeave::process_buffers_icon(jvxSize mt_mask, jvxSize idx_sta lock(); for (auto& elm : CjvxConnectorCollection::processingConnectors) { - jvxErrorType resOther = elm.second.ioconn->resultFromInputConnector(); - if( - (resOther == JVX_ERROR_UNKNOWN) || + jvxErrorType resOther = resOther = elm.second.ioconn->resultFromInputConnector(); + if ( + (resOther == JVX_ERROR_UNKNOWN) || resOther == JVX_NO_ERROR) + { elm.second.ioconn->trigger_put_data(); + } + else + { + genMixChain::monitor.ioLinkActiveCnt.value++; + } } unlock(); break; @@ -734,10 +749,10 @@ CjvxSpNMixChainEnterLeave::check_positive_zero_copy() } jvxErrorType -CjvxSpNMixChainEnterLeave::check_preset_channels(CjvxConnectorOffsetAndMaxChans& conParams, jvxComponentIdentification cpId) +CjvxSpNMixChainEnterLeave::check_preset_channels(CjvxConnectorOffsetAndMaxChans& conParams, jvxBool& linkIoActive, jvxComponentIdentification cpId) { jvxErrorType res = JVX_ERROR_ELEMENT_NOT_FOUND; - for (auto& elm : presets_channel_routing) + for (auto& elm : presets_io_routing) { if (elm.first.tp == cpId.tp) { @@ -750,6 +765,7 @@ CjvxSpNMixChainEnterLeave::check_preset_channels(CjvxConnectorOffsetAndMaxChans& (elm.first.slotsubid == cpId.slotsubid)) { conParams = static_cast (elm.second); + linkIoActive = elm.second.linkIo; res = JVX_NO_ERROR; break; } @@ -758,4 +774,4 @@ CjvxSpNMixChainEnterLeave::check_preset_channels(CjvxConnectorOffsetAndMaxChans& } return res; -} \ No newline at end of file +} diff --git a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave.h b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave.h index 43c32cb1..96529c08 100644 --- a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave.h +++ b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave.h @@ -20,6 +20,7 @@ class chanOffsetAndMaxChans: public CjvxConnectorOffsetAndMaxChans public: jvxComponentIdentification cpId; std::string deviceChannelPrefix = "Channel"; + jvxBool linkIo = false; }; class CjvxSpNMixChainEnterLeave : public CjvxBareNode1ioRearrange, @@ -44,7 +45,8 @@ class CjvxSpNMixChainEnterLeave : public CjvxBareNode1ioRearrange, // Add entries via properties: // , , - std::map presets_channel_routing; + std::map presets_io_routing; + // std::map presets_inout_coupling; /* struct @@ -117,7 +119,8 @@ class CjvxSpNMixChainEnterLeave : public CjvxBareNode1ioRearrange, bool check_positive_zero_copy()override; void offset_channels_to_property(); - jvxErrorType check_preset_channels(CjvxConnectorOffsetAndMaxChans& conParams, jvxComponentIdentification cpId); + jvxErrorType check_preset_channels(CjvxConnectorOffsetAndMaxChans& conParams, jvxBool& linkIoActive, jvxComponentIdentification cpId); + // jvxErrorType check_linkage_sources(jvxBool& linkInOut, jvxComponentIdentification cpId); jvxErrorType transfer_backward_ocon(jvxLinkDataTransferType tp, jvxHandle* data, JVX_CONNECTION_FEEDBACK_TYPE(fdb))override; jvxErrorType transfer_forward_icon(jvxLinkDataTransferType tp, jvxHandle* data JVX_CONNECTION_FEEDBACK_TYPE_A(fdb))override; diff --git a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave_input.cpp b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave_input.cpp index 26627a43..ab33b6bb 100644 --- a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave_input.cpp +++ b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave_input.cpp @@ -62,7 +62,7 @@ CjvxSpNMixChainEnterLeave::report_test_connector(CjvxSingleInputConnector* iconn if (iconn->_common_set_icon.theData_in->con_link.connect_from->transfer_backward_ocon(jvxLinkDataTransferType::JVX_LINKDATA_TRANSFER_REQUEST_REAL_MASTER, &cpId JVX_CONNECTION_FEEDBACK_CALL_A(fdb)) == JVX_NO_ERROR) { - res = check_preset_channels(iconn->chanSetting, cpId); + res = check_preset_channels(iconn->chanSetting, iconn->linkageIoActive, cpId); } } } diff --git a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave_output.cpp b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave_output.cpp index 63c94866..9b014600 100644 --- a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave_output.cpp +++ b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave_output.cpp @@ -60,7 +60,7 @@ CjvxSpNMixChainEnterLeave::report_test_connector(CjvxSingleOutputConnector* ocon { if (oconn->_common_set_ocon.theData_out.con_link.connect_to->transfer_forward_icon(jvxLinkDataTransferType::JVX_LINKDATA_TRANSFER_REQUEST_REAL_MASTER, &cpId JVX_CONNECTION_FEEDBACK_CALL_A(fdb)) == JVX_NO_ERROR) { - res = check_preset_channels(oconn->chanSetting, cpId); + res = check_preset_channels(oconn->chanSetting, oconn->linkageIoActive, cpId); } } } diff --git a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave_props.cpp b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave_props.cpp index 693902f5..affd49d4 100644 --- a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave_props.cpp +++ b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave_props.cpp @@ -6,11 +6,19 @@ CjvxSpNMixChainEnterLeave::offset_channels_to_property() genMixChain::sources_channel_routing.all_definitions.value.entries.clear(); jvx_bitFClear(genMixChain::sources_channel_routing.all_definitions.value.selection(0)); - for (auto& elm : presets_channel_routing) + for (auto& elm : presets_io_routing) { - genMixChain::sources_channel_routing.all_definitions.value.entries.push_back(jvxComponentIdentification_txt(elm.first)); + std::string str = jvxComponentIdentification_txt(elm.first); + str += "--" + elm.second.deviceChannelPrefix; + str += "--[" + jvx_size2String(elm.second.idxOffset); + str += "->" + jvx_size2String(elm.second.idxOffset+elm.second.channel_num-1) + "]"; + if (elm.second.linkIo) + { + str += "::i/o"; + } + genMixChain::sources_channel_routing.all_definitions.value.entries.push_back(str); } - if (presets_channel_routing.size()) + if (presets_io_routing.size()) { jvx_bitZSet(genMixChain::sources_channel_routing.all_definitions.value.selection(0), 0); } @@ -63,6 +71,7 @@ JVX_PROPERTIES_FORWARD_C_CALLBACK_EXECUTE_FULL(CjvxSpNMixChainEnterLeave, specif { chanOffsetAndMaxChans newElm; bool err = false; + jvxBool inoutCoupling = false; auto res = jvxComponentIdentification_decode(newElm.cpId, lst[0]); if (res != JVX_NO_ERROR) { @@ -89,10 +98,18 @@ JVX_PROPERTIES_FORWARD_C_CALLBACK_EXECUTE_FULL(CjvxSpNMixChainEnterLeave, specif if (!err) { - auto elmI = presets_channel_routing.find(newElm.cpId); - if (elmI == presets_channel_routing.end()) + if (lst.size() > 4) + { + newElm.linkIo = (lst[4] == "yes"); + } + } + + if (!err) + { + auto elmI = presets_io_routing.find(newElm.cpId); + if (elmI == presets_io_routing.end()) { - presets_channel_routing[newElm.cpId] = newElm; + presets_io_routing[newElm.cpId] = newElm; genMixChain::sources_channel_routing.last_error.value = jvxErrorType_txt(JVX_NO_ERROR); offset_channels_to_property(); } @@ -119,12 +136,12 @@ JVX_PROPERTIES_FORWARD_C_CALLBACK_EXECUTE_FULL(CjvxSpNMixChainEnterLeave, remove jvxSize idx = jvx_bitfieldSelection2Id(genMixChain::sources_channel_routing.all_definitions); if (JVX_CHECK_SIZE_SELECTED(idx)) { - if (idx < presets_channel_routing.size()) + if (idx < presets_io_routing.size()) { - auto itElm = presets_channel_routing.begin(); + auto itElm = presets_io_routing.begin(); std::advance(itElm, idx); - presets_channel_routing.erase(itElm); + presets_io_routing.erase(itElm); genMixChain::sources_channel_routing.last_error.value = jvxErrorType_txt(JVX_NO_ERROR); CjvxProperties::add_property_report_collect(genMixChain::sources_channel_routing.last_error.descriptor.std_str(), false); diff --git a/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSingleConnectorCommon.h b/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSingleConnectorCommon.h index 76959c8b..d25d2ca0 100644 --- a/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSingleConnectorCommon.h +++ b/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSingleConnectorCommon.h @@ -32,6 +32,7 @@ class CjvxConnector : public T1 jvxBool withTriggerConnector = false; jvxSize conId = 0; CjvxConnectorOffsetAndMaxChans chanSetting; + jvxBool linkageIoActive = false; // Physically the largest number of channels to be accepted jvxSize channelWidthMax = JVX_SIZE_UNSELECTED; diff --git a/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxSingleInputConnector.cpp b/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxSingleInputConnector.cpp index 67f1fcf0..1854f164 100644 --- a/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxSingleInputConnector.cpp +++ b/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxSingleInputConnector.cpp @@ -22,8 +22,12 @@ CjvxSingleInputTriggerConnector::latest_result_data() { if (bwdRef) { - jvxErrorType res = bwdRef->resLatestGetData; - bwdRef->resLatestGetData = JVX_ERROR_UNKNOWN; + jvxErrorType res = JVX_NO_ERROR; + if (bwdRef->linkageIoActive) + { + res = bwdRef->resLatestGetData; + bwdRef->resLatestGetData = JVX_ERROR_UNKNOWN; + } return res; } return JVX_ERROR_UNKNOWN;