Список входных и выходных аудиоустройств в апплете - PullRequest
4 голосов
/ 01 ноября 2011

Я использую подписанный апплет, который должен предоставить пользователю возможность выбирать аудиоустройства ввода и вывода (аналогично тому, что предоставляет Skype).

Я позаимствовал следующий код из другого потока :

import javax.sound.sampled.*;
public class SoundAudit {
  public static void main(String[] args) { try {
    System.out.println("OS: "+System.getProperty("os.name")+" "+
      System.getProperty("os.version")+"/"+
      System.getProperty("os.arch")+"\nJava: "+
      System.getProperty("java.version")+" ("+
      System.getProperty("java.vendor")+")\n");
      for (Mixer.Info thisMixerInfo : AudioSystem.getMixerInfo()) {
        System.out.println("Mixer: "+thisMixerInfo.getDescription()+
          " ["+thisMixerInfo.getName()+"]");
        Mixer thisMixer = AudioSystem.getMixer(thisMixerInfo);
        for (Line.Info thisLineInfo:thisMixer.getSourceLineInfo()) {
            if (thisLineInfo.getLineClass().getName().equals(
              "javax.sound.sampled.Port")) {
              Line thisLine = thisMixer.getLine(thisLineInfo);
              thisLine.open();
              System.out.println("  Source Port: "
                +thisLineInfo.toString());
              for (Control thisControl : thisLine.getControls()) {
                System.out.println(AnalyzeControl(thisControl));}
              thisLine.close();}}
        for (Line.Info thisLineInfo:thisMixer.getTargetLineInfo()) {
          if (thisLineInfo.getLineClass().getName().equals(
            "javax.sound.sampled.Port")) {
            Line thisLine = thisMixer.getLine(thisLineInfo);
            thisLine.open();
            System.out.println("  Target Port: "
              +thisLineInfo.toString());
            for (Control thisControl : thisLine.getControls()) {
              System.out.println(AnalyzeControl(thisControl));}
            thisLine.close();}}}
  } catch (Exception e) {e.printStackTrace();}}
  public static String AnalyzeControl(Control thisControl) {
    String type = thisControl.getType().toString();
    if (thisControl instanceof BooleanControl) {
      return "    Control: "+type+" (boolean)"; }
    if (thisControl instanceof CompoundControl) {
      System.out.println("    Control: "+type+
        " (compound - values below)");
      String toReturn = "";
      for (Control children:
        ((CompoundControl)thisControl).getMemberControls()) {
        toReturn+="  "+AnalyzeControl(children)+"\n";}
      return toReturn.substring(0, toReturn.length()-1);}
    if (thisControl instanceof EnumControl) {
      return "    Control:"+type+" (enum: "+thisControl.toString()+")";}
    if (thisControl instanceof FloatControl) {
      return "    Control: "+type+" (float: from "+
        ((FloatControl) thisControl).getMinimum()+" to "+
        ((FloatControl) thisControl).getMaximum()+")";}
    return "    Control: unknown type";}
}

Но что я получаю:

Mixer: Software mixer and synthesizer [Java Sound Audio Engine]
Mixer: No details available [Microphone (Pink Front)]

Я ожидал получить реальный список моих устройств (на панели «Мои настройки» показаны 3 устройства вывода и 1 микрофон). Я работаю на Mac OS X 10.6.7.

Есть ли другой способ получить эту информацию из Java?

Ответы [ 3 ]

4 голосов
/ 16 ноября 2011

В течение многих лет было очень прискорбным ограничением реализации Java для OS X, так как, кстати, специально для этой платформы, «Java Sound Audio Engine» является единственной программно доступной линией вывода звука.Следовательно, все, что вы отправляете в эту строку, то есть из любого созданного вами Java-приложения, всегда будет перенаправлено на то, что было установлено как выход по умолчанию в OS X, обычно это внутренние динамики.Таким образом, JSAE - это просто терминология Java для «аудио выхода по умолчанию».Насколько мы понимаем, к сожалению, это все еще относится к последнему выпуску.

Почему неудачно?Потому что это эффективно отключает даже скромную маршрутизацию звука.Мы работаем с этими вопросами ежедневно, и это требует всевозможных дополнительных сложностей.Есть обходные пути, но через сторонние приложения, такие как SoundFlower и HiJack Pro.www.soundPimp.com, например.

2 голосов
/ 13 ноября 2011

Может быть, вы можете изменить и использовать это. Следующий код используется для выбора устройств вывода звука на двух моих апплетах. Меня интересовали только выходные строки, а не порты или входные линии. В первой части перечислены параметры в группе параметров в раскрывающемся меню. Вторая часть устанавливает переменную микшера на основе выбранной опции.

private void createMenuBars(){
    JMenuBar menuBar = new JMenuBar();
    menuBar.setBounds(0, 0, 60, 20);

    JMenu optionMenu = new JMenu("Options");
    JMenuItem pickMixers = new JMenuItem("Select a Playback Path");
    optionMenu.add(pickMixers);
    optionMenu.addSeparator();

    ButtonGroup mixerSelections = new ButtonGroup();

    addMixerOption("default sound system", mixerSelections, optionMenu, true);

    AudioFormat audioFmt = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
        44100, 16, 2, 4, 44100, false);
    Mixer.Info[] mixers = AudioSystem.getMixerInfo();
    for (Mixer.Info info : mixers) 
    {
        Mixer mixer = AudioSystem.getMixer(info);

        try
        {
//          System.out.println(info);
            Info sdlLineInfo = new DataLine.Info(SourceDataLine.class, audioFmt);

            // test if line is assignable
            @SuppressWarnings("unused")
            SourceDataLine sdl = (SourceDataLine) mixer.getLine(sdlLineInfo);

            // if successful, add to list
            addMixerOption(info.getName() + " <> " + info.getDescription(),
                mixerSelections, optionMenu, false);
        }
        catch (LineUnavailableException e) 
        {
            //e.printStackTrace();
            System.out.println("Mixer rejected, Line Unavailable: " + info);
        }
        catch (IllegalArgumentException e)
        {
            //e.printStackTrace();
            System.out.println("Mixer rejected, Illegal Argument: " + info);
        }           
    }

    menuBar.add(optionMenu);
    add(menuBar,0);
}

private void addMixerOption(String optionName, ButtonGroup bg, 
    JMenu menu, boolean isSelected
{
    JRadioButtonMenuItem newOption = new JRadioButtonMenuItem(optionName);
    bg.add(newOption);
    newOption.setSelected(isSelected);
    menu.add(newOption);
    newOption.addActionListener(new OptionListener());
    newOption.setActionCommand(optionName); 
}

Вот где переменная микшера устанавливается при выборе опции.

public class OptionListener implements ActionListener 
{
    @Override
    public void actionPerformed(ActionEvent arg0) 
    {
        String optionName = arg0.getActionCommand();
        Boolean defaultMixer = true;

        Mixer.Info[] mixers = AudioSystem.getMixerInfo();
        for (Mixer.Info info : mixers)
        {
            if (optionName.equals(info.getName()+" <> "+info.getDescription()))
            {
                System.out.println("Option selected >  " + info.getName());
                System.out.println("    description >  " + info.getDescription());
                System.out.println("          class >  " + info.getClass());

                appMixer = AudioSystem.getMixer(info);
                System.out.println(appMixer);
                defaultMixer = false;
            }
        }
        if (defaultMixer) 
        {
            System.out.println("Using default mixer, whatever that is...");
            appMixer = null;
        }
    }
}

Существует переизбыток консольных сообщений. Я использую это в http://hexara.com/VSL/JTheremin.htm

1 голос
/ 14 ноября 2011

Это может быть связано с тем, что JVM не поддерживает получение этой информации в OS X или ваши устройства могут не поддерживаться Я бы сделал две вещи:

  • попробуй с другой JVM
  • попробуй на другой ОС

Я запустил код на linux и все детали получил правильно:

OS: Linux 2.6.38-12-generic/amd64
Java: 1.6.0_22 (Sun Microsystems Inc.)

Mixer: the ear-candy mixer [PulseAudio Mixer]
Mixer: Direct Audio Device: default, default, default [default [default]]
Mixer: Direct Audio Device: HDA Intel, ALC662 rev1 Analog, ALC662 rev1 Analog [Intel [plughw:0,0]]
Mixer: Direct Audio Device: Plantronics Headset, USB Audio, USB Audio [Headset [plughw:1,0]]
Mixer: Direct Audio Device: USB Device 0x46d:0x8b2, USB Audio, USB Audio [U0x46d0x8b2 [plughw:2,0]]
Mixer: HDA Intel, Realtek ALC662 rev1 [Port Intel [hw:0]]
  Source Port: Mic Boost source port
    Control: Mic Boost (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Balance (float: from -1.0 to 1.0)
  Source Port: Capture source port
    Control: Capture (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Balance (float: from -1.0 to 1.0)
      Control: Select (boolean)
  Source Port: Capture source port
    Control: Capture (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Balance (float: from -1.0 to 1.0)
      Control: Select (boolean)
  Target Port: Master target port
    Control: Master (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Mute (boolean)
  Target Port: Headphone target port
    Control: Headphone (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Balance (float: from -1.0 to 1.0)
      Control: Mute (boolean)
  Target Port: Speaker target port
    Control: Speaker (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Balance (float: from -1.0 to 1.0)
      Control: Mute (boolean)
  Target Port: PCM target port
    Control: PCM (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Balance (float: from -1.0 to 1.0)
      Control: Mute (boolean)
  Target Port: Line target port
    Control: Line (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Balance (float: from -1.0 to 1.0)
      Control: Mute (boolean)
  Target Port: Mic target port
    Control: Mic (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Balance (float: from -1.0 to 1.0)
      Control: Mute (boolean)
  Target Port: Mic Boost target port
    Control: Mic Boost (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Balance (float: from -1.0 to 1.0)
Mixer: Plantronics Headset, USB Mixer [Port Headset [hw:1]]
  Source Port: Bass source port
    Control: Bass (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
  Source Port: Treble source port
    Control: Treble (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
  Source Port: Mic source port
    Control: Mic (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Select (boolean)
  Target Port: Bass target port
    Control: Bass (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
  Target Port: Treble target port
    Control: Treble (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
  Target Port: PCM target port
    Control: PCM (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Balance (float: from -1.0 to 1.0)
      Control: Mute (boolean)
Mixer: USB Device 0x46d:0x8b2, USB Mixer [Port U0x46d0x8b2 [hw:2]]
  Source Port: Mic source port
    Control: Mic (compound - values below)
      Control: Volume (float: from 0.0 to 1.0)
      Control: Select (boolean)
...