Blöcke in Array nach links schieben

  • C++/CLI

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von simpelSoft.

    Blöcke in Array nach links schieben

    Hallo zusammen,

    ein bisschen peinlich, ich frage trotzdem mal hier nach :rolleyes: .
    Ich habe ein Array mit der festen Länge von 2048 und dem Datentyp int16_t, also short short samplesLeft[2048].
    Es besteht "gedanklich" aus 16 Blöcken mit jeweils 128 Werten.



    Bei jedem Durchgang wird auf der rechten Seite ein neuer Block mit 128 Werten gespeichert.
    Vorher soll sich das ganze Array um 128 Bytes nach links schieben, also der erste Block wandert links raus und rechts wird der neue Block eingefügt.

    Ich komme einfach nicht auf eine einfache und schnelle Lösung und bitte um HIlfe ?( .
    Das Ganze soll für ein C++ Arduino Projekt sein.
    @simpelSoft Wenn Du mit CLI arbeitest, hast Du doch Zugriff auf das Framework:
    docs.microsoft.com/de-de/dotne…eric.queue-1?view=net-5.0
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @simpelSoft OK, dann geht es natürlich nicht.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Nein ich meine die std::queue oder std::dequeue. Die solltest du so oder so haben. Ich hab mal einen STM32 programmiert und da gab's sogar schon C++17. War GCC glaube ich. Die Standardbibliothek hast du immer, egal auf welcher Platform.
    Man sollte keine std-Artikel am Arduino verwenden, da die einzelnen Dinger einfach zu groß sind für den winzigen Speichervorrat.
    Arduino hat Zugriff deshalb darauf abgeschalten. Man kann es zwar manuell wieder zuschalten, sollte man aber nicht. STM spielt da in einer ganz anderen Liga.

    Nein, du kannst dir auch einfach selbst eines dieser Dinger basteln, ist auch nicht sehr schwierig.
    Ich könnte dir hier einen zirkularen, zwei-dimensionalen Puffer empfehlen, welcher in 16 Mengen mit jeweils 128 Abtastwerten arbeitet. Also sowie

    C-Quellcode

    1. uint16_t [16][128]
    , und über die push und pop Funktionen kannst du dann den Blockaustausch vornehmen.
    ----------------------------------------------------------------------------------------------------------------------

    Hier könnte meine Signatur stehen, aber die ist mir abfußen gekommen.

    ----------------------------------------------------------------------------------------------------------------------

    Elanda schrieb:

    ch könnte dir hier einen zirkularen, zwei-dimensionalen Puffer empfehlen


    Vorerst - vielen Dank für die Anregung!
    Über Circular-Buffer aka Ringpuffer hatte ich schon gelesen, aber es übersteigt meinen Horizont || .
    Ich kämpfe dauernd mit diesem Arduino-C++ und fühle mich bei solchen Dingen recht hilflos.

    Es geht darum, dass mich die derzeitige Lösung sehr viel Zeit kostet.
    In zwei Arrays (Stereo) a 2048 shorts werden Audiosamples in 128byte Blöcken reingeschaufelt und das in einer Schleife.
    Jeder Block braucht 2,9ms, also x16, fast 50ms insgesamt.
    Die Samples werden dann in der Hauptschleife pro Durchgang abgearbeitet und das bremst eben gewaltig bei ca. 50ms.
    Deswegen die Idee, immer nur einen Block reinzuschieben und den Rest shiften.

    Momentan sieht das so aus:

    Die Sample-Puffer:

    C-Quellcode

    1. int16_t samplesLeft[2048] = { 0 };
    2. int16_t samplesRight[2048] = { 0 };


    Die Schleife, um die Blöcke reinzuspeichern:

    C-Quellcode

    1. /// <summary>
    2. /// Get Samples For Left And Right Channel
    3. /// </summary>
    4. /// <returns></returns>
    5. void GetSamples(uint16_t blocks) {
    6. if (queue1.available() >= blocks && queue2.available() >= blocks) {
    7. for (byte i = 0; i < blocks; i++) {
    8. memcpy(&samplesLeft[128 * i], queue1.readBuffer(), 256);
    9. memcpy(&samplesRight[128 * i], queue2.readBuffer(), 256);
    10. queue1.freeBuffer();
    11. queue2.freeBuffer();
    12. }
    13. }
    14. }


    Die variable 'blocks' hat momentan den Wert 16.
    Bitte von queue1 und queue2 nicht verwirren lassen, die Blöcke a 128byte werden von einer Audio-Lib bereitgestellt und können dort abgeholt werden, wenn die "queu" für beide Kanäle gefüllt ist.

    Ich weiß, dass Deine Lösung perfekt wäre, kann es aber nicht umsetzen.
    Ohje, ich glaube, die ganze Idee ist für die Tonne ;( !
    Wenn ich die 16 Sampleblöcke nicht sofort hintereinander abhole wenn sie bereitstehen, sondern häppchenweise mit Auswertung zwischendurch, dann habe ich ja keine Garantie, das sie auch zusammenpassen.
    Somit ergibt sich eine Fragmentierung der Daten.