Search code examples
javajavax

No method named getClip was found in type "javax.sound.sampled.AudioSystem"


Trying to play and audio clip in java, but this error pops up every time. I imported everything I need to so I'm not sure what the issue is.

AudioInputStream audioInputStream = AudioSystem.getAudioInputStream (this.getClass ().getResource ("hopes_and_dreams.wav"));
                Clip clip = AudioSystem.getClip ();
                clip.open (audioInputStream);
                clip.start ();
javax.sound.sampled.LineUnavailableException: Failed to allocate clip data: Requested buffer too large.
    at com.sun.media.sound.MixerClip.implOpen(Unknown Source)
    at com.sun.media.sound.MixerClip.open(Unknown Source)
    at com.sun.media.sound.MixerClip.open(Unknown Source)
    at CA_PeterLang.paint(CA_PeterLang.java:828)
    at javax.swing.JComponent.paintChildren(Unknown Source)
    at javax.swing.JComponent.paint(Unknown Source)
    at javax.swing.JComponent.paintChildren(Unknown Source)
    at javax.swing.JComponent.paint(Unknown Source)
    at javax.swing.JLayeredPane.paint(Unknown Source)
    at javax.swing.JComponent.paintChildren(Unknown Source)
    at javax.swing.JComponent.paintWithOffscreenBuffer(Unknown Source)
    at javax.swing.JComponent.paintDoubleBuffered(Unknown Source)
    at javax.swing.JComponent.paint(Unknown Source)
    at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
    at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
    at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
    at java.awt.Container.paint(Unknown Source)
    at sun.awt.RepaintArea.paint(Unknown Source)
    at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

Solution

  • The issue of the OP and not being able to find the method is related to the Ready to Program IDE which is apparently running Java 1.4. The .getClip() method in the question was added in Java 1.5 according to the JavaDocs for AudioSystem

    However, I have, in the past, had issues where the system would not find my specific speakers, so the following approach has worked for me. Note that I use a URL, but it should be adaptable to a getResource() approach.

    private Mixer.Info getSpeakers()
    {
        Mixer.Info speakers = null;
        Mixer.Info[] mixerInfo = AudioSystem.getMixerInfo();
        for (Mixer.Info mi : mixerInfo) {
            // System.out.println(mi.getName() + "\t" +
            // mi.getDescription());
    
            if (mi.getName().startsWith("Speakers")) {
                speakers = mi;
            }
        }
    
        System.out.println(
                (speakers != null ? speakers.getName() : "<no speakers>"));
    
        return speakers;
    }    
    
    public void playSound(String soundFile)
    {
        AudioInputStream ais = null;        
        try {
            URL url = new File(soundFile).toURI().toURL();
    
            ais = AudioSystem.getAudioInputStream(url);
    
            Mixer mixer = AudioSystem.getMixer(getSpeakers());
    
            DataLine.Info dataInfo = new DataLine.Info(Clip.class, null);
    
            Clip clip = (Clip)mixer.getLine(dataInfo);
    
            clip.open(ais);
            clip.start();
    
            do {
                try {
                    Thread.sleep(50);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            while (clip.isActive());            
        }
        catch (UnsupportedAudioFileException | IOException |
                LineUnavailableException e) 
        {
            e.printStackTrace();
        }        
    }
    

    When called with playSound("Alarm01.wav"), it properly executes. I think this approach uses slightly older methods.

    Edit: please do not follow my names here -- they are hacked for testing.

    Edit 2: the foreach loop may be changed to:

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

    Edit 3: to use as an InputStream rather than a URL, use

    InputStream is = this.getClass().getClassLoader().getResourceAsStream(soundName);
    // add a check for null
    ais = AudioSystem.getAudioInputStream(is);
    

    Edit 4: This method works with Java 1.4 (to the best of my knowledge). I had to hack around on my local machine settings to get the sound, but that is a different issue.

    public void playSoundOldJava(String soundFile)
    {
        try {
            InputStream is = this.getClass().getClassLoader().getResourceAsStream(soundFile);
    
            // TODO: add check for null inputsteam
            if (is == null) {
                throw new IOException("did not find " + soundFile);
            }
    
            AudioInputStream ais = AudioSystem.getAudioInputStream(is);
    
            DataLine.Info dataInfo = new DataLine.Info(Clip.class, ais.getFormat());
    
            if (AudioSystem.isLineSupported(dataInfo)) {
                Clip clip = (Clip)AudioSystem.getLine(dataInfo);
                System.out.println("open");
                clip.open(ais);
    
                clip.start();
                do {
                    try {
                        Thread.sleep(50);
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                while (clip.isActive());                  
    
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }