为什么AudioSystem.getMixerInfo()在sbt和Scala下返回不同的结果?

时间:2014-06-10 15:39:46

标签: scala audio sbt

经过大量的问题隔离后,我得到了这个片段:

object Snippet  {
    def main(args: Array[String]): Unit = {
        println("Snip demo:: "+ util.Properties.versionString)
        println(" jvm "+System.getProperty("java.version"))
        import javax.sound.sampled._
        val mixers : Array[Mixer.Info] = javax.sound.sampled.AudioSystem.getMixerInfo()
        println(" Numer of mixers: "+ mixers.size)
        for (mi : Mixer.Info <- mixers ) { 
            println("mixer info "+mi.getName) 
        } 
    }
}

令人惊讶的是,运行sbt run后的输出与运行scala后的输出不同:

$ sbt run
Loading /cygdrive/c/Program Files (x86)/sbt/bin/sbt-launch-lib.bash
[warn] The global sbt directory is now versioned and is located at         ....
[warn]   You are seeing this warning because there is global configuration ....
[warn]   The global sbt directory may be changed via the sbt.global.base system property.
[info] Set current project to snippet (in build file:/Documents/SbtProjects/Snippet/)
[info] Compiling 1 Scala source to Documents\SbtProjects\Snippet\target\scala-2.10\classes...
[info] Running Snippet
Snip demo:: version 2.10.2
 jvm 1.7.0_21
 Numer of mixers: 0
[success] Total time: 3 s, completed 10-Jun-2014 15:35:34

$ scala src/main/scala/snippet.scala
Snip demo:: version 2.10.2
 jvm 1.7.0_21
 Numer of mixers: 12
 mixer info Primary Sound Driver
 mixer info Speakers (Plantronics C320)
 mixer info Realtek Digital Output (Realtek High Definition Audio)
 mixer info Speakers (Realtek High Definition Audio)
 mixer info Realtek Digital Output(Optical) (Realtek High Definition Audio)
 mixer info Primary Sound Capture Driver
 mixer info Microphone (Plantronics C320)
 mixer info Port Speakers (Plantronics C320)
 mixer info Port Realtek Digital Output (Realtek
 mixer info Port Speakers (Realtek High Definiti
 mixer info Port Realtek Digital Output(Optical)
 mixer info Port Microphone (Plantronics C320)

我必须遗漏一些非常基本的东西。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:8)

这是一个类加载器问题。 javax.sound不喜欢让上下文类加载器不是系统类加载器。这在我当地解决了这个问题:

object Snippet  {
    def main(args: Array[String]): Unit = {
        println("Snip demo:: "+ util.Properties.versionString)
        println(" jvm "+System.getProperty("java.version"))
        import javax.sound.sampled._
        val cl = classOf[javax.sound.sampled.AudioSystem].getClassLoader
        val old = Thread.currentThread.getContextClassLoader
        try {
          Thread.currentThread.setContextClassLoader(cl)
          val mixers : Array[Mixer.Info] = javax.sound.sampled.AudioSystem.getMixerInfo()
          println(" Numer of mixers: "+ mixers.size)
          for (mi : Mixer.Info <- mixers ) { 
            println("mixer info "+mi.getName) 
          }
       } finally Thread.currentThread.setContextClassLoader(old) 
    }
}

输出:

> run
[info] Compiling 1 Scala source to /home/jsuereth/projects/sbt/diagnose/sound-issues/target/scala-2.10/classes...
[info] Running Snippet 
Snip demo:: version 2.10.4
 jvm 1.7.0_55
 Numer of mixers: 9
mixer info default [default]
mixer info PCH [plughw:0,0]
mixer info NVidia [plughw:1,3]
mixer info NVidia [plughw:1,7]
mixer info NVidia [plughw:1,8]
mixer info NVidia [plughw:1,9]
mixer info Port PCH [hw:0]
mixer info Port NVidia [hw:1]
mixer info Port Unknown Name
[success] Total time: 2 s, completed Aug 1, 2014 11:00:03 AM
>