Sinussignal erzeugen



  • Hallo,

    ich bin ein ziemlicher Frischling in C++ Programmierung bzw. komplett im Programmieren. Jetzt brauche ich für ein bestimmtes Programm ein einfaches Sinussignal. Ich habe schon viele Foren durchsucht und mich durch Google gewühlt, aber alles was ich finde ist einfach zu komplex. Ich brauche keinen Sinus Ton, das wird oft beschrieben, aber ist wie gesagt zu komplex.
    Ich nutze Visual C++ 6 und möchte wie gesagt ein einfaches Sinussignal erzeugen, z.B. mit einer Frequenz von 50Hz, die muss auch gar nicht variabel sein oder sonstwas. Ich hoffe ihr könnt mir helfen, sitz da nämlich schon ziemlich lange vor dem Problem.

    Vielen Dank
    Laura



  • Du meinst sowas wie:

    SinusSignal(50);
    

    Das "SinusSignal" sieht halt aus wie:
    http://www.tmsoft.com/tutorial-sound.html



  • Jochen Kalmbach schrieb:

    Du meinst sowas wie:

    SinusSignal(50);
    

    Ehrlich gesagt weis ich nicht ob ich sowas meine. Soll das eine Funktion sein? Ich finde dazu keine Referenz. Was macht denn diese Funktion?

    Jochen Kalmbach schrieb:

    Das "SinusSignal" sieht halt aus wie:
    http://www.tmsoft.com/tutorial-sound.html

    Das verstehe ich auch nicht ganz, was meinst du mit "sieht halt aus wie"? Meinst du die WaveFormat Struktur? Kann ich damit das Signal generieren? Ich habe das Programm getestet und mein PC gibt auch einen Sound aus.
    Wie gesagt, ich bin ziemlicher Anfänger und glaube ein Programm das die Soundkarte anspricht ist einfach ein bisschen zu schwierig für mich zu verstehen. Normalerweise kann ich Quellcode ganz gut lesen und verstehen, das trifft bei diesem Programm allerdings nicht so wirklich zu.

    Vielen Dank schonmal für deine Hilfe.



  • War das ganze jetzt eine Feststellung der Art: "Ich kann C/C++ nur verstehe nicht wie es geht", oder wo war jetzt die Frage?



  • Also zuerst mal war die Frage, was ist

    SinusSignal(50);
    

    ? Sieht aus wie eine Funktion, ich kenne sie aber nicht und finde auch nichts dazu in Google oder msdn.

    Danach wollte ich wissen was du mir mit diesem Tutorial sagen möchtest. Ich hatte ja geschrieben dass ich schon viele Seiten gefunden habe, die einem zeigen wie man einen Sinus Ton ausgibt. Da ich aber Anfänger bin, finde ich mich in den Quelltexten die so etwas beschreiben nicht zurecht und kann einfach nicht rauslesen wo das reine Signal generiert wird.

    Ich kann einfache Programme lesen und verstehen, im selber entwerfen bin ich noch nicht sehr gut. Das meine ich wie bei einer Fremdsprache, man versteht eigentlich alles wenn einer mit einem spricht, selbst sprechen kann man allerdings nur schlecht.

    Mein Problem ist, ich muss ein Sinussignal auf einem DSP generieren das ich dann weiter geben kann. Leider ist mein Wissen in C++ sehr beschränkt, da ich erst einen Anfänger Kurs belegt hatte.

    Ich hoffe nun mich verständlich ausgedrückt zu haben und mein Problem vielleicht etwas klarer dargestellt zu haben.

    Vielen Dank.



  • Die Funktion gibt es auch nicht und musst Du dir selbst schreiben.

    Hast DU keine APi zum DSP?



  • Ach so, das erklärt natürlich warum ich nichts finde.

    Ich habe zumindest keine richtige API, nur ein paar Funktionen wie ich auf den DSP schreiben oder von ihm lesen kann. Aber das generiert mir ja noch kein Signal.

    Also ich hab jetzt mal so überlegt, ich nehme einfach die Sinusformel:

    y = a * sin (2 * PI * t * f + p)

    Die Amplitude setze ich auf 1 und eine Phasenverschiebung brauche ich auch nicht, das beschränkt die Formel auf:

    y = sin (2 * PI * t * f)

    PI kann ich dank

    #ifndef M_PI
    #define M_PI    3.14159265358979323846f
    #endif
    

    mit M_PI nutzen.

    Das Signal sollte kontinuierlich sein, deshalb brauche ich jetzt eine Zeit. Dazu würde ich gerne die System Clock nutzen, ich hab schonmal irgendwie hinbekommen dass mir die Zeit seit dem Start des Systems in ms ausgegeben wird, aber ich habe vergessen wie das ging, vielleicht kann mir da nochmal wer auf die Sprünge helfen.

    Mit einer Schleife sollte sich ja dann diese Zeit nutzen lassen ein kontinuierliches Signal zu generieren, oder liege ich da falsch?

    Die Frequenz würde ich dann gerne z.B. auf 50Hz festlegen. Allerdings weis ich auch noch nicht so ganz wie. Ich müsste doch irgendwie festlegen können dass 1Hz = 1/s ist und mit der System Clock sagen was eine Sekunde ist.



  • Das mit der Systemzeit habe ich mittlerweile wieder herausgefunden, geht ja mit

    GetTickCount();
    


  • Ich habe folgendes geschrieben:

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <windows.h>
    
    #ifndef M_PI
    #define M_PI    3.14159265358979323846f
    #endif
    
    using namespace std;
    
    int main()
    {
    	while(true)
    	{
    		int Uptime = GetTickCount() * 1000;
    
    		float y;
    		y = sin(2 * M_PI * Uptime);
    		cout << y;
    		cout << endl;
    
    		Sleep(50);
    		system("cls");
    	}
    
    	cin.get();
    	return 0;
    }
    

    So bekomme ich super Werte für ein Sinussignal. Endlich! 😃



  • Oh verdammt, jetzt hab ich glatt die Frequenz vergessen! Sorry, da muss ich wohl doch noch mal ein bisserl weiter überlegen. 😡



  • omega = 2*Pi*f 😉
    Ansonsten noch als Hinweis: GetTickcount wird nur bis maximal 500Hz reichen für höhere Frequenzen benötigst du einen Multimediatimer. Stichwort: QueryPerformanceTimer.



  • Das mit der Frequenz ist mir ja dann auch noch aufgefallen. Aber danke für den Hinweis.

    Mein Code sieht jetzt so aus:

    #include <iostream>
    #include <stdio.h>
    #include <math.h>
    #include <windows.h>
    
    #ifndef M_PI
    #define M_PI    3.14159265358979323846f
    #endif
    
    using namespace std;
    
    int main()
    {
    	while(true)
    	{
    		int Uptime = GetTickCount();
    
    		/*GetTickCount() liefert die Anzahl der Millisekunden
    		die verstrichen sind, seitdem Windows gestartet wurde.*/
    
    		cout << Uptime << endl << endl;
    
    		float y;
    		float f = 5000 / (1 * 1000);
    		y = sin(2 * M_PI * Uptime * f);
    		cout << y;
    		cout << endl;
    
    		Sleep(50);
    		system("cls");
    	}
    
    	cin.get();
    	return 0;
    }
    

    connan schrieb:

    Ansonsten noch als Hinweis: GetTickcount wird nur bis maximal 500Hz reichen für höhere Frequenzen benötigst du einen Multimediatimer. Stichwort: QueryPerformanceTimer.

    Das Problem besteht jetzt eher anders herum. Ich bekomme erst Werte bei Frequenzen ab 1000Hz. Bei 500Hz gibt er mir immer 0 aus. Woran liegt das denn? Ich werde mir diesen QueryPerformanceTimer jetzt mal anschauen ob das damit dann funktioniert. Danke für den Hinweis.
    Mich würde aber wirklich interessieren woran es liegt dass ich dann keine Werte bekomme. Also falls da wer ne Antwort hat, ich freue mich.



  • connan schrieb:

    Stichwort: QueryPerformanceTimer.

    Du meinst den QueryPerformanceCounter, oder? Ich hab mich da jetzt mal in der MSDN drüber informiert, das Problem ist, dass wenn ich richtig verstanden habe ich Threads nutzen müsste um den einzubauen. Naja und das kann ich einfach noch nicht. Ich bin also über jede Hilfe dankbar.



  • Ich glaube ich habe schon wieder einen Rechenfehler entdeckt. Da ja die Zeit von GetTickCount in ms übergeben wir muss ich bei der Frequenz ja auch mit ms rechnen und da ist mein Fehler, es müsste heißen:

    float f = 5000 / 0.001;
    

    Kann das irgendwer bestätigen? Mit dem Umrechnen hatte ichs noch nie.

    Jetzt geht es übrigens mit allen Frequenzen, egal ob 5Hz oder 500000Hz.



  • laura84 schrieb:

    connan schrieb:

    Stichwort: QueryPerformanceTimer.

    Du meinst den QueryPerformanceCounter, oder? Ich hab mich da jetzt mal in der MSDN drüber informiert, das Problem ist, dass wenn ich richtig verstanden habe ich Threads nutzen müsste um den einzubauen. Naja und das kann ich einfach noch nicht. Ich bin also über jede Hilfe dankbar.

    Du hast natürlich recht, sorry. Threads brauchst du allerdings keine, am Ende funktioniert das genauso wie GetTickCount nur sehr viel genauer.

    Ansonsten lässt sich eine Frequenz natürlich nicht in 'Millisekunden' umrechnen. Aber man kann Millisekunden in Sekunden umrechnen 😉



  • connan schrieb:

    ... am Ende funktioniert das genauso wie GetTickCount nur sehr viel genauer.

    Das habe ich ausprobiert, aber ich musste dann Übergabeparameter angeben und da wusste ich dann nicht welche. In einem Beispiel in der MSDN ist einfach eine Art Start Variable übergeben, aber dann hat er immer nur wieder eine 1 ausgegeben.
    Also wenn ich das so mache:

    int main()
    {
    	LARGE_INTEGER start;
    
    	while(true)
    	{
    		int Uptime = QueryPerformanceCounter(&start);		
    
            float y;
    		float f = 50000 / 0.001;
    		y = sin(2 * M_PI * Uptime * f);
    		cout << y;
    		cout << endl;
    
    		Sleep(50);
    		system("cls");
    	}
    
    	cin.get();
    	return 0;
    }
    

    Dann gibt er immer eine 1 aus und errechnet natürlich auch immer nur einen einzigen Wert. Was mache ich denn da falsch?

    connan schrieb:

    Ansonsten lässt sich eine Frequenz natürlich nicht in 'Millisekunden' umrechnen. Aber man kann Millisekunden in Sekunden umrechnen 😉

    Ja, da hast du natürlich recht. So meinte ich das aber auch, hab mich wohl etwas falsch ausgedrückt. 😃



  • QueryPerformanceCounter gibt einen bool zurück, das eigentliche Ergebniss steht in 'start' aber du must das ganze auch noch über QueryPerformanceFrequency und Differenzbildung in eine Zeit umwandeln. Aber mir stellt sich die Frage ob du das überhaupt brauchst!? Was genau willst Du denn machen?
    Edit: Ich kann mir nicht wirklich vorstellen, das du jeden sample einzeln zum DSP übertragen kannst. Wie sehen denn die API- Funktionen aus?



  • Das hat sich jetzt eh erledigt. Ich soll den Sinus direkt auf dem DSP generieren und da kann ich mit Windows Programmierung nichts mehr anfangen.
    Jetzt muss ich mich erst mal in die Hardware einlesen und versuchen den Timer auf dem DSP anzupacken. Das kann dauern. 😞
    Aber vielen Dank für deine Hilfe.


Anmelden zum Antworten