Primarily technical blog on Lisp, .NET, C# development.

Friday, August 21, 2009

clbuild and lispbuilder-sdl

On my earlier version of the alarm clock I used the cl-sdl library. I was testing clbuild the other day and I tried to use its version of the sdl: lispbuilder-sdl. Unfortunately on my machine I was getting an error everytime the app was about to close the window due to a call to SDL-glue-SDL-Close-Audio method on the cffi part of the lispbuilder-sdl library:


I suppressed this message by calling a method I knew was working and it worked fine so far.

So if you want to try the same thing, look for the glue.lisp file on the clbuild/source
/lispbuilder-sdl/cffi and change this part to the following code:

#+lispbuilder-sdl-audio

(cffi:defcfun ("SDL_CloseAudio"
SDL-glue-SDL-Close-Audio) :void)

So instead of calling the original method I am using the SDL_CloseAudio and it is working fine so far.

Tuesday, August 18, 2009

Little Alarm Clock in LISP

I wrote this code one of these days because I left the food heating a little too long. I actually burned the pan itself. Anyway it was a little fun project. You give set the time you want it to play a song from your hard drive. Using SDL I was able to play the song and also display a little window to notify about the alarm. You need cl-sdl and cl-sdl-mixer to play the alarm song. If you use ubuntu just install them from the repository using the synaptic package manager.

Here goes the code:

;; Timer

;; Function to return the current time hour and minute in a list
(defun get-time()
(multiple-value-bind (x y z) (get-decoded-time)
(values (list z y) x)))

;; Function to compare if two times are the same
(defun check-time (time-value)
(if (equalp time-value (get-time)) t nil))

;; Function to check if time1 is before time2
(defun before-time-p (time1 time2)
(if (or (< (first time1) (first time2))
(and (equal (first time1) (first time2))
(< (second time1) (second time2))))
nil t))

;; Function to play the alarm song and display the window
(defun play-alarm (song-path)
(sdl:init (logior sdl:+init-audio+ sdl:+init-video+))
(sdl:set-video-mode 320 240 16 sdl:+resizable+)
(sdl:wm-set-caption "Alarm ON!" nil)
(sdl-mix:open-audio 44100 sdl:+audio-s16lsb+ 2 2048)
(let ((music (sdl-mix:load-mus song-path)))
(sdl-mix:play-music music 0)
(sdl:event-loop
(:key-down (key)
(when (= key (char-code #\q))
(progn
(sdl-mix:halt-music)
(sdl-mix:close-audio)
(sdl:quit)
(return))))
(:quit ()
(progn
(sdl-mix:halt-music)
(sdl-mix:close-audio)
(sdl:quit)
(return))))))

;; Function to start the alarm
(defun start-alarm (time-value song-path)
(if (not (before-time-p time-value (get-time)))
nil
(progn
(loop for x from 1
until (check-time time-value)
do (progn (print (get-time)) (sleep 10)))
(format t "~%buzzzzzz... it's ~a:~a~%"
(first time-value)
(second time-value))
(play-alarm song-path))))


; sample usage
;(asdf:oos 'asdf:load-op 'sdl-mix)
;(check-time '(9 38))
;(before-time-p '(12 7) '(12 12))
;(play-alarm "alarm.mp3")
;(start-alarm '(12 15) "alarm.mp3")