Plugins en C++

Heb je een losse header file die ik gewoon kan gebruiken, en die je dan hier als bijlage (als zip-file) bij je post bijvoegt?
 
Lukt niet:

Code:
git clone git@github.com:StrangeDelight/MiniaudioSample.git
Cloning into 'MiniaudioSample'...
The authenticity of host 'github.com (140.82.121.4)' can't be established.
ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Sorry man!! Toch een beetje te gehaast gepost. Ik moest weg.
Ik had je beter via de https link kunnen laten klonen zonder authenticatie. Ik ben zo gewend om eigen repo’s via ssh (+ authenticatie) uit te checken.

Via de download op github.com kun je inderdaad de losse elementen downloaden. Dus hopelijk heb je het al werkend.

Zo niet kun je kunt dit doen (gehele commando weer copy/paste naar je shell/terminal):

Code:
git clone https://github.com/StrangeDelight/MiniaudioSample.git
 
Ik zit nu met een probleempje: welke gehoorde frequentie kunnen we zinvol aan onderstaand geluid toeschrijven?



Dat is van belang als ik mijn progje met een midi keyboard wil aansturen.
 
Ik zit nu met een probleempje: welke gehoorde frequentie kunnen we zinvol aan onderstaand geluid toeschrijven?
Als dat één van de bij gevoegde samples is dan is het een C# noot. Als je de mono sample afspeelt op 48kHz dan hoor je de werkelijke noot.
 
Je kunt natuurlijk zelf een blokgolfje maken met een door jou geselecteerde frequentie en die vervolgens transponeren naar andere noten.
 
Nee - het is een geluid dat met mijn progje gegenereerd is. Er komen afhankelijk van de instellingen nog veel meer van dergelijke "gekke' geluidjes uit. Maar ik moet er een ervaren frequentie aan toeschrijven om zulke geluidjes aan toetsen van een MIDI keyboard te kunnen koppelen.
 
Mooi genoeg zo:

Screenshot.png
 
Update:

Het lukt mij niet om zonder AI werkende C++ code voor het binnenhalen van MIDI te vinden. Er waren steeds weer dingen die niet klopten. En boeken specifiek over MIDI in C++ zijn zeldzaam. Dus heb ik het ten einde raad maar direct aan AI gevraagd. Doch ook dat werkte in eerste instantie niet, maar door steeds aan AI aan te geven wat er fout ging ben ik zo net toch tot een werkend stukje code gekomen. Met dat resultaat ga ik nu verder experimenteren, en het aanpassen voor gebruik in mijn eigen progje.

Liefst heb ik degelijke boeken waarin tot in de puntjes wordt uitgelegd hoe zaken werken, maar als dat niet lukt neem ik ook genoegen met zoekresultaten, teksten en tutorials op internet. Lukt dat ook niet dan vraag ik het als laatste redmiddel direct aan Google in "AI-modus". Ik zie AI als laatste optie omdat ik het begrijpen van waar ik mee bezig ben belangrijker vind dan het behalen van een snel resultaat. Het is voor mij hobby, en geen productiewerk.
 
En als je AI niet gebruikt voor iets dat moet werken op de eerste hulp van het ziekenhuis, of in de cockpit van een vliegtuig, och...

;)
 
@ProgHead: Ik heb middels de RtMidi library functionaliteit toegevoegd om middels een Midi keyboard samples te spelen. Ik heb nu ook een ./r scriptje toegevoegd. Mocht je, zoals ik, meerdere MIDI devices hebben dan kun je middels ./r --port X aangeven welke MIDI device gebruikt moet worden. Ik kon dit helaas niet goed testen onder Linux omdat ik nu even geen Linux laptop beschikbaar heb. Via een VM leverde het wat problemen op met het USB virtual device. Ik kan dus niet garanderen dat het werkt op jouw Linux machine. RtMidi maakt gebruik van ALSA.

Ik zou deze versie even opnieuw klonen in een andere directory:

Code:
git clone https://github.com/StrangeDelight/MiniaudioSample.git metMIDI

Je krijgt dan een directory 'metMIDI' met deze versie.
 
Dat is me met RtMidi en wat AI hulp ook al een heel eind heen gelukt. Ik ben nu zo ver dat er naar de terminal geprint wordt welke toetsen ik op mijn MIDI keyboard wanneer aansla en weer loslaat. Nu moeten die gegevens alleen nog gekoppeld worden aan de generatie van bijpassende geluiden vanuit mijn progje. Ik zal later kijken of er in jouw aanpak voor mij nog verbeterpunten zitten die ik kan gebruiken. Ik wil het nu eerst zelf zover brengen dat ik gespeelde geluidjes hoor.
 
Ik worstel met de threads en de informatieoverdracht daartussen. Daarom ga ik daar eerst eens voor eenvoudige gevallen wat mee experimenteren:

code.png


Wat levert dat progje denken jullie voor output op, en hoe beredeneer je dat?
 
Je threading doet niet echt iets. Wat je typisch wilt doen is workload verdelen over threads. Ik heb hier een klein programmaatje dat priemgetallen berekent door het werk uit te besteden aan meerdere threads. Iedere thread krijgt zijn eigen struct met de beschrijving van het werk en waar de thread de gevonden priemgetallen kan opslaan. De main thread gaat vervolgens voortgang rapportage doen over de threads. Er is dus communicatie tussen de threads en het hoofdprogramma. In de struct zie je een atomic 'percent' (init op 0) dat gezet wordt door de thread en gelezen wordt door de main thread (programma). De atomicity zorgt ervoor dat schrijven en lezen van deze locatie gesynchroniseerd is. Een lees operatie wordt gedaan als een schrijf actie klaar is of een schrijf operatie wordt gedaan als een lees actie klaar is.

Als alle threads klaar zijn dan kan het hoofdprogramma veilig alle data lezen uit de individuele structs die ooit aan threads toebedeeld zijn.

C++:
// primes2.cpp - the smallest version: no command line, options are constants.
//
// NUM_THREADS threads search the numbers 1..RANGE for primes. Each thread
// gets its own PrimeRange object (its part of the range + a counter).
// While working, every thread stores its progress (0..100 %) in its object
// and the main program keeps drawing one progress bar per thread on screen.
//
// Compile:  g++ -std=c++17 -Wall -Wextra -O2 -pthread primes2.cpp -o primes2
// Run:      ./primes2

#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>
#include <vector>

const int  NUM_THREADS = 10;          // how many threads
const int  RANGE       = 1000000000;  // inspect the numbers 1..RANGE
const bool SHOW_PRIMES = false;       // true: store and print the primes too
const int  BAR_WIDTH   = 50;          // progress bar columns (1 column = 2 %)

struct PrimeRange {
    int low, high;               // the part this thread checks (inclusive)
    long long count = 0;         // primes found
    std::vector<int> primes;     // the primes themselves (only if SHOW_PRIMES)
    std::atomic<int> percent{0}; // progress 0..100; the thread writes it, main
                                 // reads it -> atomic makes that safe
};

bool isPrime(int n)
{
    if (n < 2) return false;
    for (int d = 2; d * d <= n; ++d)
        if (n % d == 0) return false;
    return true;
}

void findPrimes(PrimeRange* r)   // this is what every thread runs
{
    long long size = r->high - r->low + 1;
    for (int n = r->low; n <= r->high; ++n) {
        if (isPrime(n)) {
            ++r->count;
            if (SHOW_PRIMES) r->primes.push_back(n);
        }
        int done = (long long)(n - r->low + 1) * 100 / size;
        if (done != r->percent) r->percent = done;   // report progress
    }
    r->percent = 100;            // also for an empty range
}

// Draw one bar: a full block per 2 %, a half block for an odd 1 %.
void drawBar(int threadNo, int percent)
{
    std::cout << "Thread " << (threadNo < 10 ? " " : "") << threadNo << " [";
    for (int col = 0; col < BAR_WIDTH; ++col) {
        int p = percent - col * 2;   // how much of this column is filled: 0, 1 or 2+
        std::cout << (p >= 2 ? "█" : p == 1 ? "▌" : " ");
    }
    std::cout << "] " << (percent < 100 ? " " : "") << (percent < 10 ? " " : "")
              << percent << " %\n";
}

int main()
{
    // Divide 1..RANGE over the threads; thread 1 gets the leftovers.
    std::vector<PrimeRange> ranges(NUM_THREADS);
    int next = 1;
    for (int i = 0; i < NUM_THREADS; ++i) {
        int size = RANGE / NUM_THREADS + (i == 0 ? RANGE % NUM_THREADS : 0);
        ranges[i].low  = next;
        ranges[i].high = next + size - 1;
        next = ranges[i].high + 1;
    }

    // Start the threads, each with a pointer to its own object.
    auto start = std::chrono::steady_clock::now();
    std::vector<std::thread> threads;
    for (int i = 0; i < NUM_THREADS; ++i)
        threads.push_back(std::thread(findPrimes, &ranges[i]));

    // Show the progress bars until every thread reports 100 %.
    // "\033[<n>A" is the terminal code for "move the cursor n lines up", so
    // the bars stay in place and are overwritten instead of scrolling.
    // "\033[?25l" hides the cursor (no flickering), "\033[?25h" shows it again.
    std::cout << "\033[?25l";
    while (true) {
        bool allDone = true;
        for (int i = 0; i < NUM_THREADS; ++i) {
            int p = ranges[i].percent;
            drawBar(i + 1, p);
            if (p < 100) allDone = false;
        }
        std::cout << std::flush;
        if (allDone) break;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        std::cout << "\033[" << NUM_THREADS << "A";
    }
    std::cout << "\033[?25h";

    // Wait for the threads (they are done, this just cleans up).
    for (std::thread& t : threads)
        t.join();
    auto stop = std::chrono::steady_clock::now();

    // Report.
    long long total = 0;
    for (int i = 0; i < NUM_THREADS; ++i) {
        if (SHOW_PRIMES)
            for (int p : ranges[i].primes) std::cout << p << "\n";
        std::cout << "Thread " << i + 1 << ": " << ranges[i].low << " .. "
                  << ranges[i].high << " -> " << ranges[i].count << " primes\n";
        total += ranges[i].count;
    }
    std::cout << "\nRange 1 .. " << RANGE << " -> " << total << " primes in total\n"
              << "Time: " << std::chrono::duration<double, std::milli>(stop - start).count()
              << " ms\n";
}
 
Back
Top