Entwickler-Ecke

Multimedia / Grafik - Programm sol warten bis wave zu ende gespielt hat


dac424 - So 04.06.06 19:02
Titel: Programm sol warten bis wave zu ende gespielt hat
Hy ich suche eine möglich keit das das program solange wartet bis das wave fertig abgespielt ist und erst dann weiter arbeitet

habe mal ein par kommentare beigefügt.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
procedure TForm1.bakenzeitTimer(Sender: TObject); 
var 
ba:string
wa:string
wp   : TWaveProvider; 

//wave:string; 
{$J+} const CanPlay: Boolean = True; {$J-} 
      begin 
      if (form3.Bake.Checked = true) then begin 
      wp := TWaveProvider.Create('bake1.wav'); 
      // ein paar Infos über's Wave ausgeben 
  //   Memo1.Lines.Add(+IntToStr(wp.DataHeader.length div wp.FormatData.AvgBytesPerSec)); 
      FreeAndNil(wp); 
  end

check.Enabled:=false; 
bakenzeit.Interval:=StrToInt(form3.bakenzeit.text)*1000 ; 
onoff.Picture.Bitmap.LoadFromResourceName(HInstance,'ON_BIT'); 
if pin = 'dtr' then DTR(true); 
if pin2 = 'rts' then RTS(true); 
sleep (2000); 
canPlay :=True; 
if CanPlay then 
begin 
//ba:='+wave+'; 
   sndPlaySound(PChar('bake1.wav'),SND_ASYNC); 
   CanPlay := False; 

Memo1.Lines.Add('Duration in Sec.: '+IntToStr(wp.DataHeader.length div wp.FormatData.AvgBytesPerSec)); 

sleep (+InToStr+);   //// Übergabe der Zeit von Memo1.Lines Add sprich die Sekunden die das wave lang ist müssen an Sleep übergeben werden mit einem *1000 damit das programm wartet bis das wave zu ende gespielt hat befor DTR und RTS auf false gehen 

// sleep (20000); 
// bakenzeit.Enabled:=false; 
//check.Enabled:=true; 

if pin = 'dtr' then DTR(false); 
if pin2 = 'rts' then RTS(false); 
  onoff.Picture.Bitmap.LoadFromResourceName(HInstance,'OFF_BIT'); 
check.Enabled:=true; 
  end
  end
end.


Moderiert von user profile iconraziel: Code- durch Delphi-Tags ersetzt


digi_c - Di 06.06.06 18:30

Schau mal zu SndPlaySound, da gibt es nichtnur Asyncals Parameter ;)


dac424 - Di 06.06.06 20:45
Titel: Thema Async
Ich weis nur dann habe ich das Problem das mein Programm garnicht mehr reagirt und auch den befehl den ich vorher gemacht habe

DTR= True

einfach fallen läst.


fidionael - Mo 12.06.06 01:20

Naja, aber ein Zwischending zwischen synchron und assynchron herzustellen ist nicht so einfach. Wenn du einen Sound assynchron abspielst, dann weiß dein System nach Senden des Abspielbefehls nichts mehr über den Sound und gibt dementsprechend auch keine Nachricht mehr darüber zurück, wann der Sound beendet ist.

Ich kann allerdings keine 100% Garantie auf das geben, was ich hier erzähle; so tief habe ich mich noch nicht in dieses Thema eingewühlt, doch soweit ich das Handling von synchron und assynchron verstanden habe ist das so. Falls ich was falsches sage, korrigiert mich bitte - es würde mich auch interessieren ;)

Mfg


digi_c - Mo 12.06.06 09:35

Du könntest den Sound in einem eigenen Thread syncabspielen der erst danach die GUI wieder enabled oder eine globale Variable Truesetzt. Was besseres fällt mir da wirklich nicht ein.


dac424 - Sa 08.07.06 12:24
Titel: da würde ich mal um ein Beispiel bitten
Digi_c da kann ich mir garnix drunter vorstellen kannst du das mal anhand eines Beispiels plausibler machen ???


fidionael - Sa 08.07.06 16:12

Du solltest dich, um die Idee von user profile icondigi_c umsetzen zu können mit der Idee, die hinter Threads steht und mit ihnen selber vertraut machen. Hierfür solltest du dir vielleicht mal dieses Tutorial [http://www.dsdt.info/tutorials/threads] anschauen.

Die Idee ist ja, dass wenn du deinen Sound in einem eigenen Thread abspielen lässt, dieser dein Programm nicht anhält, sondern nur den Thread. Wenn du also den Sound synchron abspielst und nachher eine Boolsche Variable auf True setzt, wird diese erst auf True gesetzt, wenn dein Sound vollständig abgespielt wurde. Nun kannst du in der Hauptanwendung auf das Setzen dieser Variablen warten. Damit sollte dein Problem gelöst sein.

Mfg


dac424 - Sa 08.07.06 16:27

also das verstehe ich jetzt nicht ganz bitte mal ein Beispiel es soll also eine art Include Passieren verstehe ich das nun so richtig.


fidionael - Sa 08.07.06 16:31

Lies das Tutorial und setze dich mit dem Prinzip des MultiTasking bzw. MultiThreading auseinander.

Edit: Hier mal ein funktionierendes Beispiel:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, MMSystem;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;
  PForm1 = ^TForm1;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function PlayMySound(x: Pointer) : Longint; stdcall;
begin
  Result:=0;
  if WaveOutGetNumDevs > 0 then begin
    sndPlaySound('wave.wav',SND_SYNC);
    PForm1(x)^.Label1.Caption:='Sound wurde abgespielt';
  end else PForm1(x)^.Label1.Caption:='Keine Soundkarte gefunden!';
end;

procedure TForm1.Button1Click(Sender: TObject);
var h: THandle;
    id: DWORD;
begin
  Label1.Caption:='Sound wird abgespielt';

  h:=CreateThread(nil,0,TFNThreadStartRoutine(@PlayMySound),@Form1,0,id);
  if h<>0 then CloseHandle(h);
end;

end.


Edit2: Einige kleine Fehler im Quelltext behoben und das Setzen der Label-Caption passiert nun über Pointer.


dac424 - So 09.07.06 12:34
Titel: also startest du quasi
also wenn ich das nun richtig verstehe ist pform dan mein program ??


alias5000 - So 09.07.06 12:39

Frage an Fidionael:

Wieso verwendest du ein PForm1? die Variable "Form1" ist bereits ein pointer auf eine Instanz von TForm1


dac424 - So 09.07.06 12:51
Titel: verstehe ich ja auch nicht
bekomme wen ich das übernehme auch immer eine Fehlermeldung beim compelieren Pform gibt es nicht


fidionael - So 09.07.06 23:35
Titel: Re: verstehe ich ja auch nicht
user profile icondac424 hat folgendes geschrieben:
bekomme wen ich das übernehme auch immer eine Fehlermeldung beim compelieren Pform gibt es nicht


Ich den Typ PForm1 selber deklariert, siehe Zeile 15 meines Quelltextes:

Delphi-Quelltext
1:
PForm1 = ^TForm1;                    




user profile iconalias5000 hat folgendes geschrieben:
Frage an Fidionael:

Wieso verwendest du ein PForm1? die Variable "Form1" ist bereits ein pointer auf eine Instanz von TForm1

Hm ich habe bisher immer so gearbeitet, ich kann doch für einen untypisierten Pointer auch nicht einfach die Variable Form1 übergeben, oder? Ich könnte natürlich auch erst dereferenzieren, also mit TForm1(x^) arbeiten, aber das tut sich ja nicht soviel.


dac424 - Mo 10.07.06 20:48
Titel: aber wie bauae ich das nun in der Bake Position
Nun zu der alles entscheidenen frage wie baue ich es ein siehe meine Routine im eröfnung therhead des weiteren möchte ich gerne das Wave File selber defenieren können in Form 3
und die Barken Zeit natürlich sprich 60 Sekunden dann Spiele das Wave ab aber auch nur dann wen nicht vorher DTR = True gegangen.
war oder RTS=true die Zeit solte variabel sein Variable Zeit kein True dan Play Wave


fidionael - Di 11.07.06 00:41
Titel: Re: aber wie bauae ich das nun in der Bake Position
user profile icondac424 hat folgendes geschrieben:
Nun zu der alles entscheidenen frage wie baue ich es ein siehe meine Routine im eröfnung therhead des weiteren möchte ich gerne das Wave File selber defenieren können in Form 3
und die Barken Zeit natürlich sprich 60 Sekunden dann Spiele das Wave ab aber auch nur dann wen nicht vorher DTR = True gegangen.
war oder RTS=true die Zeit solte variabel sein Variable Zeit kein True dan Play Wave


Das ist kein deutsch - ich habe es bis jetzt zweimal gelesen und immer noch nicht verstanden - spezifizier dich mal, oder entferne zumindest Syntax- und Semantikfehler.

Außerdem solltest du in der Lage sein, dir aus meinem Code-Beispiel alles was du willst zusammen zu basteln; keiner hier wird dir dein Programm schreiben, wenn du deine Wünsche nicht zufällig auf die Rückseite eines Geldscheines schreibst ;)

Noch viel Spaß beim Programmieren.


dac424 - Sa 15.07.06 22:59
Titel: Na dan versuche ich mal
Also nun zu meiner Frage wie baue ich es in meiner Source ein das war alles was ich wissen wollte.


Narses - So 16.07.06 00:45

Moin!

Probier´s doch mal einzubauen und zeig uns die Stelle, an der du nicht weiter kommst; dann können wir dich sicher auch helfen.

Ansonsten kann ich nur sagen:
user profile iconfidionael hat folgendes geschrieben:
keiner hier wird dir dein Programm schreiben


Und hier auch: ;)
user profile iconfidionael hat folgendes geschrieben:
Noch viel Spaß beim Programmieren.


cu
Narses