I would like to know whether 15 mega is quite heavy applet to load?
My main problem are two sound files(.Au) that its weight is about 9 mega bytes.
Anybody has suggestion of how to use mp3 maybe instead or other ideas of reducing weight?
Thanks
Relevant code:
public class DJ
{
private ArrayList<Clip> m_Records = new ArrayList<Clip>();
private int m_CurrentRecored = 0;
private Thread m_MusicThread = null;
private AppletContext m_AppletContext;
//java.net.URL m_CodeBase;
//AppletContext ac;
public DJ()
{
try
{
createClip(getClass().getResourceAsStream("/Music/train.mp3"));
createClip(getClass().getResourceAsStream("/Music/machine.mp3"));
}
catch (Exception ex)
{
Logger.getLogger(DJ.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void createClip(java.io.InputStream i_SoundFileStream) throws Exception
{
InputStream i = new AudioStream(i_SoundFileStream);
AudioInputStream sound = AudioSystem.getAudioInputStream(i);
// load the sound into memory (a Clip)
DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(sound);
m_Records.add(clip);
}
Anybody has suggestion of how to use mp3 maybe instead ..
Add the mp3plugin.jar of the JMF to the run-time class-path of the applet (in the archive element) and Java Sound will be able to open the MP3s as though they were a wav or au.
The MP3 plugin will not be able to parse some of the more modern MP3s that do non-standard things like including cover art in the MP3, but encode them using a standard MP3 format and it will handle them OK.
..what did you mean to add the mp3plugin.jar to the run time class path of the applet (in the archive element)?
<HTML>
<BODY>
<APPLET
archive="MyGame.jar,mp3plugin.jar"
code="GUI.JPanelGameApplet"
width=800
height=580>
</APPLET>
</P>
</BODY>
</HTML>
Note that I also changed Archive to archive (just to keep things consistent) and
code="GUI/JPanelGameApplet.class"
(generally tolerated, but not correct) to
code="GUI.JPanelGameApplet"
(which presumes the applet is in the GUI package). If the applet is not in the GUI package, the element should be written differently.
I've downloaded the MP3 plugin in the exe format ..
Ignore the EXE link and download the Zip!
..I installed it"
Don't bother to run/install the EXE (an EXE is no use to end users on Mac. or Unix/Linux). Just expand the Zip and add the Jar to the run-time class-path
I'll definitely do that code changes in the HTML..
That will be 'problem solved' (for the embedded applet).
You could use JLayer for using mp3's.
One option to lower your applet size is load the audio separately or stream it, that way you can at least have a loading bar/image while it's getting the music.
Check out any download time calculator — it's more than a minute on a very good line. Sounds like extremely heavy.
Related
I have this directory structure:
root
resources
.png files
Music.mid
Sound.wav
src
.java files
and I play the sounds from the resources folder using this code
public void play() {
try {
URL defaultSound = getClass().getResource(filename);
AudioInputStream audioInputStream =
AudioSystem.getAudioInputStream(defaultSound);
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start( );
while (clip.isRunning()) {}
}
catch (Exception e) {
e.printStackTrace();
}
}
I pass to it filenames = /resources/Music.mid and /resources/Sound.wav.
It works fine when I run it in IDE, but when I package it into jar (all music files are inside the jar, I checked) it doesn't play sound and throws exception:
FileNotFoundException: syntax error in file name, directory name or disk name.
Why does this happen and how do I fix it?
getClass() returns a URL and not a File object. It does that because classloaders (which is what .getResource uses) are an abstract concept, and 'a resource' can be anything. It does not have to be a file. It can be an entry in a jar file (which is really a zip). It can be an entry in a jmod file (which is a custom container format introduced with JDK9). It can be a blob in a database column. A file on a webdav server. Or even generated on the fly every time you ask for the resource. Anything goes.
Clearly, your audio player library is obsolete or crappy. It DOES allow you to pass a URL to it, but the audio player library you're using will just crash out if that URL is anything except one that represents an actual file on disk.
When running in the IDE, it IS a file on disk. When running as a jar, it is as valid a resource as anything a classloader produces, but due to the failure of this player library to deal with any URL (other than file:// URLs), it crashes.
There are only two solutions:
Get a better library.
Find a temp dir, unpack the resource into it, then hand the temp file (or possibly a URL representing this temp file) to your library.
Option #2 is quite hairy. You need to find a location with write access, and you need to take care of deleting the file after. It's also a waste of disk cycles. But if you must, you can, of course, do so:
public void play() throws Exception {
File f = File.createTempFile("Sound.wav");
f.deleteOnExit();
try (InputStream in = YourPlayer.class.getResourceAsStream("/resources/Sound.wav");
OutputStream out = new FileOutputStream(f)) {
in.transferTo(out);
}
AudioInputStream audioInputStream =
AudioSystem.getAudioInputStream(f.toURI().toURL());
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start( );
while (clip.isRunning()) {}
}
NB: getClass().getResource() is slightly wrong; the right syntax is ClassThisCodeIsIn.class.getResource. Usually both work, but there are cases where the latter works but the former doesn't (such as when you're subclassing). It's a good habit to never write code that is strictly inferior to something that's just as simple, even if in this particular case it probably doesn't matter.
Trying to build a little app for sorting through audio files based on some of their properties. Have managed to grab the Sample Rate and Bit Depth using Minim but can't find anything anywhere for getting the Bit Rate?
Happy to look at taking the program to Javascript if needed but just desperate to find a method for detecting bit rate of a given file.
EDIT: Attempted to try and form an equation based off file size but cannot find a method for detecting MP3 file size either.
You can use jaudiotagger
You will need to download the jar, I managed to get it from maven central
Go to Sketch -> Add File... and select the downloaded jar, it should be added in a folder named code within your sketch folder.
Assuming you have placed an mp3 file in your data folder named audio.mp3 the following code should work, printing out the bit rate in the terminal.
import org.jaudiotagger.audio.mp3.*;
import org.jaudiotagger.audio.AudioFileIO;
void setup() {
File f = new File(dataPath("audio.mp3"));
try {
MP3File mp3 = (MP3File) AudioFileIO.read(f);
MP3AudioHeader audioHeader = mp3.getMP3AudioHeader();
println("" + audioHeader.getBitRate());
}
catch(Exception e) {
e.printStackTrace();
}
}
JAudiotagger supports a variety of file formats and you can use the relevant classes and methods for each one of these.
I suggest you take a look at the javadoc. Be careful of the examples though, the one I used in order to answer your question seems to be faulty, as you can see I had to swap getAudioHeader with getMP3AudioHeader.
This question already has an answer here:
javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input file when loading wav file
(1 answer)
Closed 8 years ago.
I want to play a audio clip from my computer while a game is playing. But i can only use very very short sounds. Is there any similar way to playing songs like i play sound effects?
Im using swing graphics for the game if that matters.
The error i get when i try to use a song
"javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input file"
public static void main(String args[]) {
Sound s = new Sound();
s.playSound("C:/Users/isac/Desktop/banjos.wav");
}
}
public void playSound(String file) {
try {
AudioInputStream audio = AudioSystem.getAudioInputStream(new File(
file));
Clip clip = AudioSystem.getClip();
clip.open(audio);
clip.start();
}
catch (UnsupportedAudioFileException uae) {
System.out.println(uae);
} catch (IOException ioe) {
System.out.println(ioe);
} catch (LineUnavailableException lua) {
System.out.println(lua);
}
}
}
The error message you are getting indicates the problem is probably with the format of the file, not its length.
You can check the format of an audio file by looking at it's properties--usually requires a right click on Windows. The properties that matter may be on an "Advanced" tab. Java can read many formats, but where I've most often seen it hang up is with the following:
a person tries to load a .mp3 or .ogg or other form of compression but hasn't implemented any libraries that can decompress those files (not your situation, since your banjo.wav is a wav).
the .wav is not the standard "CD Quality" format (44100 fps, 16-bit encoding, stereo) but rather something like 24-bit or 32-bit encoding or 48000 or 96000 fps.
Current DAWs often make it easy to record in formats that are superior to "CD Quality" but Java doesn't support them yet.
For the most part, you can convert audio files that are not readable with Java to one that is with Audacity (free), if you aren't working from another home studio program. Be careful where you obtain Audacity as some sites that provide it (other than the official site) will include adware or malware or viruses.
As a side note, for a longer file, it would be better to load into a SourceDataLine for playback instead of a Clip. With a SourceDataLine, you don't have to wait for the entire file to load before it will start playing back, and it won't take up anywhere near as much RAM. The Java Tutorials has a section for Java Sound and a page there specifically on playback.
I want just to perform a simple task. (I'm a java newbie). I want to play an audio clip when a button is clicked.
here's the part of my code(which I did exactly by copying a tutorial from Youtube.)
private void btnPlayActionPerformed(java.awt.event.ActionEvent evt) {
InputStream in;
try{
in=new FileInputStream(new File("C:\\Users\\Matt\\Documents\\dong.wav"));
AudioStream timeupsound=new AudioStream(in);
AudioPlayer.player.start(timeupsound);
}
catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
But the problem is, this doesn't work.
It throws and IOException saying: "could not create audio stream from input stream".
My question is, what am I doing wrong? (as I clearly saw this code work in that youtube video, and I've used the same code. Please help. and once again, I'm a newbie);
The sun package classes should be causing some informative warnings at compile time. Heed them. Don't use classes in that package hierarchy. They are undocumented, are not guaranteed from one Java version to the next, and will probably not be available in a non-Oracle JRE at all.
Instead use the Java Sound based Clip to play audio. See the info. page for working examples.
Note
It might be the WAV is encoded in a format that Java Sound does not support. Media formats are typically 'container formats' that might be encoded using any number of different Codecs. It is likely that WAV is using a more compressive Codec such as MP3 or OGG internally.
I don't know of a Service Provider Interface for the OGG format, but if they are encoded as MP3, you might be able to get it working using the MP3 SPI. See the info. page linked above for details.
Tip
Also change code of the form:
catch (Exception e) { ..
To
catch (Exception e) {
e.printStackTrace(); // very informative! ...
I am working on sound code for a game. And I was using the following code:
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
/**
* This enum encapsulates all the sound effects of a game, so as to separate the sound playing
* codes from the game codes.
* 1. Define all your sound effect names and the associated wave file.
* 2. To play a specific sound, simply invoke SoundEffect.SOUND_NAME.play().
* 3. You might optionally invoke the static method SoundEffect.init() to pre-load all the
* sound files, so that the play is not paused while loading the file for the first time.
* 4. You can use the static variable SoundEffect.volume to mute the sound.
*/
public enum SoundEffect {
EXPLODE("explode.wav"), // explosion
GONG("gong.wav"), // gong
SHOOT("shoot.wav"); // bullet
// Nested class for specifying volume
public static enum Volume {
MUTE, LOW, MEDIUM, HIGH
}
public static Volume volume = Volume.LOW;
// Each sound effect has its own clip, loaded with its own sound file.
private Clip clip;
// Constructor to construct each element of the enum with its own sound file.
SoundEffect(String soundFileName) {
try {
// Use URL (instead of File) to read from disk and JAR.
URL url = this.getClass().getClassLoader().getResource(soundFileName);
// Set up an audio input stream piped from the sound file.
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);
// Get a clip resource.
clip = AudioSystem.getClip();
// Open audio clip and load samples from the audio input stream.
clip.open(audioInputStream);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
// Play or Re-play the sound effect from the beginning, by rewinding.
public void play() {
if (volume != Volume.MUTE) {
if (clip.isRunning())
clip.stop(); // Stop the player if it is still running
clip.setFramePosition(0); // rewind to the beginning
clip.start(); // Start playing
}
}
// Optional static method to pre-load all the sound files.
static void init() {
values(); // calls the constructor for all the elements
}
}
Now when I replace one of the listed *.wav files from the code with my own or even name one of my own to the file name listed from the above code. I receive the follow error:
Exception in thread "main" java.lang.ExceptionInInitializerError
at soundTest.main(soundTest.java:19)
Caused by: java.lang.NullPointerException
at com.sun.media.sound.StandardMidiFileReader.getSequence(Unknown Source)
at javax.sound.midi.MidiSystem.getSequence(Unknown Source)
at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
at SoundEffect.<init>(sfx.java:75)
at SoundEffect.<clinit>(sfx.java:55)
From following the stack URL url is null going in, which is telling me the *.wav file itself is not being read.
I have tried the following lines and yes the *.wav file was present (I am aware that I cannot have three items named the same, I've used one played with it, then commented it out and try again with another one, I just removed the "//" to make is easier to read):
TEST("file://C:/shoot.wav");
TEST("/soundTest/shoot.wav");
TEST("shoot.wav");
As well as, placing a copy of the file in the directory with the package (default), in the src folder, and of course in the root (c:).
How I am envoking the enum is in my main statement where it is all the standard java, main code but with:
SoundEffect.SHOOT.play();
Where exactly does the *.wav file need to be at int he directory? Or if there is another issue I am missing please point it out. I am also using the Eclipse IDE "Kepler," on Windows 8.1. I would like to note the posted code is all I have thus far.
There is some discussion in the comments that Eclipse might be the problem. I seriously doubt Eclipse is the problem. I have loaded hundreds of audio files using Eclipse. Usually I put the files in a sub-directory "audio" that is one level below the calling code, and use the relative address form: "audio/mySound.wav".
Here is how I load my URL:
URL url = this.getClass().getResource("audio/" & fileName);
I am puzzled as to why there are MIDI references in your stack trace. MIDI has nothing to do with loading .wav files, and really should not be involved at all. Are you sure this is the correct stack trace? Why are we seeing references to MIDI?
Sometimes an unrecognizable .wav file format will throw unexpected errors. The most common .wav is 16-bit encoding, 44100 bps, stereo, little-endian. Are your .wav files of this format?
There are some aspects of your code that I haven't seen implemented in this manner, particularly the use of ENUMS. I'll take your word all that has been tested and verified. I tend to just name individual sound objects (using a wrapper for wav files with Clip or SourceDataLine for playback) and use them that way. Could be what you have with that is a good organizational tool, but I'm not clear if it is working as intended.
For example, with Static use of SoundEffect, as in SoundEffect.SHOOT.play(), are you sure it is pointing to the shoot.wav? Have you written a test to verify this? Combining ENUMS and static invocations--it's getting a little tricky for me to follow.