Search code examples
javaaudiojavasound

Play sound on specific sound device java


I am trying to do something simple. I want to play sound on a given sound media instead of playing on the default one.

There is my last try, to iterate thought all the media and play a sound. Only the media on the default device play something. Even the default device is not working when is played directly.

public void testSoundPLayer() throws Exception {
    AudioInputStream inputStream = AudioSystem.getAudioInputStream(Main.class.getResourceAsStream(Constants.SOUND_ALERT));

    Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
    for(int i = 0; i < mixerInfo.length; i++)
    {
        Mixer.Info info = mixerInfo[i];

        System.out.println(String.format("Name [%s] \n Description [%s]\n\n", info.getName(), info.getDescription()));
        System.out.println(info.getDescription());

        try
        {
            Clip clip = AudioSystem.getClip(info);
            clip.open(inputStream);
            clip.start();
        }
        catch (Throwable t)
        {
            System.out.println(t.toString());
        }
        Thread.sleep(2000L);
    }
}

I am open to use external librairies, or even to change the default sound card. I just want a "nice" method to play a sound (wav) on a given sound card without OS dependent method.


Solution

  • This is a shame, I have done a huge mistake, I have not reloaded the stream. This means the seconds play doesn't work.

    There is an working example.

    public void testSoundPLayer() throws Exception {
    
    Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
    for(int i = 0; i < mixerInfo.length; i++)
    {
        AudioInputStream inputStream = AudioSystem.getAudioInputStream(Main.class.getResourceAsStream(Constants.SOUND_ALERT));
    
        Mixer.Info info = mixerInfo[i];
    
        System.out.println(String.format("Name [%s] \n Description [%s]\n\n", info.getName(), info.getDescription()));
        System.out.println(info.getDescription());
    
        try
        {
            Clip clip = AudioSystem.getClip(info);
            clip.open(inputStream);
            clip.start();
        }
        catch (Throwable t)
        {
            System.out.println(t.toString());
        }
        Thread.sleep(2000L);
    }
    

    }

    For checking if the device is an input or output use the following method :

    // Param for playback (input) device.
    Line.Info playbackLine = new Line.Info(SourceDataLine.class);
    // Param for capture (output) device.
    Line.Info captureLine = new Line.Info(TargetDataLine.class);
    
    
    private List<Mixer.Info> filterDevices(final Line.Info supportedLine) {
        List<Mixer.Info> result = Lists.newArrayList();
    
        ArrayList<Mixer.Info> infos = Lists.newArrayList(AudioSystem.getMixerInfo());
        for (Mixer.Info info : infos) {
            Mixer mixer = AudioSystem.getMixer(info);
            if (mixer.isLineSupported(supportedLine)) {
                result.add(info);
            }
        }
        return result;
    }