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
|
type
TWAVBeep = record
const
SAMPLERATE = 48000;
private
WaveOut: HWAVEOUT;
Header : TWaveHdr;
Wave : array of SmallInt;
procedure Init;
public
procedure Beep(dwFreq, dwDuration: DWORD);
end;
procedure TWAVBeep.Init;
var
WF: TWaveFormatEx;
begin
WF.wFormatTag := WAVE_FORMAT_PCM;
WF.nChannels := 1;
WF.nSamplesPerSec := SAMPLERATE;
WF.wBitsPerSample := 16;
WF.nBlockAlign := (WF.nChannels * WF.wBitsPerSample) div 8;
WF.nAvgBytesPerSec := WF.nBlockAlign * WF.nSamplesPerSec;
WF.cbSize := 0;
if WaveOutOpen(@WaveOut, WAVE_MAPPER, @WF, 0, 0, CALLBACK_NULL) <> MMSYSERR_NOERROR then
RaiseLastOSError;
end;
procedure TWAVBeep.Beep(dwFreq, dwDuration: DWORD);
var
Index: Integer;
period: Single;
periodSamples: Integer;
time: Single;
proportionOfPeriod: Single;
value: Single;
begin
if Wave = nil then
Init;
SetLength(Wave, (dwDuration * SAMPLERATE) div 1000);
period := 1 / dwFreq;
periodSamples := Round(period * SAMPLERATE);
for Index := 0 to Length(Wave) do
begin
time := Index / SAMPLERATE;
proportionOfPeriod := (fmod(time, period))/period;
if proportionOfPeriod < 0.5 then
value := -1 + 4 * proportionOfPeriod
else
value := +3 - 4 * proportionOfPeriod;
Wave[Index] := Round(32767 * value);
end;
FillChar(Header, SizeOf(TWaveHdr), 0);
Header.dwBufferLength := Length(Wave) * SizeOf(SmallInt);
Header.lpData := Pointer(Wave);
waveOutPrepareHeader(WaveOut, @Header, SizeOf(TWaveHdr));
waveOutWrite(WaveOut, @Header, SizeOf(TWaveHdr));
Sleep(dwDuration + 50); // 50ms entre deux sons
end;
procedure TForm1.Button1Click(Sender: TObject);
var
W: TWAVBeep;
begin
W.Beep(750,100);
W.Beep(750,300);
W.Beep(750,100);
W.Beep(750,100);
end, |
Partager