compile終了時にキュピーンと音を鳴らしてみる

今書いてるプロジェクトがコンパイルに1分程度かかるようになってきたので、コンパイル終了時に音で知らせてくれたら良くね?とふと思って書いた。
コンパイルの成功/失敗が音で分かるようになります。
ただし使ってると段々うっとうしくなってきます。


sbt0.13でmapRがdeprecatedになってたので修正 (2013/12/20追記)

環境
コード
  • build.sbt
// http://www.scala-sbt.org/release/docs/Detailed-Topics/Tasks.html#handling-failure

//compile in Compile <<= compile in Compile mapR {
compile in Compile <<= (compile in Compile result) map {
  case Inc(inc: Incomplete) =>
    Sound.play("sound/NG.wav")
    throw inc
  case Value(v) =>
    Sound.play("sound/OK.wav")
    v
}
import java.io.File
import javax.sound.sampled._

import scala.concurrent.ops._

// 参考
// http://www.ibm.com/developerworks/jp/java/library/j-5things12/#N101D9

object Sound {

  def play(file: String) {
    spawn {
      val clip = AudioSystem.getClip()
      clip.addLineListener(new LineListener(){
        def update(e: LineEvent) {
          if (e.getType == LineEvent.Type.STOP) {
            clip.synchronized { clip.notify() }
          }
        }
      })
      val soundfile = new File(file)
      val stream = AudioSystem.getAudioInputStream(soundfile)
      clip.open(stream)
      clip.start()
      clip.synchronized {
        clip.wait()
      }
      clip.drain()
      clip.close()
      stream.close()
    }
  }
}

waveファイルは好きなものを自前で用意して好きな所に置いてください。
上の例ではprojectのrootにsoundディレクトリを作ってそこにぶち込みました。
あまり長い音声を設定すると、前の音声が終わらないうちに次のが重なって鳴り始めてひどいことになります。


sbt0.12系はまだscala2.9なのでconcurrent.ops.spwanを使ってますが、sbt0.13からはscala2.10でfuture使えるためsbt0.13-SNAPSHOTを使ってる人はfutureで書いた方がいいです(2.10だとconcurrent.opsは丸ごとdeprecated)