Problem mit Rückgabewerten von Timer und Funktionen
Hallo! Inzwischen weiß ich gar nichts mehr und mache mir immer mehr kaputt. Darum frage ich nun hier voller Hoffnung.
Also ich schreibe gerade an einem Programm, welches mir die Frequenz, welche am Microphoneingang meiner Soundkarte anliegt, messen soll.
Das mache ich so erstmal über das *piep* Direct X da ich nichts anderes gefunden habe was mir es ermöglicht den Buffer der Soundkarte zu lesen.
Habe also DirectX8 im meinem VB 2008 Express-Projekt eingebunden. Geht auch.
Ich krieg auch schon Frequenzen. Aber da ist nun ein Problem.
Ich muss zuerst einen Buffer erstellen und dann darin "Sound" aufnehmen. Das kostet Zeit. Dann muss die Aufnahme gestoppt werden und dann erst kann der Buffer ausgelesen werden. Das kostet wieder Zeit. Das heißt ich kann nicht einfach nur ein Sub schreiben was einen Sekundären Buffer erzeugt, und dann nach zwei Zeilen Code wieder ausließt.
Da kommt zurecht eine Fehlermeldung, dass sich noch keine Daten in dem Buffer befinden bzw. ein Array der größe Nothing.
Also kam mir der Timer in den Sinn. Da frage ich nun relativ umständlich alle 0.5 Sekunden ab, ob sich Daten im Buffer befinden. Wenn ja dann wird gestoppt und ausgelesen.
So. Und nun weiß ich nicht, wie ich die Daten weiterverarbeiten soll. Denn ich habe viele verschiedene Funktionen, die diese DAten benötigen, aber wenn ich z.B. eine Function aufrufe läuft die einmal ab und wenn dann gerade zu der Zeit nix im Buffer war dann bricht die ab und ende. Ich könnte auch eine Do Loop Schleife machen, aber das könnte eine Endlosschleife werden und ist nicht das wahre. Zumal ich immer noch ein Problem mit einer Beschreibung von einem Buffer habe. Der gibt mir manchmal 0 zurück und dann stirbt alles. Warum weiß ich nicht.
Was ich bräuchte wäre eine Möglichkeit den Buffer zu "machen", dann die Function warten zu lassen bis der gefüllt ist und dann erst mit der Fortsetzung des weiteren Code weitermacht. Aber wie soll ich einer Private Function sagen, "warte"?
Und einen Timer als Function zu deklarieren und darin auch noch Varibalen übergeben zu lassen erlaubt mir VB nicht. Wäre sowieso nicht das Wahre.
Dann habe ich noch von Events gehört. Ich hoffe ich hab das richtig verstande. Man kann also eine Function dann ausführen lassen, wenn z.B. ein bestimmtes Ereignis
wärend der Programmlaufzeit auftritt.? Wenn ja dann könnte man das doch so lösen:
Ich bastle da auf die Soundkartenschnittstelle so ein Event drauf. Wenn die Soundkarte dann einen Sec.Buffer mit Daten gefüllt hat soll z.B. eine andere Funktion wissen, jetzt kann ich die Daten abrufen und meinen Code fortsetzen. Oder so ähnlich. Da würde mir sogar eine art "Realtime" Verarbeitung möglich sein, was ich auch nicht schlecht finden würde.
Und da bin ich kläglich an allen Versuchen gescheitert so was mit Events zu realisieren, zumal ich mit events so noch nie gearbeitet habe.
Da mein Projekt riesig ist kann ich hier nicht allen Code posten aber ich versuche mal eine Art Skizze zu machen.
Also:
Programm startet -> User drückt Knopf (Frequenz messen) -> Dann soll Code warten bis Soundkarte Buffer voll hat -> Dann Daten lesen und weiterverarbeiten.
Und das soll NICHT mit einem Timer passieren. Sondern mit einem Event oder irgendwas in der Richtung was kein Timer ist.
Gibt es da was? Oder ein Lösungsvorschlag/Idee?
Ich würde mich tierisch freuen, wenn man mir da ein bisschen unter die Arme greifen könnte, denn das Projekt wäre für mich schon wichtig UND auch für andere.
Wie gesagt Code kann ich so nicht posten, da das dann im Prinzip alles wäre und das ist bis jetzt eine ganze Menge, da im Moment nix geht und auch alles irgendwie mit timern und do loops und Public Variablen gelöst ist, was einfach nur grausam ist.
Bitte helft mir!
florengray
Also ich schreibe gerade an einem Programm, welches mir die Frequenz, welche am Microphoneingang meiner Soundkarte anliegt, messen soll.
Das mache ich so erstmal über das *piep* Direct X da ich nichts anderes gefunden habe was mir es ermöglicht den Buffer der Soundkarte zu lesen.
Habe also DirectX8 im meinem VB 2008 Express-Projekt eingebunden. Geht auch.
Ich krieg auch schon Frequenzen. Aber da ist nun ein Problem.
Ich muss zuerst einen Buffer erstellen und dann darin "Sound" aufnehmen. Das kostet Zeit. Dann muss die Aufnahme gestoppt werden und dann erst kann der Buffer ausgelesen werden. Das kostet wieder Zeit. Das heißt ich kann nicht einfach nur ein Sub schreiben was einen Sekundären Buffer erzeugt, und dann nach zwei Zeilen Code wieder ausließt.
Da kommt zurecht eine Fehlermeldung, dass sich noch keine Daten in dem Buffer befinden bzw. ein Array der größe Nothing.
Also kam mir der Timer in den Sinn. Da frage ich nun relativ umständlich alle 0.5 Sekunden ab, ob sich Daten im Buffer befinden. Wenn ja dann wird gestoppt und ausgelesen.
So. Und nun weiß ich nicht, wie ich die Daten weiterverarbeiten soll. Denn ich habe viele verschiedene Funktionen, die diese DAten benötigen, aber wenn ich z.B. eine Function aufrufe läuft die einmal ab und wenn dann gerade zu der Zeit nix im Buffer war dann bricht die ab und ende. Ich könnte auch eine Do Loop Schleife machen, aber das könnte eine Endlosschleife werden und ist nicht das wahre. Zumal ich immer noch ein Problem mit einer Beschreibung von einem Buffer habe. Der gibt mir manchmal 0 zurück und dann stirbt alles. Warum weiß ich nicht.
Was ich bräuchte wäre eine Möglichkeit den Buffer zu "machen", dann die Function warten zu lassen bis der gefüllt ist und dann erst mit der Fortsetzung des weiteren Code weitermacht. Aber wie soll ich einer Private Function sagen, "warte"?
Und einen Timer als Function zu deklarieren und darin auch noch Varibalen übergeben zu lassen erlaubt mir VB nicht. Wäre sowieso nicht das Wahre.
Dann habe ich noch von Events gehört. Ich hoffe ich hab das richtig verstande. Man kann also eine Function dann ausführen lassen, wenn z.B. ein bestimmtes Ereignis
wärend der Programmlaufzeit auftritt.? Wenn ja dann könnte man das doch so lösen:
Ich bastle da auf die Soundkartenschnittstelle so ein Event drauf. Wenn die Soundkarte dann einen Sec.Buffer mit Daten gefüllt hat soll z.B. eine andere Funktion wissen, jetzt kann ich die Daten abrufen und meinen Code fortsetzen. Oder so ähnlich. Da würde mir sogar eine art "Realtime" Verarbeitung möglich sein, was ich auch nicht schlecht finden würde.
Und da bin ich kläglich an allen Versuchen gescheitert so was mit Events zu realisieren, zumal ich mit events so noch nie gearbeitet habe.
Da mein Projekt riesig ist kann ich hier nicht allen Code posten aber ich versuche mal eine Art Skizze zu machen.
Also:
Programm startet -> User drückt Knopf (Frequenz messen) -> Dann soll Code warten bis Soundkarte Buffer voll hat -> Dann Daten lesen und weiterverarbeiten.
Und das soll NICHT mit einem Timer passieren. Sondern mit einem Event oder irgendwas in der Richtung was kein Timer ist.
Gibt es da was? Oder ein Lösungsvorschlag/Idee?
Ich würde mich tierisch freuen, wenn man mir da ein bisschen unter die Arme greifen könnte, denn das Projekt wäre für mich schon wichtig UND auch für andere.
Wie gesagt Code kann ich so nicht posten, da das dann im Prinzip alles wäre und das ist bis jetzt eine ganze Menge, da im Moment nix geht und auch alles irgendwie mit timern und do loops und Public Variablen gelöst ist, was einfach nur grausam ist.
Bitte helft mir!
florengray
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 127860
Url: https://administrator.de/contentid/127860
Ausgedruckt am: 25.11.2024 um 08:11 Uhr
4 Kommentare
Neuester Kommentar
Hi florengray,
warum sollte das nicht mit einer Endlosschleife gehen, auch solche Schleifen
brauchen nur solange zu laufen, bis ein bestimmter Wert erreicht ist, oder gar
solange, bis z.B. der User durch Anklicken eines Menüpunkts eine Variable ändert.
Ein Beispiel aus einem Programm.
An einer bestimmten Stelle im Programm(oder in einer Prozedur/Funktion)
wird folg. Prozedur aufgerufen:
Also auto zeit_wert.
Erklärung:
Timer gibt einen Wert vom Typ Single zurück, der die Anzahl der seit Mitternacht vergangenen Sekunden angibt.
Heut Mittag um 12:00 würde also die Variable Zeit mit dem Wert 43200(Sekunden) belegt.
In der Loop-Zeile wird nun immer wieder Timer aufgerufen und von dem Wert wird Zeit abgezogen.
Da der Timer immer größer wird, so ist der Ausdruck Timer - Zeit natürlich auch irgendwann
größer als Tempo / 10.
Dann bricht die (scheinbare) Endlosschleife ab und ein(e) Programm/Prozedur/Funktion läuft weiter.
Das funktioniert z.B. auch innerhalb einer For-Schleife. Heißt, die Abarbeitung
der Schleife geht genau da nach einer bestimmten Zeit weiter, wo die Prozedur
aufgerufen wird.
Was ich jetzt versuchen würde . . .
Diese Prozedur in eine Function umschreiben, damit ein Wert zurückgegeben wird, z.B.:
Jetzt könnte man zwei Wege gehen.
Der erste wäre, den Ansatz oben komplett umschreiben, und innerhalb der Function den Buffer
der Soundkarte auslesen und eine Variable damit füllen.
Als Abbruchkriterien kämen dann zwei in Frage: Ich prüfe ob was gelesen wurde und beende die Schleife,
oder ich prüfe, ob die Variable irgendwann eine(n) bestimmte(n) Größe/Inhalt hat und beende dann.
Das könnte allerdings wirklich eine Endlosschleife werden, falls der Buffer der Soundkarte
nicht gelesen werden kann.
Der zweite Weg wäre, den Ansatz oben zu erweitern. Die Schleife versucht in einem definiertem Zeitraum
den Buffer auszulesen, bricht dann ab und gibt das Ergebnis zurück.
Innerhalb eines Programms oder einer Function/Prozedur wird dann eine Variable
mit dem Rückgabewert dieser Function initialisiert und ausgewertet:
Da ich zum Testen kein VB installiert habe und auch nicht weiß, wie man die Soundkarte ausliest(aber das kannst du ja),
ist das natürlich erstmal nur Theorie. Aber vielleicht hilft es dir ja ein Stück weiter.
Gruß
Günni
warum sollte das nicht mit einer Endlosschleife gehen, auch solche Schleifen
brauchen nur solange zu laufen, bis ein bestimmter Wert erreicht ist, oder gar
solange, bis z.B. der User durch Anklicken eines Menüpunkts eine Variable ändert.
Ein Beispiel aus einem Programm.
An einer bestimmten Stelle im Programm(oder in einer Prozedur/Funktion)
wird folg. Prozedur aufgerufen:
'Programmsteuerung
'Programm läuft automatisch, wird aber um die Zeitdauer Tempo verzögert
Private Sub Auto(Tempo)
Dim Zeit
Zeit = Timer
Do
DoEvents
Loop Until Timer - Zeit > Tempo / 10
End Sub
Also auto zeit_wert.
Erklärung:
Timer gibt einen Wert vom Typ Single zurück, der die Anzahl der seit Mitternacht vergangenen Sekunden angibt.
Heut Mittag um 12:00 würde also die Variable Zeit mit dem Wert 43200(Sekunden) belegt.
In der Loop-Zeile wird nun immer wieder Timer aufgerufen und von dem Wert wird Zeit abgezogen.
Da der Timer immer größer wird, so ist der Ausdruck Timer - Zeit natürlich auch irgendwann
größer als Tempo / 10.
Dann bricht die (scheinbare) Endlosschleife ab und ein(e) Programm/Prozedur/Funktion läuft weiter.
Das funktioniert z.B. auch innerhalb einer For-Schleife. Heißt, die Abarbeitung
der Schleife geht genau da nach einer bestimmten Zeit weiter, wo die Prozedur
aufgerufen wird.
Was ich jetzt versuchen würde . . .
Diese Prozedur in eine Function umschreiben, damit ein Wert zurückgegeben wird, z.B.:
private function fill_buffer()
end function
Jetzt könnte man zwei Wege gehen.
Der erste wäre, den Ansatz oben komplett umschreiben, und innerhalb der Function den Buffer
der Soundkarte auslesen und eine Variable damit füllen.
Als Abbruchkriterien kämen dann zwei in Frage: Ich prüfe ob was gelesen wurde und beende die Schleife,
oder ich prüfe, ob die Variable irgendwann eine(n) bestimmte(n) Größe/Inhalt hat und beende dann.
private function fill_buffer()
Dim Size
Dim Variable
Size = Wert
Do
'Eine Function aufrufen, die den Buffer liest
Variable = lese_buffer() 'oder Variable = lese_buffer(buffer_von_soundkarte)
Loop Until Größe(Variable) = Size
fill_buffer = Variable
end function
Das könnte allerdings wirklich eine Endlosschleife werden, falls der Buffer der Soundkarte
nicht gelesen werden kann.
Der zweite Weg wäre, den Ansatz oben zu erweitern. Die Schleife versucht in einem definiertem Zeitraum
den Buffer auszulesen, bricht dann ab und gibt das Ergebnis zurück.
private function fill_buffer(zeitraum)
Dim Zeit
Dim Variable
Zeit = Timer
Do
'Eine Function aufrufen, die den Buffer liest
Variable = lese_buffer() 'oder Variable = lese_buffer(buffer_von_soundkarte)
Loop Until Timer - Zeit > zeitraum / 10
fill_buffer = Variable
end function
Innerhalb eines Programms oder einer Function/Prozedur wird dann eine Variable
mit dem Rückgabewert dieser Function initialisiert und ausgewertet:
private sub frequenz()
Dim buffer
. . .
buffer = fill_buffer (zeit_wert)
buffer auswerten
. . .
end sub
Da ich zum Testen kein VB installiert habe und auch nicht weiß, wie man die Soundkarte ausliest(aber das kannst du ja),
ist das natürlich erstmal nur Theorie. Aber vielleicht hilft es dir ja ein Stück weiter.
Gruß
Günni
@günni
[OT]
[/OT]
Grüße
bastla
[OT]
warum sollte das nicht mit einer Endlosschleife gehen, auch solche Schleifen
brauchen nur solange zu laufen, bis ein bestimmter Wert erreicht ist, oder gar
solange, bis z.B. der User durch Anklicken eines Menüpunkts eine Variable ändert.
Ob eine Schleife mit Abbruchbedingung noch als "Endlosschleife" durchgeht? brauchen nur solange zu laufen, bis ein bestimmter Wert erreicht ist, oder gar
solange, bis z.B. der User durch Anklicken eines Menüpunkts eine Variable ändert.
[/OT]
Grüße
bastla