function ALSAPolice(BaseFreq,duration, volume: integer; speed: single): Boolean;
var
buffer: array[0..9600 - 1] of byte;
frames: snd_pcm_sframes_t;
pcm: PPsnd_pcm_t;
I, FC: integer;
SA: array[0..359] of shortint;
const
device = 'default' + #0; // name of sound device
var
count1, count2, N, X: integer;
DeltaStep: single; //winni
delta : Integer; // "
PeakFreq: Integer; // "
upDown : Integer; // "
begin
Result := False;
//ab_Load;
if snd_pcm_open(@pcm, @device[1], SND_PCM_STREAM_PLAYBACK, 0) = 0 then
if snd_pcm_set_params(pcm, SND_PCM_FORMAT_U8,
SND_PCM_ACCESS_RW_INTERLEAVED,
1, // number of channels
48000, // sample rate (Hz)
1, // resampling on/off
500000) = 0 then // latency (us)
begin
Result := True;
PeakFreq := round (BaseFreq * 4/3); //fourth - most used in signal horns
speed := EnsureRange (abs(speed),0.1,1.0); // avoid div by zero
speed := 1/speed *2400;
duration := EnsureRange(abs(duration),50,maxint);// 24.85 days
volume := EnsureRange(abs(Volume),0,100);
// 48 samples per ms -->
// 360 / 48 = 7.5
upDown := 400; // ms interval
DeltaStep := 7.5*(PeakFreq - BaseFreq) /upDown;
for I := 0 to 359 do
SA[I] := round(sin(pi * I / 180.0) * volume); // create sine wave pattern
X := 0;
N := 0; // up/down counter used by unequal interval division
count1 := 0; // count1 counts up, count2 counts down
count2 := duration * 48; // (at 48000Hz there are 48 samples per ms)
while count2 > 0 do // start making sound!
begin
FC := 0;
for I := 0 to sizeof(buffer) - 1 do // fill buffer with samples
begin
if count2 > 0 then
begin
if count1 < 480 then
buffer[I] := 128 + ((count1 * SA[X]) div 480)
else // 10ms feather in
if count2 < 480 then
buffer[I] := 128 + ((count2 * SA[X]) div 480)
else // 10ms feather out
buffer[I] := 128 + SA[X];
Inc(FC);
end
else
begin
buffer[I] := 128; // no signal on trailing end of buffer, just in case
if (FC mod 2400) <> 0 then
Inc(FC); // keep increasing FC until is a multiple of 2400
end;
delta := round (sin(Count1/speed)*DeltaStep*upDown*48/2); // winni
Inc(N,BaseFreq*360+Delta); // winni
while (N > 0) do
begin // (a variation on Bresenham's Algorithm)
Dec(N, 48000);
Inc(X);
end;
X := X mod 360;
Inc(count1);
Dec(count2);
end;
frames := snd_pcm_writei(pcm, @buffer, max(2400, FC)); // write AT LEAST one full period
if frames < 0 then
frames := snd_pcm_recover(pcm, frames, 0); // try to recover from any error
if frames < 0 then
break; // give up if failed to recover
end;
snd_pcm_drain(pcm); // drain any remaining samples
snd_pcm_close(pcm);
end;
//ab_unload;
end; //AlsaPolice