From 20ccbea614f6ff4b85aae83421b268b2828c4fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hauke=20Kr=C3=BCger?= Date: Thu, 6 Jun 2024 10:55:57 +0200 Subject: [PATCH] Cleanup and clarification in signal chains for data i/o with synchronization --- cmake/macros.cmake | 39 +- .../jvxAuCPcm/src/CjvxAuCPcmDecoder.cpp | 2 +- .../jvxAuNConvert/src/CjvxAuNConvert.cpp | 4 +- .../codeGen/exports_node.pcg | 2 +- .../src/CjvxAuNForwardBuffer.cpp | 363 +++++++++++------- .../src/CjvxAuNForwardBuffer.h | 12 +- .../src/CjvxSpNMixChainEnterLeave.cpp | 8 +- .../src/CjvxSpNSynchronize_sec_process.cpp | 6 +- .../include/common/CjvxNegotiate.h | 8 +- .../include/common/CjvxSimplePropsPars.h | 4 +- .../include/common/CjvxSingleInputConnector.h | 4 + .../common/CjvxSingleOutputConnector.h | 2 + .../include/jvxNodes/CjvxBareNtask.h | 4 +- .../src/common/CjvxNegotiate.cpp | 256 ++++++------ .../src/common/CjvxSingleInputConnector.cpp | 20 + .../src/common/CjvxSingleOutputConnector.cpp | 14 + .../CjvxInputOutputConnector_NVtask.cpp | 4 +- .../include/common/CjvxInputConnectorCore.h | 2 +- .../include/common/CjvxOutputConnectorCore.h | 2 +- .../src/common/CjvxInputConnectorCore.cpp | 2 +- .../src/common/CjvxOutputConnectorCore.cpp | 2 +- .../src/HjvxDataLinkDescriptor.cpp | 12 +- .../include/interfaces/IjvxTriggerConnector.h | 1 + .../include/typedefs/TjvxLinkDataDescriptor.h | 2 +- .../include/jvx_system_dataformats.h | 11 +- .../jvxAuCFfmpeg/src/CjvxAuCFfmpegDecoder.cpp | 2 +- versions.txt | 5 + 27 files changed, 491 insertions(+), 302 deletions(-) diff --git a/cmake/macros.cmake b/cmake/macros.cmake index 68be61c3..3bd125ea 100644 --- a/cmake/macros.cmake +++ b/cmake/macros.cmake @@ -83,19 +83,40 @@ macro(jvx_genMatProperties targetname componenttype componentprefix localfilelis file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/m-files/+${targetname_tweaked}) foreach(PCGFILE ${localfilelist}) string(REPLACE ";" " " localoptionsstr "${localoptions}") + + # Example how to set localoptions + # set(localoptionsstr a b) + if(JVX_MAX_PATH_PROP_MAT) - set(localoptionsstr "${localoptionsstr} -maxl ${JVX_MAX_PATH_PROP_MAT}") + set(localoptionsstr ${localoptionsstr} -maxl ${JVX_MAX_PATH_PROP_MAT}) endif() - - message(" > PCG MAT Generator: ${PCGFILE} for component of type ${componenttype}, generator prefix ${componentprefix}, local options = ${localoptionsstr}") - # message("exec_program(\"${JVX_PCG_MATLAB} \\\"${PCGFILE}\\\" -o \\\"${CMAKE_CURRENT_BINARY_DIR}/m-files/+${targetname_tweaked}\\\" -ctp ${componenttype} -cpf ${componentprefix} ${localoptionsstr}\")") - # pcg_mat_opts "${localoptions}") - # message("--> 1 ${localoptions} 2") - # Added some quotes for systems with spaces in path - # install(CODE "exec_program(\"${JVX_PCG_MATLAB} \\\"${PCGFILE}\\\" -o \\\"${CMAKE_CURRENT_BINARY_DIR}/m-files/+${targetname_tweaked}\\\" -ctp ${componenttype} -cpf ${componentprefix} ${localoptionsstr}\")") - install(CODE "execute_process(COMMAND \"${JVX_PCG_MATLAB} \\\"${PCGFILE}\\\" -o \\\"${CMAKE_CURRENT_BINARY_DIR}/m-files/+${targetname_tweaked}\\\" -ctp ${componenttype} -cpf ${componentprefix} ${localoptionsstr}\")") + + string(REPLACE ";" " " localoptionsstr "${localoptionsstr}") + + message(" > PCG MAT Generator: ${PCGFILE} for component of type ${componenttype}, generator prefix ${componentprefix}, local options = ${localoptionsstr} to be installed in ${INSTALL_PATH_MATLAB_SUBPROJECT}/+${targetname_tweaked}") + + # This is the old version with exec_programm - which works. I was not able to transform this into a version + # a) with exec_process + # b) with additional arguments in localoptionsstr + # c) in an INSTALL clause. + # In all attempts, CMake has done weird stuff. The problem is that in exec_process, we need to pass all + # arguments separately. This could not be achieved in this combination of a-c. + install(CODE "exec_program(\"${JVX_PCG_MATLAB} \\\"${PCGFILE}\\\" -o \\\"${CMAKE_CURRENT_BINARY_DIR}/m-files/+${targetname_tweaked}\\\" -ctp ${componenttype} -cpf ${componentprefix} ${localoptionsstr}\")") + + # Here is my last attempt - which is close but not really functional + #install(CODE "string(REPLACE \";\" \" \" localoptionsstri \"${localoptionsstr}\") + # execute_process(COMMAND \"${JVX_PCG_MATLAB}\" \"${PCGFILE}\" \"-o\" \"${CMAKE_CURRENT_BINARY_DIR}/m-files/+${targetname_tweaked}\" \"-ctp\" \"${componenttype}\" \$\{localoptionsstri\} + # COMMAND_ECHO STDOUT RESULT_VARIABLE status)") + + # The following command works but only if not in INSTALL clause!! + #execute_process(COMMAND "${JVX_PCG_MATLAB}" "${PCGFILE}" "-o" "${CMAKE_CURRENT_BINARY_DIR}/m-files/+${targetname_tweaked}" "-ctp" "${componenttype}" ${localoptionsstr} + # COMMAND_ECHO STDOUT RESULT_VARIABLE status) + + endforeach() install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/m-files/+${targetname_tweaked} DESTINATION ${INSTALL_PATH_MATLAB_SUBPROJECT}) + # message(FATAL_ERROR "Hier") + endif() endmacro(jvx_genMatProperties) diff --git a/sources/jvxComponents/jvxAudioCodecs/jvxAuCPcm/src/CjvxAuCPcmDecoder.cpp b/sources/jvxComponents/jvxAudioCodecs/jvxAuCPcm/src/CjvxAuCPcmDecoder.cpp index 9765d34a..59815366 100644 --- a/sources/jvxComponents/jvxAudioCodecs/jvxAuCPcm/src/CjvxAuCPcmDecoder.cpp +++ b/sources/jvxComponents/jvxAudioCodecs/jvxAuCPcm/src/CjvxAuCPcmDecoder.cpp @@ -368,7 +368,7 @@ CjvxAuCPcmDecoder::set_configure_token(const char* tokenArg) JVX_SIZE_DONTCARE, JVX_DATAFORMAT_BYTE, JVX_DATAFORMAT_GROUP_AUDIO_CODED_GENERIC, - JVX_DATAFLOW_NONE, + JVX_DATAFLOW_DONT_CARE, JVX_SIZE_UNSELECTED, 1); // <- number_channels and segment are different arguments here neg_output._set_parameters_fixed( diff --git a/sources/jvxComponents/jvxAudioNodes/jvxAuNConvert/src/CjvxAuNConvert.cpp b/sources/jvxComponents/jvxAudioNodes/jvxAuNConvert/src/CjvxAuNConvert.cpp index ce81175b..0036bb5f 100644 --- a/sources/jvxComponents/jvxAudioNodes/jvxAuNConvert/src/CjvxAuNConvert.cpp +++ b/sources/jvxComponents/jvxAudioNodes/jvxAuNConvert/src/CjvxAuNConvert.cpp @@ -233,9 +233,7 @@ CjvxAuNConvert::accept_negotiate_output(jvxLinkDataTransferType tp, jvxLinkDataD update_output_params_from_input_params(); adapt_output_parameters_forward(); test_set_output_parameters(); - - // This I need to find an example for - assert(0); + break; case JVX_ERROR_COMPROMISE: diff --git a/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/codeGen/exports_node.pcg b/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/codeGen/exports_node.pcg index 3c1741fb..f714e73f 100644 --- a/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/codeGen/exports_node.pcg +++ b/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/codeGen/exports_node.pcg @@ -39,7 +39,7 @@ SECTION PROPERTIES SELECTION_LIST_SELECTED = {"yes", "no"}; SELECTION_LIST_EXCLUSIVE = {"no", "no"}; SELECTION_TRANSLATOR_TYPE = "jvxOperationMode"; - SELECTION_LIST_TRANSLATORS = {"JVX_FORWARDBUFFER_BUFFER_INPUT", "JVX_FORWARDBUFFER_BUFFER_OUTPUT_ACTIVE", "JVX_FORWARDBUFFER_BUFFER_OUTPUT_PASSIVE"}; + SELECTION_LIST_TRANSLATORS = {"JVX_FORWARDBUFFER_BUFFER_INPUT", "JVX_FORWARDBUFFER_BUFFER_OUTPUT"}; SELECTION_TRANSLATOR_ENUM_CLASS = "yes"; READ_WRITE_ACCESS = "JVX_PROPERTY_ACCESS_READ_AND_WRITE_CONTENT"; CONTENT_DECODER_TYPE = "JVX_PROPERTY_DECODER_SINGLE_SELECTION"; diff --git a/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/src/CjvxAuNForwardBuffer.cpp b/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/src/CjvxAuNForwardBuffer.cpp index acc381d4..252c0cd2 100644 --- a/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/src/CjvxAuNForwardBuffer.cpp +++ b/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/src/CjvxAuNForwardBuffer.cpp @@ -166,6 +166,10 @@ CjvxAuNForwardBuffer::test_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb)) genForwardBuffer_node::associate__convert(static_cast(this), reRouting.selChannels, reRouting.numChannels); } } + + // Store the dataflow argument + dataFlowOperation_output = _common_set_ocon.theData_out.con_params.data_flow; + dataFlowOperation_input = _common_set_icon.theData_in->con_params.data_flow; } return res; } @@ -199,6 +203,26 @@ CjvxAuNForwardBuffer::from_input_to_output() node_output._common_set_node_params_a_1io.segmentation.x = node_inout._common_set_node_params_a_1io.segmentation.x; } + switch (buffermode) + { + case jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_INPUT: + + // Always involve PUSH_ON_PULL on output side in case of an input buffer + if (node_output._common_set_node_params_a_1io.data_flow == JVX_DATAFLOW_DONT_CARE) + { + node_output._common_set_node_params_a_1io.data_flow = JVX_DATAFLOW_PUSH_ON_PULL; + } + break; + case jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_OUTPUT: + + if (node_output._common_set_node_params_a_1io.data_flow == JVX_DATAFLOW_DONT_CARE) + { + node_output._common_set_node_params_a_1io.data_flow = JVX_DATAFLOW_PUSH_ASYNC; + } + break; + default: + break; + } update_output_params(); } @@ -299,18 +323,12 @@ CjvxAuNForwardBuffer::prepare_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb)) jvx_bitClear(_common_set_ocon.theData_out.con_data.alloc_flags, (jvxSize)jvxDataLinkDescriptorAllocFlags::JVX_LINKDATA_ALLOCATION_FLAGS_EXPECT_FHEIGHT_INFO_SHIFT); break; - case jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_OUTPUT_ACTIVE: + case jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_OUTPUT: // Output format // Variable segment sizes are possible jvx_bitSet(_common_set_ocon.theData_out.con_data.alloc_flags, (jvxSize)jvxDataLinkDescriptorAllocFlags::JVX_LINKDATA_ALLOCATION_FLAGS_ALLOW_FHEIGHT_INFO_SHIFT); - break; - case jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_OUTPUT_PASSIVE: - // Output format - // Variable segment sizes are possible - jvx_bitSet(_common_set_ocon.theData_out.con_data.alloc_flags, - (jvxSize)jvxDataLinkDescriptorAllocFlags::JVX_LINKDATA_ALLOCATION_FLAGS_ALLOW_FHEIGHT_INFO_SHIFT); - break; + break; } _common_set_ocon.theData_out.con_pipeline.num_additional_pipleline_stages = 0; @@ -346,7 +364,7 @@ CjvxAuNForwardBuffer::prepare_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb)) switch (buffermode) { - case jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_OUTPUT_ACTIVE: + case jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_OUTPUT: // Clear this bit jvx_bitClear(_common_set_ocon.theData_out.con_data.alloc_flags, @@ -404,6 +422,7 @@ CjvxAuNForwardBuffer::prepare_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb)) res = JVX_ERROR_WRONG_STATE; } } + return res; } @@ -649,13 +668,16 @@ CjvxAuNForwardBuffer::process_buffers_icon(jvxSize mt_mask, jvxSize idx_stage) // If we are in OUTPUT_BUFFER MODE we will trigger the output thread. The clock in this case is on the // input side. When the thread is awake it check if it can deliver enough audio samples and acts only if so. // Check function - if (buffermode == jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_OUTPUT_ACTIVE) + if (buffermode == jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_OUTPUT) { - if ( - (res == JVX_NO_ERROR) || - (res == JVX_ERROR_BUFFER_OVERFLOW)) + if (_common_set_ocon.theData_out.con_params.data_flow == JVX_DATAFLOW_PUSH_ASYNC) { - refThreads.cpPtr->trigger_wakeup(); + if ( + (res == JVX_NO_ERROR) || + (res == JVX_ERROR_BUFFER_OVERFLOW)) + { + refThreads.cpPtr->trigger_wakeup(); + } } } @@ -725,79 +747,26 @@ CjvxAuNForwardBuffer::transfer_backward_ocon(jvxLinkDataTransferType tp, jvxHand } else { - if (buffermode == jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_INPUT) + switch (buffermode) { + case jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_INPUT: + if (_common_set_ocon.theData_out.con_link.connect_to) { - res = _common_set_ocon.theData_out.con_link.connect_to->process_start_icon(); - if (res == JVX_NO_ERROR) - { - // We may limit the number of samples to a lower value - jvxSize numSamplesRequest = _common_set_ocon.theData_out.con_params.buffersize; - if (data != nullptr) - { - jvxSize* overrideNum = (jvxSize*)data; - numSamplesRequest = JVX_MIN(numSamplesRequest, *overrideNum); - } - - assert(node_output._common_set_node_params_a_1io.number_channels == - _common_set_ocon.theData_out.con_params.number_channels); - assert(node_output._common_set_node_params_a_1io.buffersize == - _common_set_ocon.theData_out.con_params.buffersize); - - // Get new audio data here - jvxData** bufsOut = jvx_process_icon_extract_output_buffers(_common_set_ocon.theData_out); - jvxSize fHeight = 0; - jvxErrorType resL = jvx_audio_stack_sample_dispenser_cont_internal_copy( - &myAudioDispenser, - (jvxHandle**)bufsOut, 0, - nullptr, 0, numSamplesRequest, 0, nullptr, NULL, NULL, NULL); - - // This call returns: - // 1) JVX_DSP_ERROR_ABORT if the buffer was not yet accessed on the input side - // 2) JVX_DSP_ERROR_BUFFER_OVERFLOW if the buffer has been accessed on the input side but there are not enough samples in the buffer - // 3) JVX_DSP_NO_ERROR if samples were read from the buffer - switch (resL) - { - case JVX_DSP_NO_ERROR: - jvx_audio_stack_sample_dispenser_buffer_status( - &myAudioDispenser, - &fHeight, nullptr); - if (fHeight < myAudioDispenser.start_threshold) - { - refThreads.cpPtr->trigger_wakeup(); - } - - res = JVX_NO_ERROR; - 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++; - - [[fallthrough]]; - - case JVX_DSP_ERROR_ABORT: - - - // No output from buffer, copy silence - for (i = 0; i < _common_set_ocon.theData_out.con_params.number_channels; i++) - { - memset(bufsOut[i], 0, (_common_set_ocon.theData_out.con_params.buffersize * jvxDataFormat_size[_common_set_ocon.theData_out.con_params.format])); - } - - // If the sample buffer does not deliver we need to wakeup the thread!! - refThreads.cpPtr->trigger_wakeup(); - res = JVX_NO_ERROR; - break; - - default: - break; - } - - _common_set_ocon.theData_out.con_link.connect_to->process_buffers_icon(); - _common_set_ocon.theData_out.con_link.connect_to->process_stop_icon(); - } + res = push_on_pull_one_buffer(data, true, (dataFlowOperation_input == JVX_DATAFLOW_PUSH_ON_PULL)); + } + break; + case jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_OUTPUT: + if (dataFlowOperation_output == JVX_DATAFLOW_PUSH_ON_PULL) + { + // Immediate write + res = push_on_pull_one_buffer(data, false, false); } + + // else: this call should not occur in case of a JVX_DATAFLOW_PUSH_ASYNC or JVX_DATAFLOW_PUSH + break; + default: + break; } } break; @@ -807,12 +776,102 @@ CjvxAuNForwardBuffer::transfer_backward_ocon(jvxLinkDataTransferType tp, jvxHand return res; } +jvxErrorType +CjvxAuNForwardBuffer::push_on_pull_one_buffer(jvxHandle* data, jvxBool runStartStop, jvxBool awakeThreadInputSide) +{ + jvxSize i; + jvxErrorType res = JVX_NO_ERROR; + if (runStartStop) + { + res = _common_set_ocon.theData_out.con_link.connect_to->process_start_icon(); + } + + if (res == JVX_NO_ERROR) + { + // We may limit the number of samples to a lower value + jvxSize numSamplesRequest = _common_set_ocon.theData_out.con_params.buffersize; + if (data != nullptr) + { + jvxSize* overrideNum = (jvxSize*)data; + numSamplesRequest = JVX_MIN(numSamplesRequest, *overrideNum); + } + + assert(node_output._common_set_node_params_a_1io.number_channels == + _common_set_ocon.theData_out.con_params.number_channels); + assert(node_output._common_set_node_params_a_1io.buffersize == + _common_set_ocon.theData_out.con_params.buffersize); + + // Get new audio data here + jvxData** bufsOut = jvx_process_icon_extract_output_buffers(_common_set_ocon.theData_out); + jvxSize fHeight = 0; + jvxErrorType resL = jvx_audio_stack_sample_dispenser_cont_internal_copy( + &myAudioDispenser, + (jvxHandle**)bufsOut, 0, + nullptr, 0, numSamplesRequest, 0, nullptr, NULL, NULL, NULL); + + // This call returns: + // 1) JVX_DSP_ERROR_ABORT if the buffer was not yet accessed on the input side + // 2) JVX_DSP_ERROR_BUFFER_OVERFLOW if the buffer has been accessed on the input side but there are not enough samples in the buffer + // 3) JVX_DSP_NO_ERROR if samples were read from the buffer + switch (resL) + { + case JVX_DSP_NO_ERROR: + if (awakeThreadInputSide) + { + jvx_audio_stack_sample_dispenser_buffer_status( + &myAudioDispenser, + &fHeight, nullptr); + if (fHeight < myAudioDispenser.start_threshold) + { + refThreads.cpPtr->trigger_wakeup(); + } + } + res = JVX_NO_ERROR; + 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++; + + [[fallthrough]]; + + case JVX_DSP_ERROR_ABORT: + + + // No output from buffer, copy silence + for (i = 0; i < _common_set_ocon.theData_out.con_params.number_channels; i++) + { + memset(bufsOut[i], 0, (_common_set_ocon.theData_out.con_params.buffersize * jvxDataFormat_size[_common_set_ocon.theData_out.con_params.format])); + } + + if (awakeThreadInputSide) + { + // If the sample buffer does not deliver we need to wakeup the thread!! + refThreads.cpPtr->trigger_wakeup(); + } + res = JVX_NO_ERROR; + break; + + default: + break; + } + + _common_set_ocon.theData_out.con_link.connect_to->process_buffers_icon(); + + if (runStartStop) + { + _common_set_ocon.theData_out.con_link.connect_to->process_stop_icon(); + } + } + return res; +} + jvxErrorType CjvxAuNForwardBuffer::accept_negotiate_output(jvxLinkDataTransferType tp, jvxLinkDataDescriptor* preferredByOutput JVX_CONNECTION_FEEDBACK_TYPE_A(fdb)) { jvxErrorType res = JVX_ERROR_UNSUPPORTED; jvxCBitField checkFlags = 0; jvxLinkDataDescriptor ld_try; + jvxBool updateOut = false; switch(buffermode) { @@ -941,23 +1000,48 @@ CjvxAuNForwardBuffer::accept_negotiate_output(jvxLinkDataTransferType tp, jvxLin } break; - case jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_OUTPUT_ACTIVE: - if (node_output._common_set_node_params_a_1io.buffersize != preferredByOutput->con_params.buffersize) + case jvxOperationMode::JVX_FORWARDBUFFER_BUFFER_OUTPUT: + + // Only option to negotiate: buffersize + jvxCBitField checkFlags = 0; + jvx_bitSet(checkFlags, (jvxCBitField)jvxAddressLinkDataEntry::JVX_ADDRESS_BUFFERSIZE_SHIFT); + jvx_bitSet(checkFlags, (jvxCBitField)jvxAddressLinkDataEntry::JVX_ADDRESS_SEGX_SHIFT); + jvx_bitSet(checkFlags, (jvxCBitField)jvxAddressLinkDataEntry::JVX_ADDRESS_DATAFLOW_SHIFT); + jvx_bitInvert(checkFlags); + + // Check if switching dataflow and buffersize may help! + if (!jvx_evalBool(jvx_check_differences(_common_set_icon.theData_in->con_params, + preferredByOutput->con_params, checkFlags))) { - res = JVX_ERROR_UNSUPPORTED; + bool noError = true; - // Only option to negotiate: buffersize - jvxCBitField checkFlags = 0; - jvx_bitSet(checkFlags, (jvxCBitField)jvxAddressLinkDataEntry::JVX_ADDRESS_BUFFERSIZE_SHIFT); - jvx_bitSet(checkFlags, (jvxCBitField)jvxAddressLinkDataEntry::JVX_ADDRESS_SEGX_SHIFT); - jvx_bitSet(checkFlags, (jvxCBitField)jvxAddressLinkDataEntry::JVX_ADDRESS_DATAFLOW_SHIFT); - jvx_bitInvert(checkFlags); + if (noError) + { + // To change the dataflow type is well possible!! + if (node_output._common_set_node_params_a_1io.data_flow != preferredByOutput->con_params.data_flow) + { + switch (preferredByOutput->con_params.data_flow) + { + case JVX_DATAFLOW_PUSH_ON_PULL: + case JVX_DATAFLOW_PUSH_ASYNC: + node_output._common_set_node_params_a_1io.data_flow = preferredByOutput->con_params.data_flow; + break; + default: + noError = false; + } + } + } - // Check if from the previous component only the samplerate or the number of channels deviate - if (!jvx_evalBool(jvx_check_differences(_common_set_icon.theData_in->con_params, - preferredByOutput->con_params, checkFlags))) + if (noError) + { + if (node_output._common_set_node_params_a_1io.buffersize != preferredByOutput->con_params.buffersize) + { + node_output._common_set_node_params_a_1io.buffersize = preferredByOutput->con_params.buffersize; + } + } + + if (noError) { - node_output._common_set_node_params_a_1io.buffersize = preferredByOutput->con_params.buffersize; test_set_output_parameters(); res = JVX_NO_ERROR; } @@ -1115,56 +1199,69 @@ CjvxAuNForwardBuffer::read_samples_to_buffer() } void -CjvxAuNForwardBuffer::write_samples_to_output() +CjvxAuNForwardBuffer::write_samples_to_output(jvxBool runStartStopBuffer) { if (_common_set_ocon.theData_out.con_link.connect_to) { - while(1) + jvxErrorType res = JVX_NO_ERROR; + while(res == JVX_NO_ERROR) { - jvxSize fHeight = 0; - jvx_audio_stack_sample_dispenser_buffer_status( - &myAudioDispenser, - &fHeight, nullptr); - if (fHeight >= _common_set_ocon.theData_out.con_params.buffersize) - { - jvxErrorType res = _common_set_ocon.theData_out.con_link.connect_to->process_start_icon(); - if (res == JVX_NO_ERROR) - { - // Get new audio data here - jvxData** bufsOut = jvx_process_icon_extract_output_buffers(_common_set_ocon.theData_out); - jvxSize numRead = _common_set_ocon.theData_out.con_params.buffersize; - jvxSize idxStage = *_common_set_ocon.theData_out.con_pipeline.idx_stage_ptr; - - if (_common_set_ocon.theData_out.con_data.fHeights) - { - if (JVX_CHECK_SIZE_SELECTED(_common_set_ocon.theData_out.con_data.fHeights[idxStage].x)) - { - numRead = JVX_MIN(numRead, _common_set_ocon.theData_out.con_data.fHeights[idxStage].x); - } - } - assert(node_output._common_set_node_params_a_1io.buffersize == - _common_set_ocon.theData_out.con_params.buffersize); + res = write_samples_to_output_one_buf(runStartStopBuffer); + } + } +} - jvxErrorType resL = jvx_audio_stack_sample_dispenser_cont_internal_copy( - &myAudioDispenser, - (jvxHandle**)bufsOut, 0, - nullptr, 0, numRead, 0, nullptr, NULL, NULL, NULL); - assert(resL == JVX_NO_ERROR); +jvxErrorType +CjvxAuNForwardBuffer::write_samples_to_output_one_buf(jvxBool runStartStopBuffer) +{ + jvxErrorType res = JVX_ERROR_NOT_ENOUGH_INPUT_DATA; + jvxSize fHeight = 0; + jvx_audio_stack_sample_dispenser_buffer_status( + &myAudioDispenser, + &fHeight, nullptr); + if (fHeight >= _common_set_ocon.theData_out.con_params.buffersize) + { + res = JVX_NO_ERROR; + if (runStartStopBuffer) + { + _common_set_ocon.theData_out.con_link.connect_to->process_start_icon(); + } + if (res == JVX_NO_ERROR) + { + // Get new audio data here + jvxData** bufsOut = jvx_process_icon_extract_output_buffers(_common_set_ocon.theData_out); + jvxSize numRead = _common_set_ocon.theData_out.con_params.buffersize; + jvxSize idxStage = *_common_set_ocon.theData_out.con_pipeline.idx_stage_ptr; - _common_set_ocon.theData_out.con_link.connect_to->process_buffers_icon(); - _common_set_ocon.theData_out.con_link.connect_to->process_stop_icon(); - } - else + if (_common_set_ocon.theData_out.con_data.fHeights) + { + if (JVX_CHECK_SIZE_SELECTED(_common_set_ocon.theData_out.con_data.fHeights[idxStage].x)) { - break; + numRead = JVX_MIN(numRead, _common_set_ocon.theData_out.con_data.fHeights[idxStage].x); } } - else + assert(node_output._common_set_node_params_a_1io.buffersize == + _common_set_ocon.theData_out.con_params.buffersize); + + jvxErrorType resL = jvx_audio_stack_sample_dispenser_cont_internal_copy( + &myAudioDispenser, + (jvxHandle**)bufsOut, 0, + nullptr, 0, numRead, 0, nullptr, NULL, NULL, NULL); + assert(resL == JVX_NO_ERROR); + + _common_set_ocon.theData_out.con_link.connect_to->process_buffers_icon(); + + if (runStartStopBuffer) { - break; + _common_set_ocon.theData_out.con_link.connect_to->process_stop_icon(); } } + else + { + res = JVX_ERROR_NOT_READY; + } } + return res; } void diff --git a/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/src/CjvxAuNForwardBuffer.h b/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/src/CjvxAuNForwardBuffer.h index 16abcc2e..1b3b2607 100644 --- a/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/src/CjvxAuNForwardBuffer.h +++ b/sources/jvxComponents/jvxAudioNodes/jvxAuNForwardBuffer/src/CjvxAuNForwardBuffer.h @@ -7,8 +7,7 @@ enum class jvxOperationMode { JVX_FORWARDBUFFER_BUFFER_INPUT, - JVX_FORWARDBUFFER_BUFFER_OUTPUT_ACTIVE, - JVX_FORWARDBUFFER_BUFFER_OUTPUT_PASSIVE + JVX_FORWARDBUFFER_BUFFER_OUTPUT }; #include "pcg_exports_node.h" @@ -101,6 +100,9 @@ class CjvxAuNForwardBuffer: public CjvxBareNode1ioRearrange, jvxBool runInitInThread = false; + jvxDataflow dataFlowOperation_output = JVX_DATAFLOW_DONT_CARE; + jvxDataflow dataFlowOperation_input = JVX_DATAFLOW_DONT_CARE; + public: JVX_CALLINGCONVENTION CjvxAuNForwardBuffer(JVX_CONSTRUCTOR_ARGUMENTS_MACRO_DECLARE); @@ -159,8 +161,12 @@ class CjvxAuNForwardBuffer: public CjvxBareNode1ioRearrange, virtual jvxErrorType JVX_CALLINGCONVENTION expired(jvxInt64 timestamp_us, jvxSize* delta_ms) override; virtual jvxErrorType JVX_CALLINGCONVENTION wokeup(jvxInt64 timestamp_us, jvxSize* delta_ms) override; virtual jvxErrorType JVX_CALLINGCONVENTION stopped(jvxInt64 timestamp_us) override; + + jvxErrorType push_on_pull_one_buffer(jvxHandle* data, jvxBool runStartStop, jvxBool awakeThreadInputSide); + void read_samples_to_buffer(); - void write_samples_to_output(); + void write_samples_to_output(jvxBool runStartStopBuffer = true); + jvxErrorType write_samples_to_output_one_buf(jvxBool runStartStopBuffer); virtual jvxErrorType JVX_CALLINGCONVENTION request_hidden_interface(jvxInterfaceType tp, jvxHandle** hdl)override; virtual jvxErrorType JVX_CALLINGCONVENTION return_hidden_interface(jvxInterfaceType tp, jvxHandle* hdl)override; diff --git a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave.cpp b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave.cpp index f131cf34..d7cc687f 100644 --- a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave.cpp +++ b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNMixChainEnterLeave/src/CjvxSpNMixChainEnterLeave.cpp @@ -459,7 +459,7 @@ CjvxSpNMixChainEnterLeave::process_buffers_icon(jvxSize mt_mask, jvxSize idx_sta lock(); for (auto& elm : CjvxConnectorCollection::processingConnectors) { - elm.second.ioconn->trigger_get_data(); + elm.second.ioconn->setLatestResultGetData(elm.second.ioconn->trigger_get_data()); } unlock(); break; @@ -473,7 +473,11 @@ CjvxSpNMixChainEnterLeave::process_buffers_icon(jvxSize mt_mask, jvxSize idx_sta lock(); for (auto& elm : CjvxConnectorCollection::processingConnectors) { - elm.second.ioconn->trigger_put_data(); + jvxErrorType resOther = elm.second.ioconn->resultFromInputConnector(); + if( + (resOther == JVX_ERROR_UNKNOWN) || + resOther == JVX_NO_ERROR) + elm.second.ioconn->trigger_put_data(); } unlock(); break; diff --git a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNSynchronize/src/CjvxSpNSynchronize_sec_process.cpp b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNSynchronize/src/CjvxSpNSynchronize_sec_process.cpp index a48b6795..7228ab2a 100644 --- a/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNSynchronize/src/CjvxSpNSynchronize_sec_process.cpp +++ b/sources/jvxComponents/jvxSignalProcessingNodes/jvxSpNSynchronize/src/CjvxSpNSynchronize_sec_process.cpp @@ -563,11 +563,11 @@ CjvxSpNSynchronize_sec::trigger_process_immediate(jvxLinkDataDescriptor* datIn, // Request data from output side of secondary chain if (referencePtr->bufferMode == jvxSynchronizeBufferMode::JVX_SYNCHRONIZE_UNBUFFERED_PULL) { - if (datOut) + if (_common_set_icon.theData_in) { - if (datOut->con_link.connect_from) + if (_common_set_icon.theData_in->con_link.connect_from) { - datOut->con_link.connect_from->transfer_backward_ocon(jvxLinkDataTransferType::JVX_LINKDATA_TRANSFER_REQUEST_DATA, nullptr JVX_CONNECTION_FEEDBACK_CALL_A_NULL); + _common_set_icon.theData_in->con_link.connect_from->transfer_backward_ocon(jvxLinkDataTransferType::JVX_LINKDATA_TRANSFER_REQUEST_DATA, nullptr JVX_CONNECTION_FEEDBACK_CALL_A_NULL); } } } diff --git a/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxNegotiate.h b/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxNegotiate.h index f8b0270d..0c89b21d 100644 --- a/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxNegotiate.h +++ b/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxNegotiate.h @@ -93,8 +93,8 @@ class CjvxNegotiate_common dimY.min = JVX_SIZE_UNSELECTED; dimY.max = JVX_SIZE_UNSELECTED; - data_flow.min = jvxDataflow::JVX_DATAFLOW_NONE; - data_flow.max = jvxDataflow::JVX_DATAFLOW_NONE; + data_flow.min = jvxDataflow::JVX_DATAFLOW_DONT_CARE; + data_flow.max = jvxDataflow::JVX_DATAFLOW_DONT_CARE; }; } ; public: @@ -126,7 +126,7 @@ class CjvxNegotiate_common jvxSize srate = 48000, jvxDataFormat format = JVX_DATAFORMAT_DATA, jvxDataFormatGroup sub_format = JVX_DATAFORMAT_GROUP_AUDIO_PCM_DEINTERLEAVED, - jvxDataflow datflow = jvxDataflow::JVX_DATAFLOW_NONE, + jvxDataflow datflow = jvxDataflow::JVX_DATAFLOW_DONT_CARE, jvxSize segment_x = JVX_SIZE_UNSELECTED, jvxSize segment_y = JVX_SIZE_UNSELECTED); @@ -139,7 +139,7 @@ class CjvxNegotiate_common jvxSize srate = JVX_SIZE_UNSELECTED, jvxDataFormat format = JVX_DATAFORMAT_NONE, jvxDataFormatGroup sub_format = JVX_DATAFORMAT_GROUP_NONE, - jvxDataflow dflow = jvxDataflow::JVX_DATAFLOW_NONE, + jvxDataflow dflow = jvxDataflow::JVX_DATAFLOW_DONT_CARE, jvxLinkDataDescriptor* datOut = NULL, jvxSize segment_x = JVX_SIZE_UNSELECTED, jvxSize segment_y = JVX_SIZE_UNSELECTED); diff --git a/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSimplePropsPars.h b/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSimplePropsPars.h index 54360c7c..ec9da147 100644 --- a/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSimplePropsPars.h +++ b/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSimplePropsPars.h @@ -17,7 +17,7 @@ class CjvxSimplePropsPars : public CjvxNodeAss_genpcg jvxInt32 samplerate = JVX_SIZE_UNSELECTED_INT32; jvxInt16 format = JVX_DATAFORMAT_NONE; jvxInt16 subformat = JVX_DATAFORMAT_GROUP_NONE; - jvxInt16 data_flow = jvxDataflow::JVX_DATAFLOW_NONE; + jvxInt16 data_flow = jvxDataflow::JVX_DATAFLOW_DONT_CARE; std::string format_spec; struct { @@ -32,7 +32,7 @@ class CjvxSimplePropsPars : public CjvxNodeAss_genpcg samplerate = JVX_SIZE_UNSELECTED_INT32; format = JVX_DATAFORMAT_NONE; subformat = JVX_DATAFORMAT_GROUP_NONE; - data_flow = jvxDataflow::JVX_DATAFLOW_NONE; + data_flow = jvxDataflow::JVX_DATAFLOW_DONT_CARE; segmentation.x = JVX_SIZE_UNSELECTED_INT32; segmentation.y = JVX_SIZE_UNSELECTED_INT32; format_spec.clear(); diff --git a/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSingleInputConnector.h b/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSingleInputConnector.h index a2dded9e..4f064e1f 100644 --- a/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSingleInputConnector.h +++ b/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSingleInputConnector.h @@ -17,6 +17,7 @@ class CjvxSingleInputTriggerConnector : public CjvxSingleTriggerConnector @@ -27,6 +28,7 @@ class CjvxSingleInputConnector: public IjvxInputConnector, public CjvxConnector< CjvxSingleConnector_report* report = nullptr; CjvxNegotiate_input neg_input; + jvxErrorType resLatestGetData = JVX_ERROR_UNKNOWN; public: CjvxSingleInputConnector(jvxBool withTriggerConnectorArg); @@ -63,6 +65,8 @@ class CjvxSingleInputConnector: public IjvxInputConnector, public CjvxConnector< virtual jvxErrorType request_trigger_otcon(IjvxTriggerOutputConnector** otcon) override; virtual jvxErrorType return_trigger_otcon(IjvxTriggerOutputConnector* otcon) override; + void setLatestResultGetData(jvxErrorType resLatestGetData); + // ======================================================================================= #define JVX_INPUT_OUTPUT_CONNECTOR_SUPPRESS_AUTOSTART diff --git a/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSingleOutputConnector.h b/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSingleOutputConnector.h index 372e4074..0166f42c 100644 --- a/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSingleOutputConnector.h +++ b/sources/jvxLibraries/jvx-component-templates-base/include/common/CjvxSingleOutputConnector.h @@ -53,6 +53,8 @@ class CjvxSingleOutputConnector : public IjvxOutputConnector, public IjvxConnect jvxErrorType available_to_connect_ocon() override; + jvxErrorType resultFromInputConnector(); + #define JVX_INPUT_OUTPUT_CONNECTOR_SUPPRESS_AUTOSTART #define JVX_CONNECTOR_NOT_DERIVED_FROM_OBJECT #define JVX_INPUTOUTPUT_CONNECTOR_OBJECT_REFERENCE nullptr diff --git a/sources/jvxLibraries/jvx-component-templates-base/include/jvxNodes/CjvxBareNtask.h b/sources/jvxLibraries/jvx-component-templates-base/include/jvxNodes/CjvxBareNtask.h index 96321cad..b4cecf3f 100644 --- a/sources/jvxLibraries/jvx-component-templates-base/include/jvxNodes/CjvxBareNtask.h +++ b/sources/jvxLibraries/jvx-component-templates-base/include/jvxNodes/CjvxBareNtask.h @@ -66,14 +66,14 @@ class CjvxBareNtask : public CjvxNodeBaseNtask, public IjvxInputOutputConnectorN jvxSize rate = JVX_SIZE_UNSELECTED; jvxDataFormat format = JVX_DATAFORMAT_NONE; jvxDataFormatGroup format_group = JVX_DATAFORMAT_GROUP_NONE; - jvxDataflow data_flow = JVX_DATAFLOW_NONE; + jvxDataflow data_flow = JVX_DATAFLOW_DONT_CARE; void clear() { bsize = JVX_SIZE_UNSELECTED; rate = JVX_SIZE_UNSELECTED; format = JVX_DATAFORMAT_NONE; format_group = JVX_DATAFORMAT_GROUP_NONE; - data_flow = JVX_DATAFLOW_NONE; + data_flow = JVX_DATAFLOW_DONT_CARE; }; }; diff --git a/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxNegotiate.cpp b/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxNegotiate.cpp index 4127b05f..059ecd15 100644 --- a/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxNegotiate.cpp +++ b/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxNegotiate.cpp @@ -229,7 +229,7 @@ CjvxNegotiate_common::_update_parameters_fixed( datOut->con_params.format_group = sub_format; } - if (datflow != jvxDataflow::JVX_DATAFLOW_NONE) + if (datflow != jvxDataflow::JVX_DATAFLOW_DONT_CARE) { SET_OTHER(res, preferred, data_flow, datflow); if (datOut) @@ -301,7 +301,7 @@ CjvxNegotiate_common::_clear_parameters_fixed( } if (datflow) { - SET_OTHER(res, preferred, data_flow, jvxDataflow::JVX_DATAFLOW_NONE); + SET_OTHER(res, preferred, data_flow, jvxDataflow::JVX_DATAFLOW_DONT_CARE); } return res; @@ -322,7 +322,7 @@ CjvxNegotiate_common::derive(jvxLinkDataDescriptor_con_params* params) SET_DEFAULT_PARAM_ENUM(params, preferred, format, format, JVX_DATAFORMAT_NONE, JVX_DATAFORMAT_DATA); SET_DEFAULT_PARAM_ENUM(params, preferred, format_group, subformat, JVX_DATAFORMAT_GROUP_NONE, JVX_DATAFORMAT_GROUP_AUDIO_PCM_INTERLEAVED); - SET_DEFAULT_PARAM_ENUM(params, preferred, data_flow, data_flow, jvxDataflow::JVX_DATAFLOW_NONE, + SET_DEFAULT_PARAM_ENUM(params, preferred, data_flow, data_flow, jvxDataflow::JVX_DATAFLOW_DONT_CARE, jvxDataflow::JVX_DATAFLOW_PUSH_ACTIVE); return JVX_NO_ERROR; } @@ -502,218 +502,226 @@ CjvxNegotiate_common::compare_core(jvxLinkDataDescriptor* ld_cp, jvxLinkDataDesc { thereismismatch = false; + // In the first part, check the data connection main topics. + // ================================================================================ - // Number output channels - // ================================================================================ - if (JVX_CHECK_SIZE_SELECTED(preferred.number_channels.min)) - { - if (ld_cp->con_params.number_channels < preferred.number_channels.min) - { - thereismismatch = true; - if (ld_fix) - { - ld_fix->con_params.number_channels = preferred.number_channels.min; - } - } - } - if (JVX_CHECK_SIZE_SELECTED(preferred.number_channels.max)) - { - if (ld_cp->con_params.number_channels > preferred.number_channels.max) - { - thereismismatch = true; - if(ld_fix) - { - ld_fix->con_params.number_channels = preferred.number_channels.max; - } - } - } - - // ================================================================================ - // Buffersize + // Dataflow // ================================================================================ - if (JVX_CHECK_SIZE_SELECTED(preferred.buffersize.min)) + if (preferred.data_flow.min != jvxDataflow::JVX_DATAFLOW_DONT_CARE) { - if (ld_cp->con_params.buffersize < preferred.buffersize.min) + if (ld_cp->con_params.data_flow < preferred.data_flow.min) { thereismismatch = true; - if(ld_fix) + if (ld_fix) { - ld_fix->con_params.buffersize = preferred.buffersize.min; + ld_fix->con_params.data_flow = preferred.data_flow.min; } } } - if (JVX_CHECK_SIZE_SELECTED(preferred.buffersize.max)) + if (preferred.data_flow.max != jvxDataflow::JVX_DATAFLOW_DONT_CARE) { - if (ld_cp->con_params.buffersize > preferred.buffersize.max) + if (ld_cp->con_params.data_flow > preferred.data_flow.max) { thereismismatch = true; if (ld_fix) { - ld_fix->con_params.buffersize = preferred.buffersize.max; + ld_fix->con_params.data_flow = preferred.data_flow.max; } } } // ================================================================================ - // Samplerate + // Subformat // ================================================================================ - if (JVX_CHECK_SIZE_SELECTED(preferred.samplerate.min)) + + if (preferred.subformat.min != JVX_DATAFORMAT_GROUP_NONE) { - if (ld_cp->con_params.rate < preferred.samplerate.min) + if (ld_cp->con_params.format_group < preferred.subformat.min) { thereismismatch = true; if (ld_fix) { - ld_fix->con_params.rate = preferred.samplerate.min; + ld_fix->con_params.format_group = preferred.subformat.min; } } } - if (JVX_CHECK_SIZE_SELECTED(preferred.samplerate.max)) + if (preferred.subformat.max != JVX_DATAFORMAT_GROUP_NONE) { - if (ld_cp->con_params.rate > preferred.samplerate.max) + if (ld_cp->con_params.format_group > preferred.subformat.max) { thereismismatch = true; if (ld_fix) { - ld_fix->con_params.rate = preferred.samplerate.max; + ld_fix->con_params.format_group = preferred.subformat.max; } } } - // ================================================================================ - // Format - // ================================================================================ - if (preferred.format.min != JVX_DATAFORMAT_NONE) + // In the second part, check the data connection topics for "real" data + + // All other parameters are not relevant from here on if trigger only + if (ld_cp->con_params.format_group != JVX_DATAFORMAT_GROUP_TRIGGER_ONLY) { - if (ld_cp->con_params.format < preferred.format.min) + // ================================================================================ + // Number output channels + // ================================================================================ + if (JVX_CHECK_SIZE_SELECTED(preferred.number_channels.min)) { - thereismismatch = true; - if (ld_fix) + if (ld_cp->con_params.number_channels < preferred.number_channels.min) { - ld_fix->con_params.format = preferred.format.min; + thereismismatch = true; + if (ld_fix) + { + ld_fix->con_params.number_channels = preferred.number_channels.min; + } } } - } - if (preferred.format.max != JVX_DATAFORMAT_NONE) - { - if (ld_cp->con_params.format > preferred.format.max) + if (JVX_CHECK_SIZE_SELECTED(preferred.number_channels.max)) { - thereismismatch = true; - if (ld_fix) + if (ld_cp->con_params.number_channels > preferred.number_channels.max) { - ld_fix->con_params.format = preferred.format.max; + thereismismatch = true; + if (ld_fix) + { + ld_fix->con_params.number_channels = preferred.number_channels.max; + } } } - } - // ================================================================================ - // Subformat - // ================================================================================ + // ================================================================================ + // Buffersize + // ================================================================================ - if (preferred.subformat.min != JVX_DATAFORMAT_GROUP_NONE) - { - if (ld_cp->con_params.format_group < preferred.subformat.min) + if (JVX_CHECK_SIZE_SELECTED(preferred.buffersize.min)) { - thereismismatch = true; - if (ld_fix) + if (ld_cp->con_params.buffersize < preferred.buffersize.min) { - ld_fix->con_params.format_group = preferred.subformat.min; + thereismismatch = true; + if (ld_fix) + { + ld_fix->con_params.buffersize = preferred.buffersize.min; + } } } - } - if (preferred.subformat.max != JVX_DATAFORMAT_GROUP_NONE) - { - if (ld_cp->con_params.format_group > preferred.subformat.max) + if (JVX_CHECK_SIZE_SELECTED(preferred.buffersize.max)) { - thereismismatch = true; - if (ld_fix) + if (ld_cp->con_params.buffersize > preferred.buffersize.max) { - ld_fix->con_params.format_group = preferred.subformat.max; + thereismismatch = true; + if (ld_fix) + { + ld_fix->con_params.buffersize = preferred.buffersize.max; + } } } - } - - // ================================================================================ - // Dataflow - // ================================================================================ - if (preferred.data_flow.min != jvxDataflow::JVX_DATAFLOW_NONE) - { - if (ld_cp->con_params.data_flow < preferred.data_flow.min) + // ================================================================================ + // Samplerate + // ================================================================================ + if (JVX_CHECK_SIZE_SELECTED(preferred.samplerate.min)) { - thereismismatch = true; - if (ld_fix) + if (ld_cp->con_params.rate < preferred.samplerate.min) { - ld_fix->con_params.data_flow = preferred.data_flow.min; + thereismismatch = true; + if (ld_fix) + { + ld_fix->con_params.rate = preferred.samplerate.min; + } } } - } - if (preferred.data_flow.max != jvxDataflow::JVX_DATAFLOW_NONE) - { - if (ld_cp->con_params.data_flow > preferred.data_flow.max) + if (JVX_CHECK_SIZE_SELECTED(preferred.samplerate.max)) { - thereismismatch = true; - if (ld_fix) + if (ld_cp->con_params.rate > preferred.samplerate.max) { - ld_fix->con_params.data_flow = preferred.data_flow.max; + thereismismatch = true; + if (ld_fix) + { + ld_fix->con_params.rate = preferred.samplerate.max; + } } } - } - // ================================================================================ - // DimX - // ================================================================================ - if (JVX_CHECK_SIZE_SELECTED(ld_cp->con_params.segmentation.x)) - { - if (JVX_CHECK_SIZE_SELECTED(preferred.dimX.min)) + // ================================================================================ + // Format + // ================================================================================ + if (preferred.format.min != JVX_DATAFORMAT_NONE) { - if (ld_cp->con_params.segmentation.x < preferred.dimX.min) + if (ld_cp->con_params.format < preferred.format.min) { thereismismatch = true; if (ld_fix) { - ld_fix->con_params.segmentation.x = preferred.dimX.min; + ld_fix->con_params.format = preferred.format.min; } } } - if (JVX_CHECK_SIZE_SELECTED(preferred.dimX.max)) + if (preferred.format.max != JVX_DATAFORMAT_NONE) { - if (ld_cp->con_params.segmentation.x > preferred.dimX.max) + if (ld_cp->con_params.format > preferred.format.max) { thereismismatch = true; if (ld_fix) { - ld_fix->con_params.segmentation.x = preferred.dimX.max; + ld_fix->con_params.format = preferred.format.max; } } } - } - // ================================================================================ - // DimY - // ================================================================================ - if (JVX_CHECK_SIZE_SELECTED(ld_cp->con_params.segmentation.y)) - { - if (JVX_CHECK_SIZE_SELECTED(preferred.dimY.min)) + // ================================================================================ + // DimX + // ================================================================================ + if (JVX_CHECK_SIZE_SELECTED(ld_cp->con_params.segmentation.x)) { - if (ld_cp->con_params.segmentation.y < preferred.dimY.min) + if (JVX_CHECK_SIZE_SELECTED(preferred.dimX.min)) { - thereismismatch = true; - if (ld_fix) + if (ld_cp->con_params.segmentation.x < preferred.dimX.min) + { + thereismismatch = true; + if (ld_fix) + { + ld_fix->con_params.segmentation.x = preferred.dimX.min; + } + } + } + if (JVX_CHECK_SIZE_SELECTED(preferred.dimX.max)) + { + if (ld_cp->con_params.segmentation.x > preferred.dimX.max) { - ld_fix->con_params.segmentation.y = preferred.dimY.min; + thereismismatch = true; + if (ld_fix) + { + ld_fix->con_params.segmentation.x = preferred.dimX.max; + } } } } - if (JVX_CHECK_SIZE_SELECTED(preferred.dimY.max)) + + // ================================================================================ + // DimY + // ================================================================================ + if (JVX_CHECK_SIZE_SELECTED(ld_cp->con_params.segmentation.y)) { - if (ld_cp->con_params.segmentation.y > preferred.dimY.max) + if (JVX_CHECK_SIZE_SELECTED(preferred.dimY.min)) { - thereismismatch = true; - if (ld_fix) + if (ld_cp->con_params.segmentation.y < preferred.dimY.min) + { + thereismismatch = true; + if (ld_fix) + { + ld_fix->con_params.segmentation.y = preferred.dimY.min; + } + } + } + if (JVX_CHECK_SIZE_SELECTED(preferred.dimY.max)) + { + if (ld_cp->con_params.segmentation.y > preferred.dimY.max) { - ld_fix->con_params.segmentation.y = preferred.dimY.max; + thereismismatch = true; + if (ld_fix) + { + ld_fix->con_params.segmentation.y = preferred.dimY.max; + } } } } @@ -763,8 +771,8 @@ CjvxNegotiate_common::_constrain_ldesc(jvxLinkDataDescriptor* theData) const // =================================================================== // Prefer min format - JVX_MAX_NEG_SET_LDAT_CMP(preferred.data_flow, theData->con_params.data_flow, JVX_DATAFLOW_NONE); - JVX_MIN_NEG_SET_LDAT_CMP(preferred.data_flow, theData->con_params.data_flow, JVX_DATAFLOW_NONE); + JVX_MAX_NEG_SET_LDAT_CMP(preferred.data_flow, theData->con_params.data_flow, JVX_DATAFLOW_DONT_CARE); + JVX_MIN_NEG_SET_LDAT_CMP(preferred.data_flow, theData->con_params.data_flow, JVX_DATAFLOW_DONT_CARE); } // =================================================================== 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 61f0c3e7..3b17771b 100644 --- a/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxSingleInputConnector.cpp +++ b/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxSingleInputConnector.cpp @@ -17,6 +17,17 @@ CjvxSingleInputTriggerConnector::trigger(jvxTriggerConnectorPurpose purp, jvxHan return res; } +jvxErrorType +CjvxSingleInputTriggerConnector::latest_result_data() +{ + if (bwdRef) + { + jvxErrorType res = bwdRef->resLatestGetData; + bwdRef->resLatestGetData = JVX_ERROR_UNKNOWN; + return res; + } + return JVX_ERROR_UNKNOWN; +} // ===================================================================================== @@ -249,6 +260,7 @@ CjvxSingleInputConnector::start_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb)) { res = trig_con->linked_ref->trigger(jvxTriggerConnectorPurpose::JVX_CONNECTOR_TRIGGER_START, nullptr JVX_CONNECTION_FEEDBACK_CALL_A(fdb)); } + resLatestGetData = JVX_ERROR_UNKNOWN; return res; } @@ -258,6 +270,8 @@ CjvxSingleInputConnector::stop_connect_icon(JVX_CONNECTION_FEEDBACK_TYPE(fdb)) jvxErrorType res = JVX_NO_ERROR; if (res == JVX_NO_ERROR) { + resLatestGetData = JVX_ERROR_UNKNOWN; + if (trig_con && trig_con->linked_ref) { @@ -346,6 +360,12 @@ CjvxSingleInputConnector::available_to_connect_icon() return JVX_ERROR_UNSUPPORTED; } +void +CjvxSingleInputConnector::setLatestResultGetData(jvxErrorType resLatestGetDataArg) +{ + resLatestGetData = resLatestGetDataArg; +} + // =============================================================================================== // =============================================================================================== diff --git a/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxSingleOutputConnector.cpp b/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxSingleOutputConnector.cpp index 3aec218d..c2e57263 100644 --- a/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxSingleOutputConnector.cpp +++ b/sources/jvxLibraries/jvx-component-templates-base/src/common/CjvxSingleOutputConnector.cpp @@ -235,6 +235,20 @@ CjvxSingleOutputConnector::available_to_connect_ocon() { return JVX_ERROR_UNSUPPORTED; } + +jvxErrorType +CjvxSingleOutputConnector::resultFromInputConnector() +{ + jvxErrorType res = JVX_ERROR_UNKNOWN; + if (trig_con) + { + if (trig_con->linked_ref) + { + res = trig_con->linked_ref->latest_result_data(); + } + } + return res; +} // ================================================================================= jvxErrorType diff --git a/sources/jvxLibraries/jvx-component-templates-base/src/jvxNodes/CjvxInputOutputConnector_NVtask.cpp b/sources/jvxLibraries/jvx-component-templates-base/src/jvxNodes/CjvxInputOutputConnector_NVtask.cpp index 47bd826c..e9d3f180 100644 --- a/sources/jvxLibraries/jvx-component-templates-base/src/jvxNodes/CjvxInputOutputConnector_NVtask.cpp +++ b/sources/jvxLibraries/jvx-component-templates-base/src/jvxNodes/CjvxInputOutputConnector_NVtask.cpp @@ -90,7 +90,7 @@ CjvxInputConnectorNVtask::supports_connector_class_icon( return JVX_ERROR_UNSUPPORTED; } } - if (_common_set_icon_nvtask.caps_in.data_flow != JVX_DATAFLOW_NONE) + if (_common_set_icon_nvtask.caps_in.data_flow != JVX_DATAFLOW_DONT_CARE) { if (_common_set_icon_nvtask.caps_in.data_flow != data_flow) { @@ -151,7 +151,7 @@ CjvxOutputConnectorNVtask::supports_connector_class_ocon( return JVX_ERROR_UNSUPPORTED; } } - if (_common_set_ocon_nvtask.caps_out.data_flow != JVX_DATAFLOW_NONE) + if (_common_set_ocon_nvtask.caps_out.data_flow != JVX_DATAFLOW_DONT_CARE) { if (_common_set_ocon_nvtask.caps_out.data_flow != data_flow) { diff --git a/sources/jvxLibraries/jvx-component-templates-min/include/common/CjvxInputConnectorCore.h b/sources/jvxLibraries/jvx-component-templates-min/include/common/CjvxInputConnectorCore.h index e800e4e4..6d50118d 100644 --- a/sources/jvxLibraries/jvx-component-templates-min/include/common/CjvxInputConnectorCore.h +++ b/sources/jvxLibraries/jvx-component-templates-min/include/common/CjvxInputConnectorCore.h @@ -22,7 +22,7 @@ class CjvxInputConnectorCore struct { jvxDataFormatGroup format_group = JVX_DATAFORMAT_GROUP_NONE; - jvxDataflow data_flow = JVX_DATAFLOW_NONE; + jvxDataflow data_flow = JVX_DATAFLOW_DONT_CARE; } caps_in; }; diff --git a/sources/jvxLibraries/jvx-component-templates-min/include/common/CjvxOutputConnectorCore.h b/sources/jvxLibraries/jvx-component-templates-min/include/common/CjvxOutputConnectorCore.h index 8cb60046..3a9b3565 100644 --- a/sources/jvxLibraries/jvx-component-templates-min/include/common/CjvxOutputConnectorCore.h +++ b/sources/jvxLibraries/jvx-component-templates-min/include/common/CjvxOutputConnectorCore.h @@ -24,7 +24,7 @@ class CjvxOutputConnectorCore struct { jvxDataFormatGroup format_group = JVX_DATAFORMAT_GROUP_NONE; - jvxDataflow data_flow = JVX_DATAFLOW_NONE; + jvxDataflow data_flow = JVX_DATAFLOW_DONT_CARE; } caps_out; }; diff --git a/sources/jvxLibraries/jvx-component-templates-min/src/common/CjvxInputConnectorCore.cpp b/sources/jvxLibraries/jvx-component-templates-min/src/common/CjvxInputConnectorCore.cpp index a8d1c85c..8af329d1 100644 --- a/sources/jvxLibraries/jvx-component-templates-min/src/common/CjvxInputConnectorCore.cpp +++ b/sources/jvxLibraries/jvx-component-templates-min/src/common/CjvxInputConnectorCore.cpp @@ -61,7 +61,7 @@ CjvxInputConnectorCore::_supports_connector_class_icon( return JVX_ERROR_UNSUPPORTED; } } - if (_common_set_icon.caps_in.data_flow != JVX_DATAFLOW_NONE) + if (_common_set_icon.caps_in.data_flow != JVX_DATAFLOW_DONT_CARE) { if (_common_set_icon.caps_in.data_flow != data_flow) { diff --git a/sources/jvxLibraries/jvx-component-templates-min/src/common/CjvxOutputConnectorCore.cpp b/sources/jvxLibraries/jvx-component-templates-min/src/common/CjvxOutputConnectorCore.cpp index b66833ea..cd4a45c7 100644 --- a/sources/jvxLibraries/jvx-component-templates-min/src/common/CjvxOutputConnectorCore.cpp +++ b/sources/jvxLibraries/jvx-component-templates-min/src/common/CjvxOutputConnectorCore.cpp @@ -60,7 +60,7 @@ CjvxOutputConnectorCore::_supports_connector_class_ocon( return JVX_ERROR_UNSUPPORTED; } } - if (_common_set_ocon.caps_out.data_flow != JVX_DATAFLOW_NONE) + if (_common_set_ocon.caps_out.data_flow != JVX_DATAFLOW_DONT_CARE) { if (_common_set_ocon.caps_out.data_flow != data_flow) { diff --git a/sources/jvxLibraries/jvx-helpers/src/HjvxDataLinkDescriptor.cpp b/sources/jvxLibraries/jvx-helpers/src/HjvxDataLinkDescriptor.cpp index 6f684f41..de710d8f 100644 --- a/sources/jvxLibraries/jvx-helpers/src/HjvxDataLinkDescriptor.cpp +++ b/sources/jvxLibraries/jvx-helpers/src/HjvxDataLinkDescriptor.cpp @@ -1434,14 +1434,22 @@ jvxErrorType jvx_check_valid(jvxLinkDataDescriptor_con_params& params, std::stri } if (params.format == JVX_DATAFORMAT_NONE) { - errReason = "Invalid format specified."; - goto fail; + if (params.format_group != JVX_DATAFORMAT_GROUP_TRIGGER_ONLY) + { + errReason = "Invalid format specified."; + goto fail; + } } if (params.format_group == JVX_DATAFORMAT_GROUP_NONE) { errReason = "Invalid format group specified."; goto fail; } + if (params.data_flow == JVX_DATAFLOW_DONT_CARE) + { + errReason = "Invalid format group specified."; + goto fail; + } return JVX_NO_ERROR; fail: return JVX_ERROR_INVALID_ARGUMENT; diff --git a/sources/jvxLibraries/jvx-system-base/include/interfaces/IjvxTriggerConnector.h b/sources/jvxLibraries/jvx-system-base/include/interfaces/IjvxTriggerConnector.h index d2bf4afe..5ef0875a 100644 --- a/sources/jvxLibraries/jvx-system-base/include/interfaces/IjvxTriggerConnector.h +++ b/sources/jvxLibraries/jvx-system-base/include/interfaces/IjvxTriggerConnector.h @@ -28,6 +28,7 @@ JVX_INTERFACE IjvxTriggerOutputConnector : public IjvxTriggerConnector virtual jvxErrorType link_connect_tcon(IjvxTriggerInputConnector* otcon) = 0; virtual jvxErrorType unlink_connect_tcon(IjvxTriggerInputConnector* otcon) = 0; + virtual jvxErrorType latest_result_data() = 0; }; #endif \ No newline at end of file diff --git a/sources/jvxLibraries/jvx-system-base/include/typedefs/TjvxLinkDataDescriptor.h b/sources/jvxLibraries/jvx-system-base/include/typedefs/TjvxLinkDataDescriptor.h index 10b7d283..466be694 100644 --- a/sources/jvxLibraries/jvx-system-base/include/typedefs/TjvxLinkDataDescriptor.h +++ b/sources/jvxLibraries/jvx-system-base/include/typedefs/TjvxLinkDataDescriptor.h @@ -361,7 +361,7 @@ struct jvxLinkDataDescriptor_con_params jvxDataFormatGroup format_group = JVX_DATAFORMAT_GROUP_NONE; // Dataflow capability - jvxDataflow data_flow = JVX_DATAFLOW_NONE; + jvxDataflow data_flow = JVX_DATAFLOW_PUSH_ACTIVE; // A buffer of size buffersize is segmented into x and y according to: // -------- segmentation_x --------> diff --git a/sources/jvxLibraries/jvx-system-min/include/jvx_system_dataformats.h b/sources/jvxLibraries/jvx-system-min/include/jvx_system_dataformats.h index 2d6b3eca..1911db76 100644 --- a/sources/jvxLibraries/jvx-system-min/include/jvx_system_dataformats.h +++ b/sources/jvxLibraries/jvx-system-min/include/jvx_system_dataformats.h @@ -347,18 +347,19 @@ static inline jvxSize jvxDataFormatGroup_getsize(jvxSize idx) typedef enum { - JVX_DATAFLOW_NONE, JVX_DATAFLOW_PUSH_ACTIVE, // Devices and nodes push data forward by calling process function of subsequent linked component JVX_DATAFLOW_PUSH_ON_PULL, // Devices and nodes are triggered from subsequent element and call process function within this "pull" + JVX_DATAFLOW_PUSH_ASYNC, // Devices and nodes push data forward by calling process function of subsequent linked component + JVX_DATAFLOW_DONT_CARE, // All dataflows are accepted, this indicates that the value from input is used on output side in 1-to-1 connections JVX_DATAFLOW_LIMIT } jvxDataflow; static jvxTextHelpers jvxDataflow_str[JVX_DATAFLOW_LIMIT] = { - {"none", "JVX_DATAFLOW_NONE"}, - {"push", "JVX_DATAFLOW_PUSH_ACTIVE" }, - {"pull", "JVX_DATAFLOW_PUSH_ON_PULL"} + {"pull", "JVX_DATAFLOW_PUSH_ON_PULL"}, + {"async", "JVX_DATAFLOW_PUSH_ASYNC"}, + {"dontcare", "JVX_DATAFLOW_DONT_CARE"} }; static inline const char* jvxDataflow_txt(jvxSize id) @@ -370,7 +371,7 @@ static inline const char* jvxDataflow_txt(jvxSize id) static inline jvxDataflow jvxDataflow_decode(const char* token) { jvxSize i; - jvxDataflow res = JVX_DATAFLOW_NONE; + jvxDataflow res = JVX_DATAFLOW_DONT_CARE; for (i = 0; i < JVX_DATAFORMAT_GROUP_LIMIT; i++) { if (!strcmp(jvxDataflow_str[i].friendly, token)) diff --git a/sources/jvxPackages/ffmpeg/jvxComponents/jvxAudioCodecs/jvxAuCFfmpeg/src/CjvxAuCFfmpegDecoder.cpp b/sources/jvxPackages/ffmpeg/jvxComponents/jvxAudioCodecs/jvxAuCFfmpeg/src/CjvxAuCFfmpegDecoder.cpp index 8d8db897..3d342cd1 100644 --- a/sources/jvxPackages/ffmpeg/jvxComponents/jvxAudioCodecs/jvxAuCFfmpeg/src/CjvxAuCFfmpegDecoder.cpp +++ b/sources/jvxPackages/ffmpeg/jvxComponents/jvxAudioCodecs/jvxAuCFfmpeg/src/CjvxAuCFfmpegDecoder.cpp @@ -19,7 +19,7 @@ CjvxAuCFfmpegAudioDecoder::set_configure_token(const char* tokenArg) JVX_SIZE_DONTCARE, JVX_DATAFORMAT_POINTER, JVX_DATAFORMAT_GROUP_FFMPEG_PACKET_FWD, - JVX_DATAFLOW_NONE, + JVX_DATAFLOW_DONT_CARE, JVX_SIZE_UNSELECTED, 1); // <- number_channels and segment are different arguments here neg_output._set_parameters_fixed( diff --git a/versions.txt b/versions.txt index 48c29e9e..309a833d 100644 --- a/versions.txt +++ b/versions.txt @@ -4,5 +4,10 @@ AudYoFlo Version Release History -------------------||--------------||---------------------------|| arbok || 19.5.2023 || Initial version release || -------------------||--------------||---------------------------|| + smettbo || 04.06.2024 || Intermediate release || + || || due to many people cloning|| +-------------------||--------------||---------------------------|| + + HK, 19.05.2023