суббота, 3 марта 2012 г.

Проигрываем wav файл на clojure

В свою игру я захотел добавить немного звука и стал разбираться с тем, как из clojure воспроизводить звук. Проще всего оказалось применить код из примера работы со звуком . Пример большой. Java поддерживает многие возможности работы со звуком, я выдрал самый простой вариант, когда проигрывается .wav файл, загружаясь целиком в память.

Открываем поток:

(defn create-stream [file]
  (AudioSystem/getAudioInputStream file))

Создаем объект Info описывающий наш звуковой файл

(defn create-info [stream]
  (let [format (.getFormat stream)]
      (DataLine$Info. Clip
     format
     (* (.getFrameLength stream)
(.getFrameSize format)))))

По объекту Info создаем Clip для проигрывания

(defn create-clip [info]
  (AudioSystem/getLine info))

Вот так выглядит код проигрывающий файл:

(defn play [file]
  (let [stream (create-stream file)
clip (create-clip (create-info stream))]
    (.open clip stream)
    (.start clip)
    (Thread/sleep 99)
    (loop [active (.isActive clip)]
      (if active
(do
 (Thread/sleep 99)
 (recur (.isActive clip)))))
    (.stop clip)
    (.close clip)))

Тут присутствует магия с потоками, которая позволяет отслеживать окончание проигрывания клипа и закрывать ресурсы по окончанию.

четверг, 1 марта 2012 г.

clojure-mode + paredit-mode + show-paren-mode

Я использую emacs для программирования на Clojure. И оказалось, что paredit-mode чудо как хорош при работе со скобочками. Ты просто пишешь код, а редактор сам следит за тем, что скобочек было необходимое и достаточное количество. У меня 2 компьютера один под Mac OS, другой под Windows. Под мак есть хорошая сборка Emacs AquaMacs, в которой у меня сразу заработали clojure-mode + paredit-mode + show-paren-mode. Под виндой пришлось немного помучится. Paredit писал ошибку рекурсивной загрузки библиотеки "recursive load", что я вылечил
строчкой в .emacs:

(load (expand-file-name "~/.emacs.d/elpa/paredit-20/paredit.el"))

Это не очень хороший вариант, из моих скромных познаний elisp следует, что emacs при каждом запуске компилит этот плагин, но другого способа запустить paredit я не нашел.

А теперь я решил еще одну проблему. Чтобы каждый раз открывая clj файл, у меня запуска сладкая троечка, добавил два хука:


(add-hook 'clojure-mode-hook (lambda () (paredit-mode +1)))
(add-hook 'clojure-mode-hook (lambda () (show-paren-mode +1)))

Это заработала. Жизнь определенно налаживается. И возможно скоро моя игра для самых маленьких станет значительно интереснее.