Main Loop

Alles rund um die Programmierung mit Qt
Antworten
eversleeping
Beiträge: 7
Registriert: 6. Juni 2011 21:52

Main Loop

Beitrag von eversleeping »

Ich wusste nicht wie ich den Thread hätte besser nennen können.
Ich habe eine Funktion, die laut Doku once per frame ausgeführt werden soll.

Im Beispiel ist das mit einer do while schleife gemacht.
Wo kann ich so eine fast Endlosschleife in ein QT-Programm einbauen?
Muss ich dazu einen eigenen Thread erstellen oder geht das auch so?

Die GUI selbst sollte ja ohnehin ein eigener Thread sein, oder?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Das hört sich arg nach Spieleprogrammierung an.
Deine Loop stellt Qt in Form einer EventLoop zur Verfügung. Diese arbeitet aber nur Events (SIGNAL/SLOT) ab. Wenn du willst, dass regelmäßig etwas abgearbeitet wird, musst du mit einem Timer arbeiten.
Mit einem Thread ginge da sicher auch was, aber da solltest du erstmal genauer sagen, das denn diese Funktion genau macht. Jede Applikation startet direkt in den MainThread - in Qt ist das der einzige Thread, der direkt in die GUI malen darf! (Das schließt ALLE Funktionen ein, die irgendwo auch in Manipulationen der Gui auslösen, z.B. ein QLabel::setText()). In einem eigenen Thread kannst du dann natürlich auch eine eigene Endlosschleife laufen lassen, in der du deine Funktion aufrufst - Mit "Frames" hat das dann aber nichts mehr zu tun, eine Kommunikation mit der GUI musst du selber erstellen, und für Anfänger ist das ein großes Problem!

Also: Wenn dich das oben wenig weiter bringt, sag einfach genau, was du machen willst, und vor allem was diese Funktion leisten soll, dann kann man besser helfen.
eversleeping
Beiträge: 7
Registriert: 6. Juni 2011 21:52

Beitrag von eversleeping »

Ich versuche einen Audio-Player zu schreiben, da ich mit bestehenden (Amarok, Banshee, Rhythmbox) sehr unzufrieden bin. Das einzige, was mir annähernd gefällt ist aTunes.

Da ich ich selbst noch sehr wenig Programmiererfahrung habe, habe ich mir zum Ziel gesetzt, meinen eigenen zu schreiben.

Da meine Kenntnisse bezüglich Audioverarbeitung auch sehr gering sind, habe ich mir für den Anfang die fmod-Library hergenommen.

Bisher klappt das Abspielen/Pausieren/Stoppen schon sehr gut.
Nun möchte ich einen Slider haben, der anzeigt wie weit ein Lied schon gespielt wurde.

Um das ordentlich zu erreichen, gibt es die Funktion
FMOD::System::update(), die once per (Audio)Frame aufgerufen werden sollte.
eversleeping
Beiträge: 7
Registriert: 6. Juni 2011 21:52

Beitrag von eversleeping »

little push
8)
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Ich hab jetzt leider absolut keine Ahnung von fmod. wie soll denn die Funktion aufgerufen werden? Ich meine, sinnlos in einer while-Schleife ständig update() triggern, nur damit man wirklich ausreichend Frames produziert (Mit Qt-Signals&Slots kann es passieren, dass eine dickere Funktion abgearbeitet werden muss, und dann hast du plötzlich ein Lag in de Musikwiedergabe).

Ich denke aber, das einfachste sollte phonon sein. Da gibt es sogar schon einen einfachen Musik-Player (samt playlist) in den Qt-Examples. Den Code fürs Playback kannst du da ganz einfach übernehmen.
FaS
Beiträge: 184
Registriert: 25. Mai 2006 19:48
Kontaktdaten:

Beitrag von FaS »

Ich glaube auch, dass FMOD eher für die Spieleprogrammierung geeignet ist, wo man einen hoch frequentierten main loop hat. Dort soll die Funktion aufgerufen werden. In einer normalen Applikation wird dieses Konzept nicht verwendet, da das entweder die CPU auslastet oder, falls getimed, UI-Verzögerungen verursachen würde. Man müsste das also emulieren, wobei man aufpassen muss, da dann eine Interaktion mit FMOD nicht mehr zeitgleich zu den update()-Aufrufen auftritt bzw. update() in unregelmäßigen Abständen aufgerufen wird. Letzteres ist aber vermutlich egal. Man könnte die Funktion also mit Hilfe eines System-Timers z.B. jede 60tel Sekunde aufrufen (vielleicht ist dies auch nur innerhalb des Audiopuffer-Zeitfensters erforderlich) und nach/vor anderen FMOD-Funktionsaufrufen - siehe Doku.

Zu deiner Thread-Idee: Falls du FMOD mit einem Mutex oder so schützt, gehts vielleicht, in der Endlosschleife sollte dann aus energietechnischen Gründen trotzdem ein msleep() auftauchen. Glaube insgesamt ist das unschöner, da du ja auch mit ihm kommunizieren musst. Andererseits spielt dann die Musik weiter, wenn der Hauptthread die von franzf erwähnte dickere Funktion abarbeitet - allerdings sollte sowas in einer Anwendung, welche auf Benutzereingaben sofort reagieren muss, eh vermieden werden. Ist halt die Frage, wie oft FMOD dieses update() benötigt.

Oder eben eine andere lib. Phonon spielt übrigens nicht alle meine Dateien ab, welche andere Player jedoch spielen (zu FMOD/BASS kann ich in diesen Fällen nichts sagen - ist aber auch ein fast vernachlässigbarer Prozentsatz); das Nonplusultra ist das also nicht, aber einfacher in Verbindung mit Qt sicherlich.

Gruß
FaS
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Ich habe mal mit FMOD im Zusammenhang mit "Qute3d" rumgespielt.
FMOD selbst ist ja bereits threaded und braucht daher im Grunde keine weiteren updates aus dem Mainthread (wenn ich beim aktuellen fmodapi43405linux64 ein Example im Debugger anhalte, erhalte ich sogar drei Threads: Main, FMOD und Pulse-Audio).

Ich glaube daher nicht, dass das damit ("once per frame") Audio-Frames gemeint sind, sondern eher GUI-(Spiele-)-Frames. Vermutlich zur Synchronisierung der Status-Daten mit dem Player-Thread.
Ich würde also davon ausgehen, dass z.B. ein mit einem QTimer realisierter GUI-Update (Aufruf von FMOD_System_Update() und Aktualisierung des Sliders) mit 100ms Takt problemlos funktioniert (=keine Unterbrechung des Sounds wenn die GUI sonst eine aufwendige Operation erledigt).
Antworten