function ALSAglide(StartFreq,EndFreq, duration, volume: integer): Boolean;

var

buffer: array[0..9600 - 1] of byte; // 1/5th second worth of samples @48000Hz

frames: snd_pcm_sframes_t; // number of frames written (negative if an error occurred)

pcm: PPsnd_pcm_t; // sound device handle

I, FC: integer;

SA: array[0..359] of shortint; // array of sine wave values for a single cycle

const

device = 'default' + #0; // name of sound device

var

count1, count2, N, X: integer;

DeltaStep: single; //winni

delta : 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;

StartFreq:= EnsureRange(abs(StartFreq),20,20000);

EndFreq := EnsureRange(abs(EndFreq),20,20000);

duration := EnsureRange(abs(duration),50,maxint);// 24.85 days

volume := EnsureRange(abs(Volume),0,100);

// 48 samples per ms -->

// 360 / 48 = 7.5

DeltaStep := 7.5*(EndFreq - startFreq) /(duration); // winni

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 (Count1*DeltaStep); // winni

Inc(N,StartFreq*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; //AlsaGlide