0

I try to load my sounds from my resource folder when trying out my Application in the IDE.

For images and other stuff that uses InputStreams I use this method:

@Override
public InputStream readAsset(String fileName) throws IOException {
    ClassLoader classloader = Thread.currentThread().getContextClassLoader();
    InputStream is = classloader.getResourceAsStream(fileName);
    return is;
}

this lets me open an Inputstream of which I can pull Images.

As soon as I would try to cast this InputStream to an Audio InputStream I get errors. Also if I would try to make a new AudioInputStream passing the above InputStream as the parameter.

This is my current way to load sounds from external paths:

public class JavaSound implements Sound {

private Clip clip;


public JavaSound(String fileName){
    try {
        File file = new File(fileName);
        if (file.exists()) {

            //for external storage Path
            AudioInputStream sound = AudioSystem.getAudioInputStream(file);

            // load the sound into memory (a Clip)
            clip = AudioSystem.getClip();
            clip.open(sound);
        }
        else {
            throw new RuntimeException("Sound: file not found: " + fileName);
        }
    }
    catch (MalformedURLException e) {
        e.printStackTrace();
        throw new RuntimeException("Sound: Malformed URL: " + e);
    }
    catch (UnsupportedAudioFileException e) {
        e.printStackTrace();
        throw new RuntimeException("Sound: Unsupported Audio File: " + e);
    }
    catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException("Sound: Input/Output Error: " + e);
    }
    catch (LineUnavailableException e) {
        e.printStackTrace();
        throw new RuntimeException("Sound: Line Unavailable Exception Error: " + e);
    }


}

@Override
public void play(float volume) {

    // Get the gain control from clip
    FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);

    // set the gain (between 0.0 and 1.0)
    float gain = volume;
    float dB = (float) (Math.log(gain) / Math.log(10.0) * 20.0);
    gainControl.setValue(dB);

    clip.setFramePosition(0);  // Must always rewind!
    clip.start();
}

@Override
public void dispose() {
    clip.close();
}
}

how can i exchange the AudioInputStream part to work like the first code, pulling the files out of my resource directory?

EDIT : this way of creating a new AudioInputStream by passing an InputStream

File file = new File(fileName);
        if (file.exists()) {
            ClassLoader classloader = Thread.currentThread().getContextClassLoader();
            InputStream is = classloader.getResourceAsStream(fileName);

            //for external storage Path
            AudioInputStream sound = new AudioInputStream(is);

            // load the sound into memory (a Clip)
            clip = AudioSystem.getClip();
            clip.open(sound);
}

also throws errors before even running it

Yesyoor
  • 157
  • 1
  • 18
  • I do not see a constructor for `AudioInputStream` that only accepts an input stream. [This Javadoc](https://docs.oracle.com/javase/8/docs/api/javax/sound/sampled/AudioInputStream.html) indicates the options are `AudioInputStream(InputStream stream, AudioFormat format, long length)` or `AudioInputStream(TargetDataLine line)`. The method `AudioSystem.getAudioInputStream(InputStream stream)` appears to take the input stream alone (as suggested in the answer). However, note the limitations in the Javadocs. – KevinO Apr 22 '16 at 18:38
  • lol how am i supposed to know the length in frames...how annoying is that? AudioSystem.getAudioInputStream(InputStream stream) this does not work! It throws a runtime error – Yesyoor Apr 22 '16 at 18:39

2 Answers2

1

this made it work in my above code:

public JavaSound(String fileName){
    try {

        ClassLoader classloader = Thread.currentThread().getContextClassLoader();
        InputStream is = classloader.getResourceAsStream(fileName);
        AudioInputStream sound = AudioSystem.getAudioInputStream(new BufferedInputStream(is));

        // load the sound into memory (a Clip)
        clip = AudioSystem.getClip();
        clip.open(sound);
    }
    catch (MalformedURLException e) {
        e.printStackTrace();
        throw new RuntimeException("Sound: Malformed URL: " + e);
    }
    catch (UnsupportedAudioFileException e) {
        e.printStackTrace();
        throw new RuntimeException("Sound: Unsupported Audio File: " + e);
    }
    catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException("Sound: Input/Output Error: " + e);
    }
    catch (LineUnavailableException e) {
        e.printStackTrace();
        throw new RuntimeException("Sound: Line Unavailable Exception Error: " + e);
    }


}

just had to start a new bufferedInputStream with my inputStream to have the AudioInputStream... :D still thanks a lot ;)

Yesyoor
  • 157
  • 1
  • 18
0

You cannot cast InputStream to AudioInputStream (you could do the inverse). The Clip.open() wants an AudioInputStream.

An approach, suggested by this answer here is to use the URL from the .getResource() call, rather than attempting to open the InputStream and then pass that in.

Therefore, try:

URL soundURL = classloader.getResource(fileName);
AudioInputStream ais = AudioSystem.getAudioInputStream(soundURL);
Community
  • 1
  • 1
KevinO
  • 4,303
  • 4
  • 27
  • 36
  • I tried both: see my edit above but it gave me error too. – Yesyoor Apr 22 '16 at 18:32
  • @railwanderer, OK. That's the limit of my working knowledge with the Audio system. I'll delete this answer in a bit since it doesn't help. Sorry neither approach worked. – KevinO Apr 22 '16 at 18:40
  • no problem still thank you very much for trying to help me :) when i figure it out I ll post the solution – Yesyoor Apr 22 '16 at 18:41
  • can i avoid using this clip thing at all and just go with regular streams and some .out method? :D – Yesyoor Apr 22 '16 at 18:43
  • 1
    @railwanderer, The thing is, having just done a quick search, is that [this post](http://stackoverflow.com/questions/8425481/play-wav-file-from-jar-as-resource-using-java) seems to imply using the `AudioSystem.getAudioInputStream() and sending it the `URL` rather than the `InputStream` should work. – KevinO Apr 22 '16 at 18:43
  • @railwanderer, updated the answer to suggest using a URL. Hope that works! – KevinO Apr 22 '16 at 18:46
  • i can´t get it to work properly :( if you want to take a closer look at my poor game framework see here: https://github.com/Railwanderer/AndroidGameFramework its downloadable and testable. the java module being the javalib folder it keeps telling me the file would not exist but see yourself its definitely in the right place. the first method for images worked too – Yesyoor Apr 22 '16 at 18:50
  • did you take a look at my repository? :) – Yesyoor Apr 22 '16 at 19:59