Entwickler-Ecke

Sonstiges (Delphi) - Probleme mit Windows.Beep und Ton zerschneiden


DiamondDog - Mo 27.04.09 10:33
Titel: Probleme mit Windows.Beep und Ton zerschneiden
Hallo Leute,
ich würde gerne über Windows.Beep einen Sound ausgeben. Das Problem dabei ist das Windows.Beep nur mit 2 Zahlen und einem Komma klarr kommt. Bsp: (640,50)
Mein Problem ist, das ich die Sounds so in einem Edit stehen habe 640,50;740,80;640,50;740,80 und so das ganze nicht funktioniert. Meine Frage ist jetzt, wie bekomme ich es hin das der Sound gestückelt wird? Also das immer nur biß zum ; gelsen wird, dann abgespiel und dann der nächste Ton genommen wird?

Ich hab das schon so versucht:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
var i      : integer;
    Melody : string;
    Komma  : integer;
    Laenge : integer;
    Ton1   : string;
    Ton2   : string;
begin
  RichEditSoundInt.Text := StringReplace(editSoundInt.Text, ';'#10, [rfReplaceAll]);
  for i:=0 to RichEditSoundInt.Lines.Count-1 do
  begin
  Melody := RichEditSoundInt.Lines[1];
  Melody := StringReplace(Melody, ' ''', [rfReplaceAll]);

  Komma := Pos(',',Melody);
  Laenge := Length(Melody);

  Ton1 := Copy(Melody, 0, Komma-1);
  Ton2 := Copy(Melody, Komma+1, Laenge);

  Windows.Beep(strtoint(Ton1),strtoint(Ton2));
  end;
end;
aber irgend was stimmt da noch nicht so ganz.
der Fehler der dann kommt ist:
" ist kein gültiger Integerwert.

Danke schon mal fürs Helfen.

Mfg Dog

Edit:
Ich hab mal eine pas angehängt die genau das macht, was ich haben möchte.
Das Problem ist ich weiß nicht wie udn was ich machen muß damit es mit der pas läuft.
Ich weiß das die pas in die uses muss. Aber ab da weiß ich nicht mehr weiter wie ich ihr den Ton übergeben muss bzw was ich in der pas ändern muss das Sie nachher den Ton abspielt.
Wäre super wenn mir das da jemand Helfen könnte die Datei anzupassen.


jaenicke - Mo 27.04.09 11:12

Zu dem Copy bei Ton1: Der erste Buchstabe hat den Index 1...
Zu dem Copy bei Ton2: Der dritte Parameter für Copy ist die Länge des zu kopierenden Stücks, nicht der Index des letzten Buchstabens.

Was ich nicht verstehe: Was macht das RichEdit dabei? :gruebel:

Nimm einfach eine TStringList mit Delimiter := ';' und DelimitedText := editSoundInt.Text, dann geh die Liste durch, da stehen die Werte mit Komma getrennt drin dann.


DiamondDog - Mo 27.04.09 11:36

Ok so weit bin ich jetzt, aber weiter weiß ich irgendwie nicht:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
var sl: TStringList;
    i : integer;
begin
  sl := TStringList.Create;             
  try
    sl.Delimiter := ';';                 
    sl.DelimitedText := editSoundInt.Text;

    for i:=0 to sl.Count-1 do
    begin
      // Hier weiß ich nicht weiter

      Windows.Beep(strtoint(Ton1),strtoint(Ton2));
    end;
  finally
    sl.Free;                             
  end;
end;


jaenicke - Mo 27.04.09 11:52

Schau dir einmal NameValueSeparator und Values an...


DiamondDog - Mo 27.04.09 12:47

Ich habs jetzt so gelöst:

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:
var sl  : TStringList;
    i   : integer;
    Ton1: string;
    Ton2: string;
    Komma  : integer;
    Laenge : integer;
begin
  sl := TStringList.Create;                // StringList erstellen
  try
    sl.Delimiter := ';';                   // Trennzeichen einstellen
    sl.DelimitedText := editSoundInt.Text; // Delphi die Arbeit machen lassen

    for i:=0 to sl.Count-1 do
    begin
      if (sl.Strings[i] = ''or (sl.Strings[i] = ' 'then sl.Strings[i] := '0,0';
      Komma := Pos(',',sl.Strings[i]);
      Laenge := Length(sl.Strings[i]);

      Ton1 := Copy(sl.Strings[i], 0, Komma-1);
      Ton2 := Copy(sl.Strings[i], Komma+1, Laenge);

      //Windows.Beep(Frequenz, Dauer);
      Windows.Beep(strtoint(Ton1),strtoint(Ton2));
    end;
  finally
    sl.Free;                               // Speicher freigeben
  end;
end;
gibts da noch ne bessere Methode? Diese funktioniert zwar aber wäre auch interesant zu wissen, wie es richtig gelöst wird.

PS:
Neben bei eine kleine Frage und zwar im Edit werden nur zahlen und , zu gelassen:

Delphi-Quelltext
1:
if not (key in[#8,#44,#48..#57]) then key:=#0;                    
Was ist den der Code für ;
Damit auch ; zugelassen wird?


jaenicke - Mo 27.04.09 12:56

user profile iconDiamondDog hat folgendes geschrieben Zum zitierten Posting springen:
gibts da noch ne bessere Methode? Diese funktioniert zwar aber wäre auch interesant zu wissen, wie es richtig gelöst wird.
Meinen Vorschlag für die kürzeste Lösung hast du ja geflissentlich übergangen... :nixweiss:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
  i: Integer;
  sl: TStringList;
begin
  sl := TStringList.Create;                // StringList erstellen
  try
    sl.Delimiter := ';';                   // Trennzeichen einstellen
    sl.DelimitedText := editSoundInt.Text; // Delphi die Arbeit machen lassen
    sl.NameValueSeparator := ',';

    for i := 0 to sl.Count - 1 do
      Windows.Beep(StrToInt(sl.Names[i]), StrToInt(sl.ValueFromIndex[i]));
  finally
    sl.Free;                               // Speicher freigeben
  end;
Wobei ein wenig Fehlerbehandlung nicht schaden würde, so á la TryStrToInt.

user profile iconDiamondDog hat folgendes geschrieben Zum zitierten Posting springen:
Was ist den der Code für ;
Damit auch ; zugelassen wird?
59...


BenBE - Mo 27.04.09 13:11

user profile iconDiamondDog hat folgendes geschrieben Zum zitierten Posting springen:
Was ist den der Code für ;
Damit auch ; zugelassen wird?

';'


jaenicke - Mo 27.04.09 13:13

user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
';'                    
Das ist doch langweilig, wenn man nicht nur kryptische Zahlen dort sieht. :mrgreen:


DiamondDog - Mo 27.04.09 13:16

Bin mit deiner Methode nciht ganz klarr gekommen, deswegen hab ich es erst mal auf einem andern Weg versucht.
Die Fehlerabfrage werd ich wohl noch einbauen das geprüft wird ob es auch wirklich ein Integerwert ist.

Den Rest sollte ich jetzt hinbekommen.
Besten Dank fürs Helfen.


BenBE - Mo 27.04.09 13:16

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
';'                    
Das ist doch langweilig, wenn man nicht nur kryptische Zahlen dort sieht. :mrgreen:

Man kann es auch mit Chr(1 shl (48 shr (1 xor (1 shl 1))) - 10 shr (42 div 23)) ausdrücken ... schon klar :P

Edit: Zwei Klammern entfernt, um C-Programmierer zu verwirren :P


DiamondDog - Mo 27.04.09 15:40

Ich hab doch das Problem das ich es nicht hinbekomme den String zu Pfüfen ob es ein integer ist.

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:
45:
46:
47:
48:
49:
50:
[...]

{$HINTS OFF}
function IsValidInteger(S: String): Boolean;
var
  dummy, Code: Integer;
begin
  Val(S, dummy, Code);
  Result := Code = 0;
end;
{$HINTS ON}

[...]

var
  i: Integer;
  sl: TStringList;
  Ton1 : string;
  Ton2 : string;
  S: string;
begin
  sl := TStringList.Create;                // StringList erstellen
  try
    sl.Delimiter := ';';                   // Trennzeichen einstellen
    sl.DelimitedText := EditSoundInt.Text;          // Delphi die Arbeit machen lassen
    sl.NameValueSeparator := ',';
for i := 0 to sl.Count - 1 do
    S := sl.Names[i];
    if IsValidInteger(S) then
    begin
      Ton1 := S;
    end else
    begin
      Ton1 := '0';
    end;

    S := sl.ValueFromIndex[i];
    if IsValidInteger(S) then
    begin
      Ton2 := S;
    end else
    begin
      Ton2 := '0';
    end;


      Windows.Beep(StrToInt(Ton1), StrToInt(Ton2));
  finally
    sl.Free;                               // Speicher freigeben
  end;


BenBE - Mo 27.04.09 15:42

Siehe StrToIntDef ...


DiamondDog - Mo 27.04.09 18:53

Also irgend wie finde ich den Fehler nicht oder ich seh den Wald vor lauter Bäumen nicht.
Es ist doch eigendlich richtig das ich erst in integer umwandeln muss wenn ich grprüft habe ob der String ein integer ist.
Komisch ist auch die Fehler meldung die ich bekomme:
Listenindex überschreitet das Maximum (5)

Also ich bräuchte doch noch nen Schups Bitte.