Procedure StartRecording ;
Const Buffer_Frames = NBPoints; // in Main = 16384 int 16 bits
Var
// Samplerate : Int32 = 8192 ; defined in Main
// Capture_handle : Psnd_pcm_t ; // declared as global to unit
// Channels : int32 = 1 ; //mono defined In Main
buffer : Pchar ;
hw_params : Psnd_pcm_hw_params_t ;
format : snd_pcm_format_t = SND_PCM_FORMAT_S16_LE ; // 16 bits signed little endian
direction : integer = 0 ;
i,err ,readsize : Integer;
begin
ReadSize := Buffer_Frames div 16 ; // 2048 bytes 16 times 1024 read * 2 bytes
err := snd_pcm_open(@capture_handle,Pchar(deviceTable[MainForm.CBListDevices.itemIndex].iname),SND_PCM_STREAM_CAPTURE,0(*SND_PCM_NONBLOCK*)) ;
If err < 0 then begin PostError('Error opening PCM') ; Exit ;end;
err := snd_pcm_hw_params_malloc (@hw_params) ;
If err < 0 then begin PostError('Error hwparams'); Exit ;end;
err := snd_pcm_hw_params_any (capture_handle, hw_params) ;
if err< 0 then begin PostError('Cannot initialize hardware parameter structure') ; Exit ; end ;
// SND_PCM_ACCESS_MMAP_NONINTERLEAVED
err := snd_pcm_hw_params_set_access (capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
if err < 0 then begin PostError('Cannot access PCM type');Exit;end;
err := snd_pcm_hw_params_set_format (capture_handle, hw_params, format) ;
if err < 0 then begin Posterror('Cannot set format') ; Exit; end;
err := snd_pcm_hw_params_set_rate_near (capture_handle, hw_params, @samplerate, @direction);
if err < 0 then begin Posterror('Cannot set rate') ; Exit ; end;
if Direction <> 0 then begin Posterror('Cannot set exact rate') ; Exit; end;
err := snd_pcm_hw_params_set_channels (capture_handle, hw_params, channels) ; // 1 channel = mono
if err < 0 then begin PostError('Cannot set channel count') ; Exit ; end;
err := snd_pcm_hw_params (capture_handle, hw_params) ;
if err < 0 then Begin PostError('Cannot set parameters') ; Exit ; end ;
snd_pcm_hw_params_free (hw_params);
err := snd_pcm_prepare (capture_handle) ;
if err < 0 then begin PostError('Cannot prepare audio interface for use'); Exit ; end;
buffer := GetMem ((Buffer_Frames * snd_pcm_format_width(format) DIV 8 * Channels) div 16);
FillWord(SavedFrameData,length(SavedFrameData),0); // remove garbage
Repeat
for i := 0 to 15 do begin
err := snd_pcm_readi (capture_handle, buffer, ReadSize);
Move(buffer^,SavedFrameData[i*ReadSize],ReadSize *2) ;
// SavedFrameData is int16 array no need to multiply ReadSize in index
Application.ProcessMessages ;
end;
// we assume we have a full buffer
// Find the max value
gMax := 0 ;
gMaxIndex := 0 ;
For i := 0 to length(SavedFrameData)-1 do
begin
if abs(SavedFrameData[i])> gmax then // use only positives values
begin
gMax := Abs( SavedFrameData[i]);
gMaxIndex := i ;
End;
End;
If gMax > gSensitivity then // Check if level is higher than sensitivity set level
begin
// StopVisualBuffer ;
MainForm.RBdataReady.checked := true ; // set an event to draw graphs
end // gMax > sensivity
else
begin // gMax is lower then sensitivity
ResetVisualBuffer ;
end;
until gMax > gSensitivity ;
Processing := False ;
FreeMem(Buffer) ;
//snd_pcm_close (Capture_handle) is called from main by Stop Recording ;
end;
Procedure StopRecording ;
begin
snd_pcm_Close (Capture_Handle) ;
end;