Arthur Ulfeldt
Arthur Ulfeldt

Reputation: 91554

A clojure friendly library for playing sounds

I'm looking for an easy to program library for infrequently playing sounds (notifications and the like) from a clojure function.

edit: like this

(use 'my.sound.lib') 
(play-file "filename")
(beep-loudly)
(bark-like-a-dog)
...

Upvotes: 9

Views: 2828

Answers (2)

Aleksei Zyrianov
Aleksei Zyrianov

Reputation: 2342

Since year 2010 there appeared at least three libraries for audio playback, manipulation, visualization and saving.

clj-audio

A general-purpose audio library built on top of the Java Sound API. Has minimal amount of dependencies, but the project looks pretty abandoned.

Reference in project.clj (the second one is required for playing MP3 files):

[org.clojars.beppu/clj-audio "0.3.0"]
[com.googlecode.soundlibs/mp3spi "1.9.5.4"]

Usage example:

(require '[clj-audio.core :refer :all])

;; Play an MP3 file
(-> (->stream "bell.mp3")
    decode
    play)

;; Playing synthesized sounds is an experimental feature for the library

More details: https://github.com/beppu/clj-audio

Dynne

A simple and easy to use choice. Has tons of dependencies.

Reference in project.clj:

[org.craigandera/dynne "0.4.1"]

Usage example:

(require '[dynne.sampled-sound :refer :all])

;; Play an MP3 file
(play (read-sound "bell.mp3"))

;; Play a synthesized sound
(play (sinusoid 1.0 440))

More details: https://github.com/candera/dynne

Overtone

An advanced option that relies on the SuperCollider synthesis engine. I guess it'd be an overkill for just playing notifications, but I'm referring it here for sake of completeness.

More details: https://github.com/overtone/overtone

Upvotes: 2

Michał Marczyk
Michał Marczyk

Reputation: 84341

OK, with the question now including an API wishlist... ;-)

You can use JLayer for MP3 playback on the JVM. On Ubuntu it's packaged up as libjlayer-java. There's a simple example of use in Java here. A Clojure wrapper:

(defn play-file [filename & opts]
  (let [fis (java.io.FileInputStream. filename)
        bis (java.io.BufferedInputStream. fis)
        player (javazoom.jl.player.Player. bis)]
    (if-let [synchronously (first opts)]
      (doto player
        (.play)
        (.close))
      (.start (Thread. #(doto player (.play) (.close)))))))

Use (play-file "/path/to/file.mp3") to play back an mp3 fly in a separate thread, (play-file "/path/to/file.mp3" true) if you'd prefer to play it on the current thread instead. Tweak to your liking. Supply your own loud beep and barking dog mp3. ;-)

For a load beep and the like, you could also use MIDI... Perhaps this blog entry will be helpful if you choose to try.

Also, the link from my original answer may still be helpful in your tweaking: Java Sound Resources: Links.

Upvotes: 8

Related Questions