diff --git a/tests/core/steam/engine/test-rand-ontology.cpp b/tests/core/steam/engine/test-rand-ontology.cpp index c203376f8..8f8dc7c27 100644 --- a/tests/core/steam/engine/test-rand-ontology.cpp +++ b/tests/core/steam/engine/test-rand-ontology.cpp @@ -44,6 +44,72 @@ namespace test { const string DUMMY_FUN_ID{"dummyFun(TestFrame)"}; + /* ========= Dummy implementation of Media processing ========= */ + + /** + * @param buff a sufficiently sized allocation to place the result data into + * @param frameNr the frame of the »source feed« to generate (determines actual random data) + * @param flavour a further seed parameter to determine the actual (reproducibly) random data + */ + void + generateFrame (TestFrame* buff, size_t frameNr, uint flavour) + { + REQUIRE (buff); + new(buff) TestFrame{uint(frameNr), flavour}; + } + + /** + * @param chanCnt size of the array of frames to generate + * @param buffArry pointer to an allocation sufficiently sized to hold `TestFrame[chanCnt]` + * @param frameNr the frame of the »source feed« to use commonly on all those frames in the output + * @param flavour a further seed parameter used as starting offest for the output's `family` parameters + * @remark this is a variation of the [dummy data generator](\ref #generateFrame), + * which immediately generates a planar block of related frames with random data, + * all seeded with the _same_ `frameNr` and _consecutive_ `family` parameters, + * which will be offset commonly by adding the \a flavour parameter. + */ + void + generateMultichan (uint chanCnt, TestFrame* buffArry, size_t frameNr, uint flavour) + { + REQUIRE (buffArry); + for (uint i=0; idata().size(); ++i) + out->data()[i] = char(param * in->data()[i]); + } + + /** + * @param out existing allocation to receive the calculated result TestFrame + * @param srcA a buffer holding the input data for feed-A + * @param srcB a buffer holding the input data for feed-B + * @param mix degree of mixing (by integer arithmetics): 100 means 100% feed-B + * @remark this function emulates a mixing or overlaying operation: + * each result byte is the linear interpolation between the corresponding inputs. + */ + void + combineFrames (TestFrame* out, TestFrame* srcA, TestFrame* srcB, int mix) + { + REQUIRE (srcA); + REQUIRE (srcB); + REQUIRE (out); + for (size_t i=0; i < srcA->data().size(); ++i) + out->data()[i] = char((1-mix) * srcA->data()[i] + mix * srcB->data()[i]); + } diff --git a/tests/core/steam/engine/test-rand-ontology.hpp b/tests/core/steam/engine/test-rand-ontology.hpp index 85eb49de3..feaaa3db0 100644 --- a/tests/core/steam/engine/test-rand-ontology.hpp +++ b/tests/core/steam/engine/test-rand-ontology.hpp @@ -30,6 +30,7 @@ #include "lib/error.hpp" +#include "lib/depend.hpp" #include "steam/engine/testframe.hpp" #include @@ -41,6 +42,20 @@ namespace engine{ namespace test { using std::string; + + /** produce sequences of frames with (reproducible) random data */ + void generateFrame (TestFrame* buff, size_t frameNr, uint flavour); + + /** produce planar multi channel output of random data frames */ + void generateMultichan (uint chanCnt, TestFrame* buffArry, size_t frameNr, uint flavour); + + /** »process« random frame date by multiply-wrapping with a parameter */ + void manipulateFrame (TestFrame* out, TestFrame* in, int param); + + /** mix two random data frames by a parameter-controlled proportion */ + void combineFrames (TestFrame* out, TestFrame* srcA, TestFrame* srcB, int mix); + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET #1367 : Dummy / Placeholder using NoArg = std::array; diff --git a/tests/core/steam/engine/testframe-test.cpp b/tests/core/steam/engine/testframe-test.cpp index dee144ce2..7ccf884d7 100644 --- a/tests/core/steam/engine/testframe-test.cpp +++ b/tests/core/steam/engine/testframe-test.cpp @@ -64,7 +64,7 @@ namespace test { * TestFrame instances can be created right away, without any * external library dependencies. A test frame is automatically * filled with random data; multiple frames are arranged in - * sequences and channels, causing the random data to be + * sequences and channels, causing the random data to be * reproducible yet different in each frame. * * To ease writing unit tests, TestFrame provides comparison @@ -77,7 +77,7 @@ namespace test { { virtual void - run (Arg) + run (Arg) { verifyBasicProperties(); verifyFrameLifecycle(); diff --git a/tests/core/steam/engine/testframe.cpp b/tests/core/steam/engine/testframe.cpp index 551d4830c..521fc1ec6 100644 --- a/tests/core/steam/engine/testframe.cpp +++ b/tests/core/steam/engine/testframe.cpp @@ -25,8 +25,8 @@ */ -#include "steam/engine/testframe.hpp" #include "lib/error.hpp" +#include "steam/engine/testframe.hpp" #include @@ -83,7 +83,7 @@ namespace test { * Some tests might rely on the actual memory locations, using the * test frames to simulate a real input frame data stream. * @param CHA the maximum number of channels to expect - * @param FRA the maximum number of frames to expect per channel + * @param FRA the maximum number of frames to expect per channel * @warning choose the maximum number parameters wisely. * We're allocating memory to hold a table of test frames * e.g. sizeof(TestFrame) * 20channels * 100frames ≈ 2 MiB @@ -193,7 +193,7 @@ namespace test { : distinction_(o.distinction_) , stage_(CREATED) { - memcpy (data_, o.data_, BUFFSIZ); + memcpy (buffer_, o.buffer_, BUFFSIZ); } TestFrame& @@ -205,7 +205,7 @@ namespace test { { distinction_ = o.distinction_; stage_ = CREATED; - memcpy (data_, o.data_, BUFFSIZ); + memcpy (buffer_, o.buffer_, BUFFSIZ); } return *this; } @@ -245,7 +245,7 @@ namespace test { TestFrame::contentEquals (TestFrame const& o) const { for (uint i=0; i -#include +#include "lib/integral.hpp" + +#include namespace steam { @@ -63,12 +64,15 @@ namespace test { CREATED, EMITTED, DISCARDED }; - static const size_t BUFFSIZ = 1024; + static constexpr size_t BUFFSIZ = 1024; + using _Arr = std::array; uint64_t distinction_; StageOfLife stage_; - char data_[BUFFSIZ]; + /** inline storage buffer for the payload media data */ + alignas(uint64_t) + std::byte buffer_[sizeof(_Arr)]; public: ~TestFrame(); @@ -95,6 +99,10 @@ namespace test { friend bool operator== (TestFrame const& f1, TestFrame const& f2) { return f1.contentEquals(f2); } friend bool operator!= (TestFrame const& f1, TestFrame const& f2) { return !f1.contentEquals(f2); } + + /** Array-style direct access to the payload data */ + _Arr& data() { return * std::launder (reinterpret_cast<_Arr* > (&buffer_)); } + _Arr const& data() const { return * std::launder (reinterpret_cast<_Arr const*> (&buffer_)); } private: bool contentEquals (TestFrame const& o) const; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 2c57f5f68..6ed125fc1 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -13740,9 +13740,7 @@ - - - +

...will sagen, @@ -14518,9 +14516,7 @@ - - - +

als Subklasse von UICoord @@ -16100,9 +16096,7 @@ - - - +

Zwei Fälle sind hier zu unterscheiden: @@ -18604,9 +18598,7 @@ - - - +

In Summe viel eleganter. @@ -46714,9 +46706,7 @@ - - - +

die Frage ist, wie generisch ist eigentlich ein Command-Aufruf selber? @@ -47369,9 +47359,7 @@ - - - +

Mutator verwendet einen Binder @@ -47859,9 +47847,7 @@ - - - +

this is (probably) the only operation which entirely messes up the mutator state @@ -48076,9 +48062,7 @@ - - - +

Verb muß den @@ -48305,9 +48289,7 @@ - - - +

das ist die schlankeste Lösung, die ästhetisch befriedigt. @@ -57023,9 +57005,29 @@ + + + + + + + + + + + + + + +

+ also per reinterpret-cast mit std::launder, storage als std::byte mit sauberer Alignment-Angabe +

+ + +
+ + - - @@ -80336,7 +80338,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -85728,6 +85730,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + +
@@ -85735,6 +85741,17 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + @@ -87669,7 +87686,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + @@ -91410,8 +91427,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
...darüber hab ich damals viel nachgedacht: eine generische Implementierung der Blatt-Iteration ist nicht so einfach zu realisieren, da man einem Element nicht anhand generischer Eigenschaften ansehen kann, ob es ein Blatt ist oder noch weiter expandiert werden kann. Ein Ausweg wäre, das Element versuchsweise zu expandieren und es selber nur zurückzuliefern, wenn die Expansion leer ist. Davon habe ich damals aber Abstand genommen, da es (a) erfordert, den Aufwand für die Expansion stets und für jedes Element zu leisten und (b) dann irgendwie eine Interaktion mit dem internen Stack stattfinden muß, und das dann auch noch rekursiv oder repretitiv  (und das wurde mir dann alles zu kompliziert)

- - +
@@ -91421,8 +91437,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
...und deshalb können wir erst expandAll() machen, und dann die inneren Blattknoten einfach nachträglich wegfiltern, woduch automatisch weiter repetitiv konsumiert wird.

- -
+
@@ -91442,8 +91457,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
....aus Sicherheits-Gründen: der Container soll irgendwo „daneben“ in sicherer Storage liegen

- - + @@ -91466,8 +91480,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
Der Trick ist: die Funktion nimmt ein Template-Argument, das aber als Default den forward-deklarierten STL-Container hat. Scheint mit meinem GCC zu klappen .... ich bin da aber sehr skeptisch, denn die Signatur mit den Template-Parametern könnte sich in Zukunft schon noch erweitern.....

- - +
@@ -91509,6 +91522,52 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -91548,9 +91607,10 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- + - + +
@@ -92115,11 +92175,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - + + - + + @@ -92150,13 +92211,13 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - + + + - - + + @@ -92315,7 +92376,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- +