Wie mit waveOutWrite() zeitlich synchronisieren?



  • Hallo,
    Mein Programm soll in vorgegebenen Intervallen immer 50 Millisekunden lang nen Ton ausgeben. Dies mach ich mit den waveOut-Funktionen, so ähnlich wie es in charles petzolds Buch beschrieben ist.
    Auch wie im Buch beschrieben arbeite ich mit 2 Puffer, die ich nacheinander waveOutWrite übergebe.
    Ich habe der waveOutWrite-Funktion eine CALLBACK-Funktion übergeben, die sich meldet, wenn ein Puffer leer ist. Ist dies der Fall wird dieser wieder mit den Audioinformationen gefüllt. Währenddessen wird der andere Puffer von der Soundkarte abgearbeitet u.s.w., damit eben keine Lücken im Audiosignal entstehen.
    Damit gebe ich ja nicht "on the fly" die Audioinformationen - was ich jetzt schreibe, wird erst in z.b. 100 ms zu hören sein. Und das ist das Problem - ich möchte zu den Pieptönen grafische Informationen liefern, die eben genau im richtigen Moment (wenn es Piept), sich aktualisieren müssen.
    Wie stell ich das an?
    Ich habe probehalber einfach ne Schleife gemacht, die mit GetTickCount() oder dem Performance-Counter im gleichen Intervall die Grafik aktualisiert. Doch auch wenn Sound und Grafik gleichzeitig startet, schon nach ein paar Sekunden ist es völlig daneben. Oder wenn ich ein rechenintensives Programm starte, wird manchmal die Audioausgabe verzögert.

    Womit ich auch nicht glücklich bin, ist meine Funktion, den Puffer zu füllen:

    void FillBuffer(char *pBuf, int iSpeed)
    {
    	static double	fAngle;
    	static double	dMSDone;
    	int i;
    
    	double dTickLen = 60000.0 / iSpeed;
    
    	for(i = 0; i < OUT_BUFFER_SIZE; i++)
    	{
    		if(dMSDone < BEEP_LENGTH)
    		{
    			// Beep:
    			pBuf[i] = (char) (127 + 127 * sin(fAngle));
    			fAngle += 2* PI * BEEP_FREQUENCE / SAMPLE_RATE;
    			if(fAngle > 2 * PI)
    				fAngle -= 2 * PI;
    		}
    		else
    		{
    			// "Ruhe":
    			pBuf[i] = (char)0x80;
    		}
    		// 1 Byte stellt (1000 Millisekunden) / (SAMPLE_RATE) Millisekunden dar.
    		// Um diese Zeit wird dMSDone erhöht.
    		dMSDone += 1000.0 / SAMPLE_RATE;
    		if(dMSDone >= dTickLen)	// 1 Tick+Pause verstrichen? -> neuer Tick?
    			dMSDone = 0;
    	}
    }
    

    iSpeed ist dabei die Anzahl der Pieptöne pro Minute. BEEP_LENGTH sind wie oben erwähnt 50 ms.
    Es wird eben anhand der geschriebenen Bytes festgestellt, wie viel Zeit verging, und nicht eine Zeit "gemessen".

    Hoffe mir kann jemand helfen 🙂

    MfG



  • hm hab grad die Funktionen waveOutPause und waveOutRestart entdeckt^^
    ich probiers mal damit.
    mfg


Anmelden zum Antworten