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

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)
(:key-down (key)
(when (= key (char-code #\q))
(:quit ()

;; Function to start the alarm
(defun start-alarm (time-value song-path)
(if (not (before-time-p time-value (get-time)))
(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")

No comments: