Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does AudioSystem.getMixerInfo() return different results under sbt vs Scala?

Tags:

scala

sbt

audio

After a lot of problem isolation, I got this snippet:

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) 
        } 
    }
}

Amazingly the output after running sbt run is different than than running 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)

I must be missing something very fundamental. Any help very much appreciated.

like image 466
Germán Bouzas Avatar asked Jun 10 '14 15:06

Germán Bouzas


1 Answers

This is a classloader issue. javax.sound does NOT like having the context classloader be anything other than the system classloader. This fixes it for me locally:

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) 
    }
}

And the output:

> 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
> 
like image 115
jsuereth Avatar answered Dec 08 '22 10:12

jsuereth