/* Library Syscom, Capture part - Mai 2001 - by JP DANDRIEUX */ /* V1.0 */ /* This library contains the main functions needed for the construction of the capture (video, audio and textual) part, of a SCOL communication system */ struct TtextParam= [ Tid : S, /* user id ot the param owner */ FontSize : S, /* in pixels */ FontEffect : S, /* RTEXT_BOLD bold font, RTEXT_ITALIC italic font, RTEXT_UNDERLINE underlined font, RTEXT_STRIKED striked font, RTEXT_OFFSET subscript font */ FontName : S, /* Arial is the only implemented font in SCOL */ Color : S /* For exemple itoa (make_rgb 0 0 0) for color black */ ] mkTtextParam;; struct TaudioParam= [ Aid : S, /* user id ot the param owner */ FreqMultiplyer : S, /* 1 : 5,5khz ,2 : 11khz ,4 : 22khz or 8 : 44 khz */ nBuffers : S, /* nBuffers is the number of buffers captured during the SYCrecording */ Sample : S, /* 1 : 8 bits or 2 : 16 bits */ Stereo : S /* 1:mono or 2:stereo */ ] mkTaudioParam;; struct TvideoParam= [ Vid : S, /* user id ot the param owner */ Framerate : S, /* Delay between 2 images in microsec */ Width : S, /* Width in pixel, Height is calculated in a 4/3 format */ nbcolor : S, /* Not implemented yet in the webcam driver */ Quality : S /* Compression factor */ ] mkTvideoParam;; /* SYCdefaultId is a variable who must be set in a DMI with a 'set DefaulId=DMSid;' */ typeof SYCdefaultId = I;; /* SYCsend is an user defined function whose role is to carry out the buffer captured */ typeof SYCsend=fun [I S S] I;; /* SYCbaseFrequency is the frequency whose multiple we will use to set the sampling */ var SYCbaseFrequency=5512;; /* SYCbufferSize is the size of a sample at a frequency of 5512 hz */ var SYCbufferSize=160;; /* SYCcodec is the audio codec used */ typeof SYCcodec = GsmCodec;; /* SYCsndrecording is the global boolean parameter for the status of sound capture */ var SYCsndrecording=0;; /* SYCvideorecording is the global boolean parameter for the status of webcam capture */ var SYCvideorecording=0;; /* SYCsndplaying is the global boolean parameter for the status of Playing */ var SYCsndplaying=0;; /* SYCsampleList is a FIFO list where every received audio sample is stacked waiting its turn to be played */ typeof SYCsampleList=[S r1];; /* SYCwebcam is the video captured by the SYCwebcam */ typeof SYCwebcam = Video;; /* SYCmyrecparams is the list of my recorders params */ typeof SYCmyrecparams=[TaudioParam TvideoParam TtextParam];; /* SYCmyplayparams is the list of my players params */ typeof SYCmyplayparams=[TaudioParam TvideoParam TtextParam];; /**/ typeof SYCcamPb=fun [] I;; /* The following functions are used to manage the Sample List in a FIFO way */ /* SYCgetSample removes the SYCsampleList's head and takes its value */ fun SYCgetSample ()= if SYCsampleList==nil then nil else let SYCsampleList -> [a n] in ( set SYCsampleList=n; a ) ;;/* tested */ /* SYCaddTl puts item at the tail of list and takes the value of the new list */ fun SYCaddTl (list,item,n)= if n==0 then nil else let list -> [hd tl] in { if hd==nil then item::nil else hd::SYCaddTl tl item (n-1) } ;;/* tested */ /* SYCaddSample puts smp at the tail of SYCsampleList, it limits the number of buffers in list to 30 !!!!!!!!!!!!!!!!!!!!!!! IT IS AN ARBITRARY CONSTANT*/ fun SYCaddSample (smp)= set SYCsampleList=SYCaddTl SYCsampleList smp 30 ;;/* tested */ /* The following functions set the SYCrecorder for the sound communications, */ /* SYCrecAudioCB and SYCrecAudio16CB are callbacks who receive the captured sound and transform it via the appropriate SYCcodec. The result is transfered to SYCsend a syscom_treatment function */ fun SYCrecAudioCB (srec,param,buf,j)= let strcatn param.Aid::" "::param.FreqMultiplyer::" "::param.nBuffers ::" "::param.Sample::" "::param.Stereo::nil -> para in exec SYCsend with [100 (_AudioGsmEncode buf SYCcodec) para]; 1 ;; fun SYCrecAudio16CB (recorder,param,buf,bufnumber)= let strcatn param.Aid::" "::param.FreqMultiplyer::" "::param.nBuffers ::" "::param.Sample::" "::param.Stereo::nil -> para in exec SYCsend with [100 (_AudioGsmEncode16 buf SYCcodec) para]; 1 ;; /* SYCrecCloseCB sets SYCsndrecording when the SYCrecording is stopped */ fun SYCrecCloseCB (recorder,param)= set SYCsndrecording=0; 1 ;; /* SYCrecOpenCB sets SYCsndrecording when the SYCrecording is started */ fun SYCrecOpenCB (recorder,param)= set SYCsndrecording=1; 1 ;; /* SYCstartRecSnd start the SYCrecording process and sets the SYCrecordind callbacks */ fun SYCstartRecSnd (MyAudioParam)= let ( _sndRecStart _channel (atoi MyAudioParam.FreqMultiplyer)*SYCbaseFrequency (atoi MyAudioParam.FreqMultiplyer)*SYCbufferSize *(atoi MyAudioParam.nBuffers) (atoi MyAudioParam.Sample)*8 (atoi MyAudioParam.Stereo) )-> SYCrecorder in if SYCrecorder !=nil then { if !(strcmp MyAudioParam.Sample "1") then _sndSetRflxRecBuf SYCrecorder @SYCrecAudioCB MyAudioParam else _sndSetRflxRecBuf SYCrecorder @SYCrecAudio16CB MyAudioParam; _sndSetRflxRecOpen SYCrecorder @SYCrecOpenCB MyAudioParam; _sndSetRflxRecClose SYCrecorder @SYCrecCloseCB MyAudioParam; set SYCsndrecording=1 } else set SYCsndrecording=0 ;; /* SYCstopRecSnd stops the current SYCrecording. SYCsndrecording is updated via SYCrecCloseCB */ fun SYCstopRecSnd ()= set SYCsndrecording=0; _sndRecStop ;; /* The following functions set the player for the sound communications */ /*SYCplayAudioCB is a callback who receives the captured sound then plays it*/ fun SYCplayAudioCB (splay,param,i)= let SYCgetSample -> Sample in let (atoi param.nBuffers) ->nbuff in { if (SYCsndplaying) then if (((strlen Sample)==nbuff)|| (Sample==nil)) then { _sndSetPending; nil } else { _sndUnsetPending; Sample } else Sample } ;; /* SYCplayCloseCB is a callback who sets SYCsndplaying when the player is closed */ fun SYCplayCloseCB (splay,i)= set SYCsndplaying=0 ;; /* SYCplayOpenCB is a callback who sets SYCsndplaying when the player is opened */ fun SYCplayOpenCB (splay,i)= set SYCsndplaying=1 ;; /* SYCstartPlaySnd starts the playing process and sets the playing callbacks */ fun SYCstartPlaySnd (HisAudioParam)= let ( _sndPlayStart _channel (atoi HisAudioParam.FreqMultiplyer)*SYCbaseFrequency (atoi HisAudioParam.FreqMultiplyer)*SYCbufferSize *(atoi HisAudioParam.nBuffers) (atoi HisAudioParam.Sample)*8 (atoi HisAudioParam.Stereo) ) -> player in if player!=nil then { _sndSetRflxPlayOpen player @SYCplayOpenCB 0; _sndSetRflxPlayClose player @SYCplayCloseCB 0; _sndSetRflxPlayBuf player @SYCplayAudioCB HisAudioParam; 1 } else 0 ;; /* SYCstopPlaySnd stops the playing process */ fun SYCstopPlaySnd ()= set SYCsndplaying=0; _sndPlayStop ;; /* The following functions set the SYCrecorder for the video communications, */ /* SYCrecVideoCB is a callback who receives the transformed bitmap and transfers it via SYCsend */ fun SYCrecVideoCB (SYCwebcam,param,buffer) = _JCompInit (atoi param.Quality); let strcatn param.Vid::" "::param.Framerate::" "::param.Width::" ":: param.nbcolor::" "::param.Quality::nil -> para in let (_JComp _c15to32 buffer (atoi param.Width) ((3*(atoi param.Width))/4)) ->buf in ( exec SYCsend with [ 10 buf para ] ); 0 ;; /* SYCstartRecVideo sets the video SYCrecorder */ fun SYCstartRecVideo (MyVideoParam)= _JCompInit (atoi MyVideoParam.Quality); let (atoi _getress "videocapture") -> default in let if (default==nil || default==-1) then 0 else default -> driver in ( if SYCwebcam==nil then ( set SYCwebcam= _CRcapWindow _channel nil /* father window */ driver 0 0 /* starting coordinate */ (atoi MyVideoParam.Width) ((3*(atoi MyVideoParam.Width))/4) /* size : width height */ 1 /* Visibility */ (atoi MyVideoParam.Framerate) ) else nil; if (SYCwebcam!=nil) then ( _SETcapVideoStart SYCwebcam @SYCrecVideoCB MyVideoParam; set SYCvideorecording=1 ) else ( set SYCvideorecording=0; /*_DLGMessageBox _channel nil "Problème de SYCwebcam :" "Impossible de démarrer le périphérique de capture vidéo par défaut" 0;*/ exec SYCcamPb with [] ) ) ;; /* SYCstopRecVideo stops the video SYCrecorder */ fun SYCstopRecVideo()= if SYCvideorecording then ( _SETcapVideoStop SYCwebcam; set SYCvideorecording=0; 1 ) else 0; _DScapWindow SYCwebcam; set SYCwebcam=nil ;; /* SYCvideoRecord starts the video recorder if needed */ fun SYCvideoRecord(MyVideoParam)= if (SYCvideorecording==1) then 1 else { SYCstartRecVideo MyVideoParam } ;; /* The following functions are very high level for the Audio */ /* SYCiniAudio is the first audio function to be called. It sets the SYCcodec used */ fun SYCiniAudio()= set SYCcodec=_AudioGsmInit ;; /*SYCplayAudio fills the SYCsampleList whith the new sample received. It starts the player if needed */ fun SYCplayAudio (HisAudioParam,audio)= if (SYCsndplaying==0) then { SYCiniAudio; SYCstartPlaySnd HisAudioParam } else nil; if (atoi HisAudioParam.Sample) == 1 then SYCaddSample _AudioGsmDecode audio SYCcodec else ( SYCaddSample _AudioGsmDecode16 audio SYCcodec ) ;; fun SYChangUp ()= if SYCsndplaying==1 then SYCstopPlaySnd else 0; if SYCsndrecording==1 then SYCstopRecSnd else 0 ;; /* SYCsndRecord starts the audio recorder if needed */ fun SYCsndRecord(MyAudioParam)= if (SYCsndrecording==1) then 1 else { SYCiniAudio; SYCstartRecSnd MyAudioParam } ;; /* SYCpauseRecord ends the SYCrecording process */ fun SYCpauseRecord ()= if (SYCsndrecording==0) then 1 else SYCstopRecSnd ;; /* The following functions are very high level for the Video */ /* SYCiniVideo is the first video function to be called. It sets the comprression factor */ fun SYCiniVideo (MyVideoParam)= _JCompInit (atoi MyVideoParam.Quality) ;; /* SYCplayVideo uncompress and SYCsend the image to the desired display function */ fun SYCplayVideo (HisVideoParam,video)= _c32to15 (_JDecomp video ((3*(atoi HisVideoParam.Width)/4)) (atoi HisVideoParam.Width) (atoi HisVideoParam.Quality) ) ;; /* */ fun SYCrecText(param,buffer)= exec SYCsend with [1 buffer param]; 1 ;; /* TESTS TESTS TESTS TESTS TESTS TESTS TESTS TESTS TESTS TESTS TESTS */ typeof win= ObjWin;; typeof SYCcontainer=ObjContainer;; fun setVideoBitmap(infoCom,mBitmap)= let _GETcontainerPositionSize SYCcontainer -> [ _ _ wcont hcont] in let _CRbitmap _channel wcont hcont -> videobitmap in let _GETbitmapSize mBitmap -> [wbitmap hbitmap] in let _SCPbitmap videobitmap 0 0 wcont hcont mBitmap 0 0 wbitmap hbitmap nil -> videobitmap in let _CRalphaBitmap _channel videobitmap nil nil nil -> myalphabitmap in ( let _CRcompBitmap _channel (SYCcontainer) nil [0 0] OBJ_VISIBLE nil myalphabitmap 0 0 wcont hcont -> mycompBitmap in ( _PAINTcontainer (SYCcontainer); _DSalphaBitmap myalphabitmap; _DSbitmap videobitmap; _DScompBitmap (mycompBitmap); ); ); infoCom ;; fun PrintVid(image,hisid)= if win==nil then ( set win=_CRwindow _channel nil 0 0 320 240 WN_MENU|WN_DOWN "Webcam"; set SYCcontainer = _CRcontainerFromObjWin _channel win 0 0 320 240 CO_CHILDINSIDE nil "Image"; ) else nil; let _CRbitmap _channel 320 240 -> mybmp in let _SETbitmap mybmp (_InvertCapBitmap image 320) -> bitmap in ( setVideoBitmap 1 bitmap; _DSbitmap mybmp ); 1 ;; fun Player(ty,buffer,param)= let SYCmyrecparams ->[aparam vparam _] in if ty==100 then ( SYCplayAudio aparam buffer; 1 ) else ( PrintVid (SYCplayVideo vparam buffer) nil; 1 ) ;; fun photo()= let hd hd strextr _getpack _checkpack "locked/conf/photo.conf" -> myphoto in if myphoto == nil then nil else let _fooS strcat "chemin et nom : " myphoto -> _ in let _fooS strcat "Buffer photo : " (_getpack _checkpack myphoto) -> _ in let (_getpack _checkpack myphoto) -> strphoto in /* recherche si la concatenation des deux premiers caractères = BM. */ let _fooS strcat "BM = " (substr strphoto 0 2) -> _ in let (substr strphoto 0 2) -> signature in if !(strcmp signature "BM") then /*let _DLGMessageBox _channel nil "MOI" "JP" 0 ->_ in*/ let _LDbitmap _channel (_checkpack myphoto) -> photobitmap in let _GETbitmapSize photobitmap -> [wi hi] in let _CRbitmap _channel 320 (3*(320))/4 -> photobitmap2 in let _SCPbitmap photobitmap2 0 0 (320) (3*(320))/4 photobitmap 0 0 wi hi nil -> photobitmap in PrintVid (_InvertCapBitmap (_GETbitmap photobitmap2) (320)) 0 else let (substr strphoto 6 4) -> signature in if !(strcmp signature "JFIF") then let _LDjpeg _channel (_checkpack myphoto) -> photobitmap in let _GETbitmapSize photobitmap -> [wi hi] in let _CRbitmap _channel 320 (3*(320))/4 -> photobitmap2 in let _SCPbitmap photobitmap2 0 0 (320) (3*(320))/4 photobitmap 0 0 wi hi nil -> photobitmap in PrintVid (_InvertCapBitmap (_GETbitmap photobitmap2) (320)) 0 else nil ;; fun main()= _showconsole; set SYCsend=@Player; let mkTaudioParam [itoa SYCdefaultId "2" "2" "2" "2"] ->aparam in let mkTvideoParam [itoa SYCdefaultId "50" "320" nil "20"] -> vparam in ( set SYCmyrecparams=[aparam vparam nil]; /*SYCiniAudio; SYCsndRecord aparam;*/ SYCstartRecVideo vparam; ) ;; /* /* TestList tests the validity of the FIFO functions */ fun TestList()= set SYCsampleList=nil; SYCaddSample "Toto"; SYCaddSample "Toto2"; SYCaddSample "Toto3"; _DLGMessageBox _channel nil "titre" strcatn SYCsampleList 0; _DLGMessageBox _channel nil "titre" SYCgetSample 0; _DLGMessageBox _channel nil "titre" strcatn SYCsampleList 0 ;; /* The following functions are callbacks used by GetAudioParam */ fun _FreeWin(window,param)= _DSwindow window ;; fun _FreqValue(combo,Param,selnumber,selstring)= set Param.FreqMultiplyer= itoa((atoi selstring) / SYCbaseFrequency) ;; fun _SampleValue(combo,Param,selnumber,selstring)= set Param.Sample=itoa ((atoi selstring)/8) ;; fun _StereoValue(combo,Param,selnumber,selstring)= set Param.Stereo=itoa (selnumber+1) ;; /* GetAudioParam create the AudioParam structure and fills it */ fun GetAudioParam ()= let mkTaudioParam [itoa SYCdefaultId "1" "2" "1" "1"] -> Param in let _CRwindow _channel nil 0 0 200 175 WN_DOWN|WN_MENU|WN_MINBOX "Audio Capture" -> win in let _CRcombo _channel win 0 0 70 400 CB_NOEDIT "5512"-> FreqMulCombo in let _CRcombo _channel win 0 55 70 400 CB_NOEDIT "8"-> SampleCombo in let _CRcombo _channel win 0 110 70 400 CB_NOEDIT "Mono"-> StereoCombo in let _CRtext _channel win 75 3 300 50 ET_ALIGN_LEFT "Hz Frequency" -> FreqText in let _CRtext _channel win 75 58 300 50 ET_ALIGN_LEFT "bits Numerisation" -> SampleText in let _CRtext _channel win 75 113 300 50 ET_ALIGN_LEFT "Sample" -> StereoText in { _ADDcombo FreqMulCombo 1 " 5512"; _ADDcombo FreqMulCombo 2 "11024"; _ADDcombo FreqMulCombo 3 "22048"; _ADDcombo FreqMulCombo 4 "44096"; _CBcombo FreqMulCombo @_FreqValue Param; _ADDcombo SampleCombo 1 " 8"; _ADDcombo SampleCombo 2 " 16"; _CBcombo SampleCombo @_SampleValue Param; _ADDcombo StereoCombo 1 "Mono"; _ADDcombo StereoCombo 2 "Stereo"; _CBcombo StereoCombo @_StereoValue Param; _CBwinDestroy win @_FreeWin nil; Param } ;; /* The following functions are callbacks used by GetAudioPAram */ fun _FrameRateValue(combo,Param,selnumber,selstring)= set Param.Framerate=itoa((atoi selstring)*1000) ;; fun _WidthValue(combo,Param,selnumber,selstring)= set Param.Width=selstring ;; fun _QualityValue(combo,Param,selnumber,selstring)= set Param.Quality=selstring ;; /* GetVideoParam create the VideoParam structure and fills it */ fun GetVideoParam ()= let mkTvideoParam [itoa SYCdefaultId "1000000" "32" nil "25"] -> Param in let _CRwindow _channel nil 210 0 200 175 WN_DOWN|WN_MENU|WN_MINBOX "Video Capture" -> win in let _CRcombo _channel win 0 0 70 400 CB_NOEDIT "1000"-> FramerateCombo in let _CRcombo _channel win 0 55 70 400 CB_NOEDIT "32"-> WidthCombo in let _CRcombo _channel win 0 110 70 400 CB_NOEDIT "25"-> QualityCombo in let _CRtext _channel win 75 3 300 50 ET_ALIGN_LEFT "ms Framerate" -> FrameRateText in let _CRtext _channel win 75 58 300 50 ET_ALIGN_LEFT "pixels Width" -> WidthText in let _CRtext _channel win 75 113 300 50 ET_ALIGN_LEFT "% jpg Compression" -> QualityText in { _ADDcombo FramerateCombo 1 "1000"; _ADDcombo FramerateCombo 2 " 250"; _ADDcombo FramerateCombo 3 " 100"; _ADDcombo FramerateCombo 4 " 50"; _CBcombo FramerateCombo @_FrameRateValue Param; _ADDcombo WidthCombo 1 " 32"; _ADDcombo WidthCombo 2 " 64"; _ADDcombo WidthCombo 3 " 128"; _ADDcombo WidthCombo 4 " 256"; _ADDcombo WidthCombo 5 " 320"; _CBcombo WidthCombo @_WidthValue Param; _ADDcombo QualityCombo 1 " 1"; _ADDcombo QualityCombo 2 " 25"; _ADDcombo QualityCombo 3 " 50"; _ADDcombo QualityCombo 4 " 75"; _ADDcombo QualityCombo 5 " 99"; _CBcombo QualityCombo @_QualityValue Param; _CBwinDestroy win @_FreeWin nil; Param } ;; */