Giter Site home page Giter Site logo

cross-platform / dspatch Goto Github PK

View Code? Open in Web Editor NEW
206.0 22.0 43.0 5.99 MB

The Refreshingly Simple Cross-Platform C++ Dataflow / Patching / Pipelining / Graph Processing / Stream Processing / Reactive Programming Framework

Home Page: https://flowbasedprogramming.com/

License: BSD 2-Clause "Simplified" License

C++ 99.53% Meson 0.41% Batchfile 0.03% Shell 0.03%
stream-processing reactive-programming dataflow dataflow-programming pipelines pipelining flow-based-programming data-driven cross-platform patching

dspatch's People

Contributors

daniel-k avatar linux-admirer avatar marcustomlinson avatar nyue avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dspatch's Issues

Nested/Sub Flow : Flow reuse/encapsulation

Is there a concept/mechanism to support flow reuse through nested/sub flow whereby a flow definition can be wrap up in a way that e.g. exposes salient inputs/outputs, when view from the outside, user only see those salient inputs/outputs like a function.

Can a component output be wired to multiple component inputs?

Hi @MarcusTomlinson,

Just wondering if DSPatch supports wiring the output pin of a component to more than one input pin, or must the user instantiate a broadcast component explicitly? I couldn't find an explicit mention of this, if I'm correct I would suggest adding a note somewhere, perhaps to Circuit::ConnectOutToIn().

Best regards,
JO

Async data/event

Many thanks for sharing this data centric programing framework. Actually I love it very much and think it will simplifies a lot of programming effort when dealing with streaming data.

After reading the docs, I come across a question that if there are async event, such as user input, or history data based decision branch, that generating data not synced with the main data stream, what is the best way to do with the DSPatch framework?

Best regards,
Xing

named and optional IO

It is quite simple and refreshing indeed.
It would be nice to add named inputs/outputs so that components can be connected by name. It would be less bug prone, especially since the types are dynamic and there is no type safety on the bus.

Also, can a component know if a specific output is required by some future component or not? This is nice for performance reasons. If it is not needed, it can be skipped.

Thx.

DSPATCH Circuit COmpilation

Hello Marcus, i work for Bretain university in france and i like your Dataflow Frameworks.
We want to test your frameworks and why not using it for research on Noc.

i have follow your tutorial and i have create a small circuit code to the end of post :

i have compile it and it return an undefined reference, i dont really know why because all dspatch header has been put inside usr/include directory in my linux18.04 OS.
Have you some idies? i am autodidact

Thanks

chapoul@lo-lester-007:~/Téléchargements/dspatch-master$ gcc hello.cpp -o f
/tmp/ccWZiQ8F.o : Dans la fonction « main » :
hello.cpp:(.text+0x1db) : référence indéfinie vers « DSPatch::Circuit::AddComponent(std::shared_ptrDSPatch::Component const&) »
hello.cpp:(.text+0x21e) : référence indéfinie vers « DSPatch::Circuit::AddComponent(std::shared_ptrDSPatch::Component const&) »
hello.cpp:(.text+0x261) : référence indéfinie vers « DSPatch::Circuit::AddComponent(std::shared_ptrDSPatch::Component const&) »
hello.cpp:(.text+0x2a1) : référence indéfinie vers « DSPatch::Circuit::AddComponent(std::shared_ptrDSPatch::Component const&) »
hello.cpp:(.text+0x2e1) : référence indéfinie vers « DSPatch::Circuit::AddComponent(std::shared_ptrDSPatch::Component const&) »
/tmp/ccWZiQ8F.o:hello.cpp:(.text+0x321) : encore plus de références indéfinies suivent vers « DSPatch::Circuit::AddComponent(std::shared_ptrDSPatch::Component const&) »

CODE:

#include <DSPatch.h>
#include <components.h>
#include <stdio.h>
#include <stdlib.h>

using namespace DSPatch;

class Multiplexeur: public Component{

public:
    Multiplexeur(){
        //input/output block
        SetInputCount_( 3 );
        SetOutputCount_( 1 );
    }

protected:
virtual void Process_( SignalBus const& inputs, SignalBus& outputs ) override{
    // create some local pointers to hold our input values
    auto int1 = inputs.GetValue<int>( 0 );
    auto int2 = inputs.GetValue<int>( 1 );
    auto int3 = inputs.GetValue<int>( 2 );

    // check first that our component has received valid inputs
    if ( int1 && int2 && int3 )
    {
        // set the output as the result of bool1 AND bool2
        outputs.SetValue( 0, *int1 && *int2 && *int3 );
    }
}

};

class Sub: public Component{

public:
    Sub(){
        //input/output block
        SetInputCount_( 2 );
        SetOutputCount_( 1 );
    }

protected:
virtual void Process_( SignalBus const& inputs, SignalBus& outputs ) override{
    // create some local pointers to hold our input values
    auto int1 = inputs.GetValue<int>( 0 );
    auto int2 = inputs.GetValue<int>( 1 );

    // check first that our component has received valid inputs
    if ( int1 && int2)
    {
        // set the output as the result of bool1 AND bool2
        outputs.SetValue( 0, *int1 - *int2);
    }
}

};

class Add: public Component{

public:
    Add(){
        //input/output block
        SetInputCount_( 1 );
        SetOutputCount_( 1 );
    }

protected:
virtual void Process_( SignalBus const& inputs, SignalBus& outputs ) override{
    // create some local pointers to hold our input values
    auto int1 = inputs.GetValue<int>( 0 );

    // check first that our component has received valid inputs
    if ( int1 )
    {
        // set the output as the result of bool1 AND bool2
        outputs.SetValue( 0, *int1 +10);
    }
}

};

class RandInt final : public Component
{
public:
RandInt()
{
// add 1 output
SetOutputCount_( 1 );

    // seed randomizer
    srand( static_cast<unsigned int>( time( nullptr ) ) );
}

protected:
virtual void Process_( SignalBus const&, SignalBus& outputs ) override
{
// set output as randomized true / false
outputs.SetValue( 0, rand() );
}
};

class PrintValue final : public Component
{
public:
PrintValue()
{
// add 1 input
SetInputCount_( 1 );
}

protected:
virtual void Process_( SignalBus const& inputs, SignalBus& ) override
{
// create a local stack variable to hold input value
auto inputVal = inputs.GetValue( 0 );

    // get boolean value from inputs bus
    if ( inputVal )
    {
        // print "true" / "false" depending on boolean value received
        if ( *inputVal )
        {
            std::cout << "PrintValue:" <<inputVal <<std::endl;
        }
        else
        {
            std::cout << "error" << '\n';
        }
    }
}

};

int main(){

//component declaration
auto circuit = std::make_shared();

auto randIntGen1 = std::make_shared();

auto randIntGen2 = std::make_shared();

auto randIntGen3 = std::make_shared();

auto Sub1 = std::make_shared();

auto Mult1 = std::make_shared();

auto Add1 = std::make_shared();

auto Print1 = std::make_shared();

//circuit component declaration
circuit->AddComponent( randIntGen1 );

circuit->AddComponent( randIntGen2 );

circuit->AddComponent( randIntGen3 );

circuit->AddComponent( Sub1 );

circuit->AddComponent( Mult1 );

circuit->AddComponent( Add1 );

circuit->AddComponent( Print1 );

//Graphe node configuration of the circuit
circuit->ConnectOutToIn( randIntGen1, 0, Mult1, 0 );

circuit->ConnectOutToIn( randIntGen2, 0, Mult1, 1 );

circuit->ConnectOutToIn( randIntGen2, 0, Sub1, 0 );

circuit->ConnectOutToIn( randIntGen3, 0, Sub1, 1 );

circuit->ConnectOutToIn( Sub1, 0, Mult1, 2 );

circuit->ConnectOutToIn( Mult1, 0, Print1, 0 );

for( int i = 0; i < 10; ++i )

{

circuit->Tick();

}

std::cout << "Press any key to begin circuit auto-tick.";

getchar();

circuit->StartAutoTick();

circuit->SetBufferCount( 4 );

return 0;
}

Question : Handling similar types

Hi,

Just discovered dspatch.

Is there some design-pattern/coding-wisdom for handling of similar types e.g. all the numerical POD (Plain Old Datatypes) e.g. int8_t, uint64_t, float, double etc, without having to write one for each type and types combination.

I am writing a component call Add and would like to be able to flexibly handle similar arithmetic types.

There are two sub cases, when input 1 and input 2 are of the same type and when input 1 and input 2 are of different types.

My testing reveal that GetValue(N) returns nullptr if "type" is different from the underlying type which I can understand.

`
class Add final : public Component
{
public:
// 2. Configure component IO buses
// ===============================
Add()
{
// add 2 inputs
SetInputCount_( 2 );

    // add 1 output
    SetOutputCount_( 1 );
}

protected:
// 3. Implement virtual Process_() method
// ======================================
virtual void Process_( SignalBus const& inputs, SignalBus& outputs ) override
{
std::cout << "Add::_Proces()" << std::endl;
// create some local pointers to hold our input values
auto float1 = inputs.GetValue( 0 );
`

Cheers

Why does multithreading get stuck? The program cannot continue to run

1.My working environment:
dspatch v9.7.3
VS2019x64

2.code here
#include <DSPatch.h>
#include "components.h"

using namespace DSPatch;

void fixme()
{
auto circuit = std::make_shared();
circuit->SetBufferCount(2); //count=1,ok; but count>1, no good, why? fixme

for (int i = 0; i < 10; ++i)
{
    circuit->RemoveAllComponents();

    auto randBoolGen1 = std::make_shared<RandBool>();
    auto randBoolGen2 = std::make_shared<RandBool>();
    auto logicAnd = std::make_shared<And>();
    auto boolPrinter = std::make_shared<PrintInt>();

    circuit->AddComponent(randBoolGen1);
    circuit->AddComponent(randBoolGen2);
    circuit->AddComponent(logicAnd);
    circuit->AddComponent(boolPrinter);

    circuit->ConnectOutToIn(randBoolGen1, 0, logicAnd, 0);
    circuit->ConnectOutToIn(randBoolGen2, 0, logicAnd, 1);
    circuit->ConnectOutToIn(logicAnd, 0, boolPrinter, 0);

    circuit->Tick();
    circuit->Sync();

    std::cout << i << std::endl;
}

//finish
std::cout << "finish" << std::endl;

}

int main(int argc, char *argv[])
{
fixme();
return 0;
}

3.The problem I'm having is:
If SetBufferCount=1, then the for loop runs normally 10 times
If SetBufferCount>1, then the for loop can only run once and will get stuck the second time.
Why?
How to solve it?

Running DSPatch script in SniperSimulator

Hello,

Aftyer have succefully build and test script DSPatch, i try to use it in sniperSimulator ( hardware simulator. http://snipersim.org/w/The_Sniper_Multi-Core_Simulator
have you ever seen that kind of error?

i have put to dir the LD_LIBRARY_PATH=$(pwd) , libDSPatch.so

/home/chapoul/sniper/fff: symbol lookup error: /home/chapoul/sniper/fff: undefined symbol: _ZN7DSPatch9Component14SetInputCount_EiRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE

The Signal.h file is missing, resulting in an error in compiling the Inout project

1.The earlier version had the Signal.h file, but now the new version does not have this header file. causing a compilation error:
\DSPatchables\Components\InOut\InOut.h(64,44): error C2065: 'Signal': undeclared identifier

https://github.com/cross-platform/dspatch/tree/master/include/dspatch/Signal.h

2.cmake+msvc2019, Compile Error
1>------ Build started: Project: InOut, Configuration: Debug x64 ------
1>Automatic MOC for target InOut
1>InOut.cpp
1>E:\temp\svntmp\dspatcher\dspatcher-master\DSPatchables\Components\InOut\InOut.cpp(79,47): error C2664: “bool DSPatch::Signal::MoveSignal(DSPatch::Signal &)” : cannot convert argument 1 from 'fast_any::any' to 'DSPatch::Signal &'
1>E:\temp\svntmp\dspatcher\dspatcher-master\DSPatchables\DSPatch\include\dspatch/Signal.h(214,21): message : See the declaration of "DSPatch::Signal::MoveSignal"
1>E:\temp\svntmp\dspatcher\dspatcher-master\DSPatchables\Components\InOut\InOut.cpp(89,62): error C2664: “void DSPatch::SignalBus::MoveSignal(int,fast_any::any & )": cannot convert argument 2 from "_Ty2" to "fast_any::any &"
1> with
1>[
1> _Ty2=DSPatch::Signal
1>]
1>E:\temp\svntmp\dspatcher\dspatcher-master\DSPatchables\DSPatch\include\dspatch/SignalBus.h(187,24): message : See the declaration of "DSPatch::SignalBus::MoveSignal"
1>Completed generating project "InOut.vcxproj" - Failed.
========== Generated: 0 succeeded, 1 failed, 2 latest, 0 skipped ==========

Is the data structure used in this project DAG?

DAG:Directed Acyclic Graph

1.Is the data structure of "circuit" a graph or a tree?
2.Is the data structure of adding "components" to "circuit" a graph or a tree? If it is a graph, is it acyclic or cyclic?
3.Is there any documentation that explains the principles of each component traversal? Is it depth-first or breadth-first?

SocketIn.cpp(26,1): error C2059: syntax error: "}"

dspatch-9.7.1
MSVC 2019

1.compile error,
\DSPatchables\Components\Sockets\SocketInSocketIn.cpp

image

1>E:\temp\svntmp\dspatcher\dspatcher-master\DSPatchables\Components\Sockets\SocketIn\SocketIn.cpp(26,1): error C2059: syntax error: "}"
1>E:\temp\svntmp\dspatcher\dspatcher-master\DSPatchables\Components\Sockets\SocketIn\SocketIn.cpp(26,1): error C2143: syntax error: missing ';' (before '}')
1>E:\temp\svntmp\dspatcher\dspatcher-master\DSPatchables\Components\Sockets\SocketIn\SocketIn.cpp(29,1): error C2143: syntax error: missing ";" (before "{")
1>E:\temp\svntmp\dspatcher\dspatcher-master\DSPatchables\Components\Sockets\SocketIn\SocketIn.cpp(29,1): error C2447: "{": missing function header (is it an old-style form? )
1>E:\temp\svntmp\dspatcher\dspatcher-master\DSPatchables\Components\Sockets\SocketIn\SocketIn.cpp(80,52): error C2065: "fn": undeclared identifier
1>E:\temp\svntmp\dspatcher\dspatcher-master\DSPatchables\Components\Sockets\SocketIn\SocketIn.cpp(115,79): error C2065: "fn": undeclared identifier
1>E:\temp\svntmp\dspatcher\dspatcher-master\DSPatchables\Components\Sockets\SocketIn\SocketIn.cpp(119,60): error C2065: "fn": undeclared identifier

2.compile error,
\DSPatchables\Components\WebRtc\webrtc-audio-processing-prefix\src\webrtc-audio-processing\webrtc\modules\interface\module_common_types.h
image

4>E:\temp\svntmp\dspatcher\dspatcher-master\build\DSPatchables\Components\WebRtc\webrtc-audio-processing-prefix\src\webrtc-audio-processing\webrtc/modules/interface/module_common_types.h(343 ,5): warning C4003: Insufficient "max" arguments for function-like macro call
4>E:\temp\svntmp\dspatcher\dspatcher-master\build\DSPatchables\Components\WebRtc\webrtc-audio-processing-prefix\src\webrtc-audio-processing\webrtc/modules/interface/module_common_types.h(343 ,5): error C2589: illegal token to the right of "(":"::"
4>E:\temp\svntmp\dspatcher\dspatcher-master\build\DSPatchables\Components\WebRtc\webrtc-audio-processing-prefix\src\webrtc-audio-processing\webrtc/modules/interface/module_common_types.h(343 ): error C2062: Unexpected type 'unknown-type'
4>E:\temp\svntmp\dspatcher\dspatcher-master\build\DSPatchables\Components\WebRtc\webrtc-audio-processing-prefix\src\webrtc-audio-processing\webrtc/modules/interface/module_common_types.h(343 ,1): error C2059: syntax error: ")"
5>E:\temp\svntmp\dspatcher\dspatcher-master\build\DSPatchables\Components\WebRtc\webrtc-audio-processing-prefix\src\webrtc-audio-processing\webrtc/modules/interface/module_common_types.h(343 ,5): warning C4003: Insufficient "max" arguments for function-like macro call
5>E:\temp\svntmp\dspatcher\dspatcher-master\build\DSPatchables\Components\WebRtc\webrtc-audio-processing-prefix\src\webrtc-audio-processing\webrtc/modules/interface/module_common_types.h(343 ,5): error C2589: illegal token to the right of "(":"::"
5>E:\temp\svntmp\dspatcher\dspatcher-master\build\DSPatchables\Components\WebRtc\webrtc-audio-processing-prefix\src\webrtc-audio-processing\webrtc/modules/interface/module_common_types.h(343 ): error C2062: Unexpected type 'unknown-type'
5>E:\temp\svntmp\dspatcher\dspatcher-master\build\DSPatchables\Components\WebRtc\webrtc-audio-processing-prefix\src\webrtc-audio-processing\webrtc/modules/interface/module_common_types.h(343 ,1): error C2059: syntax error: ")"

feature request

As I know, dspatch component would be ticked after all input sigals ready.
is it posible to be ticked just after one of input sigals ready?

MoveValue without copy constructor

I have a class with only a move constructor but without a copy constructor. When I use it as a an output from a component, I get an error. Below I give a minimal example where this happens together with the compilation error. My platform is macOS Sonoma 14.2.1 on a M2 processor, and compilation is done using Apple clang version 15.0.0 (clang-1500.1.0.2.5)

Code:

{
class movable_class {
public:
movable_class() {}
movable_class(movable_class && other) {};
};

class test_component final : public DSPatch::Component {
	public:
		test_component()
		{
			SetInputCount_(0);
			SetOutputCount_(1);
		}
		void Process_(DSPatch::SignalBus& inputs, DSPatch::SignalBus& outputs) override
		{
			movable_class x;
			outputs.MoveValue(0, std::move(x));
		}
};
auto c = std::make_shared<test_component>();

auto circuit = std::make_shared<Circuit>();
circuit->AddComponent(c);
circuit->Tick();

}

Compilation error:

In file included from /Users/pswoboda/repo/dspatch/include/DSPatch.h:31:
In file included from /Users/pswoboda/repo/dspatch/include/dspatch/Circuit.h:31:
In file included from /Users/pswoboda/repo/dspatch/include/dspatch/Component.h:31:
In file included from /Users/pswoboda/repo/dspatch/include/dspatch/SignalBus.h:33:
/Users/pswoboda/repo/dspatch/include/fast_any/any.h:279:58: error: object of type 'movable_class' cannot be assigned because its copy assignment operator is implicitly deleted
static_cast<value_t*>( _value_holder )->value = std::forward( value );
^
/Users/pswoboda/repo/dspatch/include/dspatch/SignalBus.h:172:31: note: in instantiation of function template specialization 'fast_any::any::emplace<movable_class>' requested here
_signals[signalIndex].emplace( std::forward( newValue ) );
^
/Users/pswoboda/repo/dspatch/tests/main.cpp:982:13: note: in instantiation of function template specialization 'DSPatch::SignalBus::MoveValue<movable_class>' requested here
outputs.MoveValue(0, std::move(x));
^
/Users/pswoboda/repo/dspatch/tests/main.cpp:959:4: note: copy assignment operator is implicitly deleted because 'movable_class' has a user-declared move constructor
movable_class(movable_class && other)
^

Thank you for any help!

Circular circuits don't work

This might be my misunderstanding of the feature "Feedback loops".

Recreate Issue:

Start from the tutorial project

  • Change step 4 to
// 4. Wire up the components inside the circuit
// ============================================
circuit->ConnectOutToIn( randBoolGen1, 0, logicAnd, 0 );
circuit->ConnectOutToIn( logicAnd, 0, logicAnd, 1 );
circuit->ConnectOutToIn( logicAnd, 0, boolPrinter, 0 );

Basically wire the output of the And Component to one of it's inputs

Expected:
Some true or false value printed depending on the random gen

Result:
Nothing, GetValue on the And and PrintBool components seem to return null;

How to check if inputs have changed since last Circuit::Tick() ?

In the method

void SomeClass::Process_( SignalBus const& inputs, SignalBus& outputs )

is there a way to determine if the inputs have change since the last call to ::Tick() or within the ::Process_() call.
I am looking for a way to avoid doing any computation and updating outputs if the inputs have not change.

Cheers

aec and agc, Compile Error

MSVC 2019 x64

1.aec and agc, Compile Error

image

1>------ Build started: Project: webrtc-audio-processing, Configuration: Debug x64 ------
2>------ Build started: Project: Aec, Configuration: Debug x64 ------
2>Automatic MOC for target Aec
2>libwebrtc_audio_processing.a(audio_processing_impl.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(audio_processing_impl.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(checks.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(checks.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(audio_converter.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(audio_converter.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(agc_agc_manager_direct.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(agc_agc_manager_direct.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(audio_buffer.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(audio_buffer.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(audio_ring_buffer.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(audio_ring_buffer.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(beamformer_nonlinear_beamformer.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(beamformer_nonlinear_beamformer.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(processing_component.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(processing_component.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(echo_cancellation_impl.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(echo_cancellation_impl.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(echo_control_mobile_impl.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(echo_control_mobile_impl.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(gain_control_impl.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(gain_control_impl.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(high_pass_filter_impl.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(high_pass_filter_impl.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(intelligibility_intelligibility_enhancer.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(intelligibility_intelligibility_enhancer.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(level_estimator_impl.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(level_estimator_impl.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(noise_suppression_impl.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(noise_suppression_impl.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(transient_transient_suppressor.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(transient_transient_suppressor.cc.obj) : error LNK2038: Mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' does not match value 'MDd_DynamicDebug' (in Aec.obj)
2>libwebrtc_audio_processing.a(voice_detection_impl.cc.obj) : error LNK2038: Mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' does not match value '2' (in Aec.obj)
2>libwebrtc_audio_processing.a(voice_detecti

2.Error copying file (if different) from "/bin/libEGLd.dll" to "E:/temp/svntmp/dspatcher/dspatcher-master/build/DSPatcher/Debug/libEGLd.dll".
image

Error copying file (if different) from "/bin/libEGLd.dll" to "E:/temp/svntmp/dspatcher/dspatcher-master/build/DSPatcher/Debug/libEGLd.dll".
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: command "setlocal
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: "C:\Program Files\CMake\ bin\cmake.exe" -E copy_if_different E:/temp/svntmp/dspatcher/dspatcher-master/build/DSPatcher/../DSPatchables/DSPatch/Debug/DSPatch.dll E:/temp/svntmp/dspatcher/dspatcher-master /build/DSPatcher/Debug
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: :cmEnd
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: endlocal & call :cmErrorLevel %errorlevel% & goto:cmDone
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: :cmErrorLevel
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: exit /b %1
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: :cmDone
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: setlocal
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: "C:\Program Files\CMake\ bin\cmake.exe" -E copy_if_different /bin/libEGLd.dll E:/temp/svntmp/dspatcher/dspatcher-master/build/DSPatcher/Debug/libEGLd.dll
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: :cmEnd
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: endlocal & call :cmErrorLevel %errorlevel% & goto:cmDone
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: :cmErrorLevel
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: exit /b %1
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: :cmDone
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: setlocal
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: "C:\Program Files\CMake\ bin\cmake.exe" -E copy_if_different /bin/libGLESv2d.dll E:/temp/svntmp/dspatcher/dspatcher-master/build/DSPatcher/Debug/libGLESv2d.dll
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: :cmEnd
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: endlocal & call :cmErrorLevel %errorlevel% & goto:cmDone
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: :cmErrorLevel
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: exit /b %1
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3073: :cmDone
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3

Error when building

[ 76%] Building CXX object tests/CMakeFiles/DSPatchTests.dir/main.cpp.o
In file included from /usr/include/signal.h:328,
                 from /home/user/dspatch/tests/../subprojects/catch/catch.hpp:4811,
                 from /home/user/dspatch/tests/main.cpp:3:
/home/user/dspatch/tests/../subprojects/catch/catch.hpp:7441:45: error: size of array 'altStackMem' is not an integral constant-expression
 7441 |     char FatalConditionHandler::altStackMem[SIGSTKSZ] = {};
      |                                             ^~~~~~~~
cc1plus: note: unrecognized command-line option '-Wno-vla-extension' may have been intended to silence earlier diagnostics
cc1plus: note: unrecognized command-line option '-Wno-gnu-zero-variadic-macro-arguments' may have been intended to silence earlier diagnostics
cc1plus: note: unrecognized command-line option '-Wno-return-type-c-linkage' may have been intended to silence earlier diagnostics
make[2]: *** [tests/CMakeFiles/DSPatchTests.dir/build.make:76: tests/CMakeFiles/DSPatchTests.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:162: tests/CMakeFiles/DSPatchTests.dir/all] Error 2
make: *** [Makefile:146: all] Error 2

Scripting language interface for main block

Hi there,
I have a question. When looking at the tutorial, I was wondering if the construction and ticking of a circuit inside the main block can be made more accessible through a scripting language, eg. Ruby, Python or Scheme.
I have no experience with SWIG or embedded scripting languages yet. By chance, are there already thoughts or experiences in this direction?
−Martin

sort out git version tags

Hi,
thanks for your wonderful library. I am currently trying to put together some distro packages for it, and whilst the latest release is labelled in the CMake file (and description) as "8.0.0", the output of git describe is 4.00-76-g83e39ef and the output of git describe --tags is 7.0.1-15-g83e39ef. I know there is now a tag latest-linux but it would be nice to retain separate tags for large release versions.

Thanks

Suggest renaming ReleaseThread() to ReleaseNextThread()

Hi @MarcusTomlinson ,

Just a suggestion given on a somewhat subjective basis, but the following block of code, in Component.cpp, would be easier to understand if ReleaseThread was called ReleaseNextThread instead. In that method, I read too fast and missed the "threadNo + 1" when trying to understand if re-entry into a component's Process_() method was possible, seeing the word "Next" would have been a good supplemental cue. Again, this is somewhat subjective but hopefully helpful feedback.

  if ( p->processOrder == ProcessOrder::InOrder && p->bufferCount > 1 )
  {
      // 6. wait for our turn to process
      p->WaitForRelease( bufferNo );

      // 7. call Process_() with newly aquired inputs
      Process_( p->inputBuses[bufferNo], p->outputBuses[bufferNo] );

      // 8. signal that we're done processing
      p->ReleaseNextThread( bufferNo );    // <== RENAMED
  }

Best regards.

Flow diagram

A diagram illustrating how different parts of dspatch are interconnected would be highly appreciated.

Signal update timing and simulation of programmable logic

Hi,

I'm looking into dspatch as a framework for emulating the behavior of programmable logic on an FPGA. dspatch looks perfect, except for a timing issue I cannot resolve. For example, let's talk about a simple serial circuit of three components:

 ------       ------        -----
|   A  | --> |   B  |  --> |  C  |
 ------       ------        -----

In a realistic FPGA environment with a common clock, B would only be able to process the output of A one clock tick after A produced it, rather than instantly (for most operations, anyway). Similarly, C would have a delay of one tick to B and two ticks to A, etc. From a quick review of the code, it seems to me that such delays are not included in dspatch. Instead, the tick methods of A, B and C are all called on the first clock tick and a signal can propagate from left to right in a single tick. Is that a correct summary?

I considered handling this delay explicitly inside each component, but it seems to me that this is not possible for more complex circuits without rewriting the way Circuit ticks.

need complex demo

firstly,thx for you guys offering such good code! I test DSPatch last day. and now i want write a more bigger demo.but need some help!
A1-

C1 -->D1
/
B1-

can i embeded circuit into a circuit ?
A1 is task1-->task2--->task3 (serial pipeline)
B1 is task3,task4,task5(parallel pipeline)

when and how to use ProcessOrder::NoOrder?

Tick DSPtach

Hello,

i haven't find forum so i post my question here.
just to be sure

  1. We can choose for component all component declaration, 2 tick modes:
    Series: unthreading, sequential.
    Parallel: Threading, parallelise

Isn't it?

Cordially

Crash the program

Dear All,
If I run it many times in parallel mode, it will crash the program with error: Invalid Address specified to RtlFreeHeap
when i run in series mode i dont get this error. Can anyone help me?
Thank you!

Tests failing on head

0x Buffer Efficiency (Series Mode): 24%
1x Buffer Efficiency (Series Mode): 24%
2x Buffer Efficiency (Series Mode): 48%
3x Buffer Efficiency (Series Mode): 72%
4x Buffer Efficiency (Series Mode): 91%
0x Buffer Efficiency (Parallel Mode): 55%

DSPatchTests is a Catch v1.9.3 host application.
Run with -? for options

-------------------------------------------------------------------------------
ThreadPerformanceTest2
-------------------------------------------------------------------------------
/home/nicholas/projects/DSPatch/dspatch/dspatch_git/tests/main.cpp:799
...............................................................................

/home/nicholas/projects/DSPatch/dspatch/dspatch_git/tests/main.cpp:835: FAILED:
  REQUIRE( count / 10 >= efficiencyThreshold * 0.8 )
with expansion:
  55 >= 64.0

===============================================================================
test cases:     26 |     25 passed | 1 failed
assertions: 357317 | 357316 passed | 1 failed


+++++++++++++++++++++++++++++++++++++++++

Test on both:
OS : CentOS 7 and default GCC (4.8.5)
OS : CentOS 7 and GCC (6.3.0)

Is it possible to add an exception handling method?

Is it possible to add an exception handling method?
For example, Node B depends on the output of A. When node A crashes or throws an exception, the circuit diagram stops running. Instead of continuing.
When a node throws an exception, it will force the entire circuit to stop.

is there a way to define parameters for a component?

Let's say I want to implement a subtractor component that gets two numbers as inputs, subtracts them, and outputs the result. Now I want to have a boolean parameter, named "absolute value", for this component. When the value is true, the absolute difference is sent to the output, and when the value is false, the normal difference is sent to the output.
I know I can do this by adding a third input but this does not feel good. A subtractor is expected to get two inputs. The behavior should be controlled using parameters.

Question : final in class

Other than performance and devirtualization purposes, are there other software design reasons for using the final keyword ?

what "a feedback component" mean?

        // 1. set tickStatus -> TickStarted
        p->tickStatuses[bufferNo] = internal::Component::TickStatus::TickStarted;

        // 2. tick incoming components
        for ( auto& wire : p->inputWires )
        {
            if ( mode == TickMode::Series )
            {
                wire.fromComponent->Tick( mode, bufferNo );
            }
            else if ( mode == TickMode::Parallel )
            {
                if ( !wire.fromComponent->Tick( mode, bufferNo ) )
                {
                    p->feedbackWires[bufferNo].emplace( &wire );
                }
            }
        }

        // 3. set tickStatus -> Ticking
        p->tickStatuses[bufferNo] = internal::Component::TickStatus::Ticking;

According to the code above, I think a component in stage 2 are took as a feed back component by a behind component in another thread. But in this circumstance, this component may turn to Ticking latter, why we needn't wait such a component but wait for component whose state is Ticking?

                    // wait for non-feedback incoming components to finish ticking
                    auto wireIndex = p->feedbackWires[bufferNo].find( &wire );
                    if ( wireIndex == p->feedbackWires[bufferNo].end() )
                    {
                        wire.fromComponent->p->componentThreads[bufferNo]->Sync();
                    }
                    else
                    {
                        p->feedbackWires[bufferNo].erase( wireIndex );
                    }

Are the components random ticked? Is there a better way?

        // tick all internal components
        for ( auto& component : p->components )
        {
            component->Tick( mode );
        }

        // reset all internal components
        for ( auto& component : p->components )
        {
            component->Reset();
        }

According to the code above and the fact that there is no order restriction when add components, can I assume the components are random ticked?
Is it will be better if we know the end components( eg. audio writter) in a circuit and tick them directly?
Or like the FFmpeg filter graph, schedule them accroding to their priority?

spurious auto-ticking when pipeline depth is greater than one but ticking manually

Hi,

When evaluating dspatch I've noticed some behaviour which is not correct. The basic setup is as follows:

// create a circuit with 3 "no-op" components connected in series
// these "no-op" test components simply count how many times they have been ticked
auto circuit = std::make_shared<DSPatch::Circuit>();
auto countA = std::make_shared<Dummy>("countA");
auto countB = std::make_shared<Dummy>("countB");
auto countC = std::make_shared<Dummy>("countC");
circuit->addComponent(countA);
circuit->addComponent(countB);
circuit->addComponent(countC);
circuit->ConnectOutToIn(countA, 0, countB, 0);
circuit->ConnectOutToIn(countB, 0, countC, 0);

circuit->SetBufferCount(3)   // pipeline depth of 3

// manually tick 4 times
circuit->Tick(DSPatch::Component::TickMode::Series);
circuit->Tick(DSPatch::Component::TickMode::Series);
circuit->Tick(DSPatch::Component::TickMode::Series);
circuit->Tick(DSPatch::Component::TickMode::Series);

circuit = nullptr;   // shutdown & destroy the circuit

// examine the number of times the components have been ticked, suprisingly it will be 6
if (countA->numTicks != 4) {
    printf("surprise! number of ticks should be 4, not %d\n", countA->numTicks);
}

The reason this happens can be found in the method Circuit::PauseAutoTick() at L312 of Circuit.cpp.

https://github.com/cross-platform/dspatch/blob/master/src/Circuit.cpp#L312

When the circuit is destroyed, there is no check to see if the circuit was being auto-ticked to begin with. The assumption is that it was, and there seems to be a policy to keep ticking the circuit until the currentThreadNo wraps to zero. Thus, when shutting down the auto-tick thread it appears the aim is to have the circuit be ticked an integer number of times the pipeline depth, which I can understand.

The path to L312 being hit is ~Circuit(), followed by SetBufferCount(0), then PauseAutotick(). So basically destruction of the circuit unconditionally goes through the auto-tick shutdown without checking to see if auto-ticking was active to begin with.

You might ask why a user is not auto-ticking yet having a SetBufferCount > 1. Good question. However, if user is ticking manually, as they might do when debugging, they are rightfully (I would argue) surprised to find that the circuit is being ticked more often than was specifically asked.

Bottom line, at least for me, is that the above-described behaviour is surprising and I would not consider that as correct from a user point of view.

I am available for follow-up discussion.

Again, great work on this library!

Best Regards.

Is there any way to get whether the operation of circuit->Tick() is completed?

I tested the tutorial of the project
https://github.com/cross-platform/dspatch/tree/master/tutorial

If we set
circuit->SetBufferCount(0);
Then circuit->Tick(); is executed on the main thread;
If we set
circuit->SetBufferCount(4);
Then circuit->Tick(); is executed in the sub-thread;
my question is:
When the sub-thread is running, do we have a way to get whether circuit->Tick(); has finished running?
Is it possible to add a new function to obtain the end flag of this Tick operation?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.