Forum: PC-Programmierung C#/.NET: Soundausgabe mit DirectSound


von Ralf (Gast)


Lesenswert?

Hi,

ich versuche gerade, mit DirectSound (DirectX) eine Datei wiederzugeben. 
Als Basis habe ich dieses Tutorial verwendet:
http://www.riemers.net/eng/Tutorials/DirectX/Csharp/Series2/tut15.php

Die Referenzen auf DirectX und DirectX.DirectSound habe ich im Projekt. 
Den Code der im Tutorial gezeigten 'InitializeSound()' Methode habe ich 
in das FormLoad-Ereignis gepackt und auf eine andere Sounddatei 
verwiesen.
Ansonsten befinden sich keinerlei Buttons, etc. oder sonstiger Code im 
Projekt, also wirklich ein nacktes Windows.Forms-Projekt.
So, und wenn ich das Programm in der Debug-Konfiguration starte wird 
nicht mal in das FormLoad-Ereignis gesprungen (Breakpoint auf ersten 
Befehl zeigt keine Wirkung) und auch das 'nackte' Fenster erscheint 
nicht.
Kommentiere ich den Code im FormLoad-Ereignis aus, dann erscheint das 
Fenster.

Wo liegt das Problem? Ich hätte zumindest erwartet, dass das 
FormLoad-Ereignis aufgerufen wird.
Gibt's bei DirectX/DirectSound etwas spezielles zu beachten?

IDE ist #Dev, .NET FW 4.5, Win7-64, Dx SDK.

DirectX.AudioVideoPlayBack ist keine Option. Die Applikation soll später 
keine Dateien wiedergeben, sondern die Audioausgabe (egal welches 
Programm die Dateien ausgibt) als PeakMeter darstellen.

Hat jemand eine Idee, warum das Programm hängt?

Ralf

von Uhu U. (uhu)


Lesenswert?

Ralf schrieb:
> Kommentiere ich den Code im FormLoad-Ereignis aus, dann erscheint das
> Fenster.

Dann pack den Aufruf doch einfach ins Paint-Event...

von Ralf (Gast)


Lesenswert?

> Dann pack den Aufruf doch einfach ins Paint-Event...
Mit welcher Begründung räumst du dem Ansatz mehr Erfolg ein? Mal 
abgesehen davon, dass das Paint-Event wahrscheinlich permanent ausgelöst 
wird, sobald man mit der Maus über's Fenster fährt oder dieses 
bewegt/minimiert, etc.

Ralf

von A. Simpson (Gast)


Lesenswert?

Ralf schrieb:
> Mal
> abgesehen davon, dass das Paint-Event wahrscheinlich permanent ausgelöst
> wird, sobald man mit der Maus über's Fenster fährt oder dieses
> bewegt/minimiert, etc.
Jenau. Man will ja auch nicht die beim Hausbau errichtete Garage 
neubauen, nur weil man tapeziert. :D

Aber du sagst, wenn du den Code im Event-Handler auskommentierst, wird 
das Fenster angezeigt. Klingt eher so, als würde das Event doch 
auslösen, nur der im Handler blockierende Code verhindert den 
Fensteraufbau; also dein Direct-X-Aufruf gibt nicht zurück. Wird denn 
wirklich nichts weiter angezeigt? Output-Window? Exception, auch nach 
längerer Wartezeit (Timeout)? Nichts?

von Uhu U. (uhu)


Lesenswert?

Ralf schrieb:
> Mit welcher Begründung räumst du dem Ansatz mehr Erfolg ein?

Für manche Dinge ist FormLoad zu früh - ich hatte damit auch schon 
Probleme.

> Mal
> abgesehen davon, dass das Paint-Event wahrscheinlich permanent ausgelöst
> wird, sobald man mit der Maus über's Fenster fährt oder dieses
> bewegt/minimiert, etc.

Und was hindert dich daran, ein Flag zu setzen, daß die Sound-Kiste 
schon läuft?

Ansonsten hängs auf einen Button, oder nimm einen Timer, der in FormLoad 
angekickt wird und mit Zeitverzug den Sound startet - nicht schön, aber 
umschifft solche Probleme.

Und jetzt setz dich hin und probiers aus.

von Uhu U. (uhu)


Lesenswert?

Ralf schrieb:
> Mit welcher Begründung räumst du dem Ansatz mehr Erfolg ein?

FormLoad wird sehr früh nach der Erzeugung des Window-Handles gerufen. 
Wenn es sich bei dem Form um das Hauptfenster handelt, läuft der Message 
Loop noch nicht.

Wenn man in diesem Stadium irgendwas startet, was selbst Messages 
schickt, dann werden die nicht verarbeitet und Folge ist ein Deadlock.

von Ralf (Gast)


Lesenswert?

@A.Simpson:
> Jenau. Man will ja auch nicht die beim Hausbau errichtete Garage
> neubauen, nur weil man tapeziert. :D
grins Naja, ich kenne Leute, denen würd ich selbst das zutrauen, aber 
lassen wir das... ;)

> Aber du sagst, wenn du den Code im Event-Handler auskommentierst, wird
> das Fenster angezeigt. Klingt eher so, als würde das Event doch
> auslösen, nur der im Handler blockierende Code verhindert den
> Fensteraufbau; also dein Direct-X-Aufruf gibt nicht zurück.
Das komische ist halt, dass nicht mal der erste Befehl angesprungen 
wird, wenn ich dort einen Breakpoint setze.
Ich hab's auch schon über einen Button probiert. Den DirectSound-Code 
habe ich in eine eigene Funktion gepackt und im Button-ClickEvent 
aufgerufen. Beim Klicken pausiert die Form. Lässt sich nicht mal 
bewegen.
Pausiere ich den Debugger, dann steht der Ausführungsmarker beim Aufruf 
der Funktion, und nicht irgendwo im DirectSound-Code.
Kann es sein, dass man DirectX/DirectSound-Zugriffe in einem separaten 
Thread ausführen muss? Also gelöst vom GUI-Thread?

> Wird denn wirklich nichts weiter angezeigt? Output-Window? Exception, auch
> nach längerer Wartezeit (Timeout)? Nichts?
Im Output-Window war nüscht, und nach zwei Minuten gab's immer noch 
keine Exception oder sonstwas (ich weiss, dass DirectX/DirectSound nicht 
unbedingt das schnellste ist, aber sooooo lange kann's ja wohl nicht 
dauern ;)

@ Uhu Uhuhu:
>> Mit welcher Begründung räumst du dem Ansatz mehr Erfolg ein?
> Für manche Dinge ist FormLoad zu früh - ich hatte damit auch schon
> Probleme.
> FormLoad wird sehr früh nach der Erzeugung des Window-Handles gerufen.
> Wenn es sich bei dem Form um das Hauptfenster handelt, läuft der Message
> Loop noch nicht.
> Wenn man in diesem Stadium irgendwas startet, was selbst Messages
> schickt, dann werden die nicht verarbeitet und Folge ist ein Deadlock.
Danke für den Hinweis. Ich hab zwar in der Variante über das 
FormLoad-Ereignis auch schon probeweise geprüft, ob das Fenster ein 
Handle hat (wenn nicht wird es wohl automatisch bei der Abfrage 
angelegt), da eine der DirectSound-Funktionen ein Handle erwartet, aber 
dass die MessageLoop zu dem Zeitpunkt evtl. noch nicht läuft wusste ich 
nicht.

> Und was hindert dich daran, ein Flag zu setzen, daß die Sound-Kiste
> schon läuft?
Für's Ausprobieren okay, ansonsten unschön :) Aber zum Prüfen schon 
machbar, das stimmt.

> Ansonsten hängs auf einen Button, oder nimm einen Timer, der in FormLoad
> angekickt wird und mit Zeitverzug den Sound startet - nicht schön, aber
> umschifft solche Probleme.
Wie oben genannt, die Button-Variante tat's auch nicht. Man sieht noch, 
wie der Button geklickt wird, danach ist Ende, kein Bewegen des Fensters 
möglich, der Button bleibt "hinterlegt" (weil ja der Mauscursor drüber 
war), aber sonst nüscht.

> Und jetzt setz dich hin und probiers aus.
Aye, Captain ;)

Ich werd jetzt mal die Gegenprobe auf nem WinXP 32-Bit System machen. 
Vielleicht finde ich so heraus, an was es noch klemmen könnte.

Ralf

von Uhu U. (uhu)


Lesenswert?

Ralf schrieb:
> Wie oben genannt, die Button-Variante tat's auch nicht. Man sieht noch,
> wie der Button geklickt wird, danach ist Ende, kein Bewegen des Fensters
> möglich, der Button bleibt "hinterlegt" (weil ja der Mauscursor drüber
> war), aber sonst nüscht.

Hast du mal einen Breakpoint auf die Click-Eventroutine gesetzt, dann im 
Einzelschritt weiter gemacht und vor Aufruf der Sound-Geschichten die 
Parameter überprüft?

Bist du sicher, daß der Sound-File gesund ist?

> Kann es sein, dass man DirectX/DirectSound-Zugriffe in einem separaten
> Thread ausführen muss? Also gelöst vom GUI-Thread?

Das muß man eigentlich nur dann machen, wenn die Soundroutine erst dann 
zurückkehrt, wenn der File komplett abgespielt ist und während des 
Abspielens der Message-Loop nicht mehr dran kommt.

Bevor du dir darüber gedanken machen mußt, sollte die Ausgabe erstmal 
prinzipiell laufen.

von Ralf (Gast)


Lesenswert?

@Uhu Uhuhu:
> Hast du mal einen Breakpoint auf die Click-Eventroutine gesetzt, dann im
> Einzelschritt weiter gemacht und vor Aufruf der Sound-Geschichten die
> Parameter überprüft?
Ja, hab ich auch schon. Der Ausführungsmarker steht auf dem Aufruf der 
Funktion mit dem DirectSound-Code. Wenn ich dann einen Single-Step 
mache, passiert gar nix. Das ist vom Verhalten her wie wenn man die 
Ausführung fortsetzen würde, es wird einfach nicht weiter gesprungen. 
Ich kann das Programm dann lediglich wieder anhalten.

> Bist du sicher, daß der Sound-File gesund ist?
Das File selbst existiert, der Pfad sollte auch in Ordnung sein. 
Gegenwärtig verweise ich auf ein MP3-File. Aber selbst wenn das File 
oder der Pfad fehlerhaft wären sollte das erst beim Anlegen des 
SecondaryBuffer eine Rolle spielen.

Ich werd morgen mal ein WAV-File direkt auf C: ausprobieren, zusammen 
mit dem WinXP Test, zu dem bin ich heut leider nicht mehr gekommen.

> Das muß man eigentlich nur dann machen, wenn die Soundroutine erst dann
> zurückkehrt, wenn der File komplett abgespielt ist und während des
> Abspielens der Message-Loop nicht mehr dran kommt.
Okay. Dann ist das also auch nicht das Problem.

> Bevor du dir darüber gedanken machen mußt, sollte die Ausgabe erstmal
> prinzipiell laufen.
Ganz meine Meinung. Sieht aus als ob das schon der schwierigste Teil 
ist, wenn ich den geknackt habe sollte alles andere easy sein ;)

Ralf

von Uhu U. (uhu)


Lesenswert?

Hast du mal versucht, das komplette Programm, das am Ende deines Links 
steht, so weit abzuspecken, daß nur noch das leere Form und der 
Sound-Code übrig bleibt?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.