Autor Beitrag
dummzeuch
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 593
Erhaltene Danke: 5


Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
BeitragVerfasst: Fr 18.07.08 08:34 
Hi,

Windows hat eine API Funktion Beep, zu der auf MSDN folgende Beschreibung steht:

Zitat:

Generates simple tones on the speaker. The function is synchronous; it performs an alertable wait and does not return control to its caller until the sound finishes.


Leider ist das fuer mich nicht brauchbar, denn ich kann das Programm nicht solange blockieren.

MessageBeep (und damit SysUtils.Beep) ist asynchron, aber bietet mir nicht die Moeglichkeit, Frequenz und Laenge zu uebergeben.

Ich koennte jetzt einen extra Thread starten, der nichts anderes macht, als fuer andere Threads die Beep API aufzurufen, aber das kommt mir irgendwie wie Overkill vor.

Eine Google-Suche hat nicht allzuviel gebracht (ausser einer BeepEx-Funktion, deren "Vorteil" es ist synchron zu sein).

Jemand 'ne Idee?

twm
matox
Hält's aus hier
Beiträge: 4
Erhaltene Danke: 1

XP
Delphi 7.0 Personal
BeitragVerfasst: Fr 25.07.08 16:04 
Titel: Töne ausgeben
//Ausgabe einer CDUR-Tonleiter

ausblenden volle Höhe 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:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure MakeSound(Frequency, Duration : integer);

var
  WaveFormatEx : TWaveFormatEx;
  MS           : TMemoryStream;
  i, TempInt,
  DataCount,
  RiffCount    : integer;
  SoundValue   : byte;
  w            : double;
const
  Mono       : Word = $0001;
  SampleRate : integer = 11025;
  RiffId     : string = 'RIFF';
  WaveId     : string = 'WAVE';
  FmtId      : string = 'fmt ';
  DataId     : string = 'data';
begin
  with WaveFormatEx do begin
    wFormatTag := WAVE_FORMAT_PCM;
    nChannels := Mono;
    nSamplesPerSec := SampleRate;
    wBitsPerSample := $0008;
    nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
    nBlockAlign := (nChannels * wBitsPerSample) div 8;
    cbSize := 0;
  end;
  MS := TMemoryStream.Create;
  with MS do begin

    DataCount := (Duration *  SampleRate) div 1000;
    RiffCount := Length(WaveId)
                 + Length(FmtId) + SizeOf(DWord)
                 + SizeOf(TWaveFormatEx)
                 + Length(DataId) + SizeOf(DWord)
                 + DataCount;
    Write(RiffId[1], 4);
    Write(RiffCount, SizeOf(DWord));
    Write(WaveId[1], Length(WaveId));
    Write(FmtId[1], Length(FmtId));
    TempInt := SizeOf(TWaveFormatEx);
    Write(TempInt, SizeOf(DWord));
    Write(WaveFormatEx, SizeOf(TWaveFormatEx));
    Write(DataId[1], Length(DataId));
    Write(DataCount, SizeOf(DWord));
    w := 2 * Pi * Frequency;
    for i := 0 to DataCount - 1 do begin
      SoundValue := 127 + trunc(127 * sin(i * w / SampleRate));
      Write(SoundValue, SizeOf(Byte));
    end;
    sndPlaySound(MS.Memory, SND_MEMORY or SND_SYNC);
    MS.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MakeSound(523,600); //C 2
  MakeSound(587,600); //D
  MakeSound(659,600); //E
  MakeSound(698,600); //F
  MakeSound(784,600); //G
  MakeSound(880,600); //H
  MakeSound(987,600); //A
  MakeSound(1046,600);//C 3
end;
end.
dummzeuch Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 593
Erhaltene Danke: 5


Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
BeitragVerfasst: Sa 27.03.10 12:25 
Ich hab's jetzt doch mit einem eigenen Thread geloest.