playing a sound - java

I'm very beginner in Java, so ...
I've written a simple Java code to display images from my hard drive wherever I click the mouse, not on the applet, on panel, now how can I make a sound play automatically when I view 6 pictures ?
public void mouseClicked(MouseEvent e) {
if (count == images.length - 1) {
???????????????????????
} else {
count++;
}
x = e.getX();
y = e.getY();
frameTest.repaint();
}
I want to play a sound file from the Hard drive, in the place of question marks ..
can some one help plz ?

Try to write this inside your if :
try
{
Clip clickClip = AudioSystem.getClip();
URL clipURL = new URL("file://C:/aFile.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(clipURL);
clickClip.open(ais);
clickClip.start();
}
catch(Exception e)
{
System.out.ptintln("Something didn't work !\n" + e.printStackTrace());
}
Hope this helps.

Related

Java SoundSystem error

I am trying to make a program that plays sound back to you. How I got the sound was I went to this link and I had it speak some words for about 9 seconds. While he was speaking, I was recording him with Audacity. It recorded him at 16-bit PCM, 48 khz and a stereo channel.
The code I use to play the sound is,
public void playSound(String Path) {
try {
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(Variables.class.getResourceAsStream("/com/project/resources/" + Path));
clip.open(inputStream);
clip.start();
} catch (Exception e) {
e.printStackTrace();
System.err.println(e.getMessage());
}
}
and the error that pops up is at this link.
I have stored the file in another package located at com.project.resources.
If you have any questions about this situation, let me know.

I can't delete a file because it seems 'open'

I'm coding something with an audio part with WAV Files and after 2 days of searching for a bug, I really don't know where the problem is. I guess my thread doesn't stop and that prevents me from deleting a file, but when I'm debugging everything goes well and I've no exceptions or errors.
Here is my interface:
Picture of my interface
So when I want to delete a file by clicking on delete button that launches 'DeleteTrack' method and it works, but when I listen to it first thanks to listen button that launches 'PlaySound' method, I can't delete it, it's like if nothing happen.
Also, when I use 'PlaySound' and then I try to delete my file from windows I have this:
Windows error
Thank you for reading and I'll be very grateful if you could help me and sorry if my English isn't perfect.
GatherFiles method just return my list of waves I've verified it's not null
MajListAudio method refresh my list if I add or delete a song
public void DeleteTrack() {
String song_name = audioList.getSelectedValue();
File[] listeOfFiles = GatherFiles(null);
// Loop to find the file to delete and then delete it.
for(int i=0;i<listeOfFiles.length;i++){
if(song_name.equals(listeOfFiles[i].getName())){
listeOfFiles[i].delete();
}
}
// Refresh the list
MajListAudio();
}
}
So here is the function when I guess there is a problem.
public void PlaySound(File sound){
thread = new Thread(){
#Override public void run(){
try {
// Initialize a clip with our sound file
AudioInputStream audioStream = AudioSystem.getAudioInputStream(sound);
Clip clip = AudioSystem.getClip();
clip.open(audioStream);
// Variable that will updated to fix the percentage of the progressBar
int progressContains =0;
// Size in Seconds of our music
int sizeAudio = (int) (clip.getMicrosecondLength()/1000000);
clip.start();
do{
// indice allow us to know how much the progress bar has to grow every second. We divide with 100 because it's the maximum
//of the bar
int indice = 100/sizeAudio;
// Refresh the value of the bar and prepare her next value
progressBar.setValue(progressContains);
progressContains+= indice;
// The main thread is sleeping for 1s
Thread.sleep(1000);
}while(clip.isActive());
//Reset the bar after a play
clip.stop();
clip.close();
audioStream.close();
progressBar.setValue(0);
} catch (UnsupportedAudioFileException ex) {
ex.printStackTrace();
} catch (LineUnavailableException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
};
thread.start();
}
Others functions
public File[] GatherFiles(DefaultListModel myModel){
// If you want to get the list without implementing the model
if(myModel == null){
File[] both = Concatenate(getListOfFiles("\\cryptedAudio"), getListOfFiles("\\audio"));
return both;
// Same with a model
}else{
audioList.setModel(myModel);
File[] both = Concatenate(getListOfFiles("\\cryptedAudio"), getListOfFiles("\\audio"));
return both;
}
}
public File[] getListOfFiles(String endPath){
String folderPath = new File(".").getAbsolutePath();
folderPath= folderPath.substring(0, folderPath.length()-1);
File folder = new File(folderPath+endPath);
File[] listeOfFiles = folder.listFiles();
return listeOfFiles;
}
/*
*Return a new Array that contains borh arrays in parameters
*/
public <T> T[] Concatenate (T[] a, T[] b) {
int aLen = a.length;
int bLen = b.length;
#SuppressWarnings("unchecked")
T[] c = (T[]) Array.newInstance(a.getClass().getComponentType(), aLen+bLen);
System.arraycopy(a, 0, c, 0, aLen);
System.arraycopy(b, 0, c, aLen, bLen);
return c;
}
I really suspect your threading is an issue. You wait one second after the sound finishes, at the very least. So maybe your delete happens too soon. One way around this, is to read everything from the file, and then make the sound. That way the file should always be closed.
byte[] bytes = Files.readAllBytes(sound.toPath());
AudioInputStream audioStream = AudioSystem.getAudioInputStream(
new ByteArrayInputStream(bytes)
);
Clip clip = AudioSystem.getClip();
clip.open(audioStream);
Since your problem appears to be your file not getting released to the system, we use File.readAllbytes which reads the whole file, and release it back to the OS before you even play a sound.
The concept behind your original setup should work, but it appears that your loop does not finish before you try and delete the file. It could also be that you start more than one thread to access the file.
Have you tried something like
AudioInputStream audioStream = AudioSystem.getAudioInputStream(sound);
Clip clip = AudioSystem.getClip();
clip.open(audioStream);
// play the audio...
clip.close();
audioStream.close();
This is just making sure that the AudioInputStream is getting closed properly since I'm not sure that clip.close() is closing it (though one would think it should...)
This method API AudioSystem.getAudioInputStream(sound) returns an AudioInputStream that you should close.
So better if you first assign the returned value to a local variable:
AudioInputStream inputAudioStream = AudioSystem.getAudioInputStream(sound);
And then you can open it using the clip instance:
Clip clip = AudioSystem.getClip();
clip.open(inputAudioStream);
Finally don't forget to close the inputAudioStream variable:
clip.close();
inputAudioStream.close();
I strongly suggest to use the try-with-resources Statement
try(AudioInputStream inputAudioStream = AudioSystem.getAudioInputStream(sound)) {
// Initialize a clip with our sound file
Clip clip = AudioSystem.getClip();
clip.open(inputAudioStream);
[.... ] your code
clip.close();
progressBar.setValue(0);
}
[.... ] your catch code

Java Thread stopping when hiding to SystemTray

For my parents I am writing a simple program to copy files from their digital photocamera to their 'My Documents' folder. They always need my help (they are not so technically advanced) to get their pictures off their camera so I decided to help them out. I called it The Copying Machine. Since I couldn't find a suitable USB-Listener in Java, I wrote one myself:
private void sync()
{
// All devices in an ArrayList
File[] roots = File.listRoots();
ArrayList<File> newList = new ArrayList<File>();
for(File f : roots)
{
newList.add(f);
}
// Delete unavailable devices
ArrayList<File> removeThese = new ArrayList<File>();
for(File f : devices)
{
if(!newList.contains(f))
{
removeThese.add(f);
}
}
devices.removeAll(removeThese);
// Add unknown devices
for(File f : newList)
{
if(!devices.contains(f) && f.canRead() && f.canWrite())
{
alarm(f); // Called when new device inserted
devices.add(f);
}
}
}
This method is called every 1000ms in a seperate Thread and I guess that will do. Admitted, this is a dirty method but it works. I tested this function often and I always had the result I wanted. When I continued building my programm, I found that the thread would stop detecting new devices when I hide my programm to the SystemTray. When I open it again, the detection thread still won't work. Could anyone tell me what causes this and how this is to be solved?
Upon saving the data inserted by the user, I stopped detection of new devices. This was foolish of me so I thank you for making me aware of this.
public boolean saveSettings()
{
File f = new File(fsv.getHomeDirectory() + File.separator + "settings.cms");
ObjectOutputStream objOut;
try
{
// Here was my problem.
detector.stopDetection();
if(gui.saveSettings())
{
// Settings-file wegschrijven
objOut = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
objOut.writeObject(settings);
objOut.flush();
objOut.close();
return true;
}
else
{
return false;
}
}
catch (IOException e)
{
handleExceptions(e);
return false;
}
}

String Array iteration and startsWith()

I have a class thats responsible for animating some images. I have 3 player classes that each create their own instance of this animation class. Each player class sends a String path and a String array of file names to my animation class. So what im doing is checking if the String array of file names starts with up, down, left or right. I then add them to an array of buffered images, 4 in total named up, down, left and right.
Now when the player wants to move left for example, the left[] will animate, same goes for the up direction etc. The problem is that only one image gets stored in each array. For example the up[] of buffered images holds only one image for up, while their should be 3 (there are 3 images for each direction). I cant figure it out.
The following code is taken from my Animation class that processes the arrays. Can someone tell me if I am missing something?
If this made absolutely no sense, my apologies :)...it sounded good in my head
thanks
try
{
for (String file : fileName)
{
String path = PATH + file + EXT;
for (int i = 0; i < arrayLength; i++)
{
if (file.startsWith("u"))
{
up[i] = ImageIO.read(new File(path));
}
if(file.startsWith("d"))
{
down[i] = ImageIO.read(new File(path));
}
if (file.startsWith("l"))
{
left[i] = ImageIO.read(new File(path));
}
if (file.startsWith("r"))
{
right[i] = ImageIO.read(new File(path));
}
}
}
}
catch (IOException e)
{
System.out.println("Could not load images: " + e);
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println("Array out of bounds: " + e);
}
I'm having some trouble following your description, but looking at your code here are my thoughts on what could potentially be your problem. First unrelated to your problem a coding suggestion, you have mutually exclusive cases (file.startsWith(...)) that you test with ifs, you should have else so that when one tests positive the others can be ignored:
for (String file : fileName) {
String path = PATH + file + EXT;
for (int i = 0; i < arrayLength; i++) {
if (file.startsWith("u")) {
up[i] = ImageIO.read(new File(path));
} else if(file.startsWith("d")) {
down[i] = ImageIO.read(new File(path));
} else if (file.startsWith("l")) {
left[i] = ImageIO.read(new File(path));
} else if (file.startsWith("r")) {
right[i] = ImageIO.read(new File(path));
}
}
}
As for the logic of the code, one potential problem I see is your array index does not seem to be properly linked to the file. As of now your code could be rewritten thusly without changing its effects:
for (String file : fileName) {
String path = PATH + file + EXT;
BufferedImage array = null;
if (file.startsWith("u")) {
array = up;
} else if(file.startsWith("d")) {
array = down;
} else if (file.startsWith("l")) {
array = left;
} else if (file.startsWith("r")) {
array = right;
}
for (int i = 0; i < arrayLength; i++) {
array[i] = ImageIO.read(new File(path));
}
}
You are simply writing a new buffered image with the same path to the entire array (or whatever portion is included by the variable "arrayLength") on each iteration of the outer loop. Because of this if "file" is the same type every time (i.e. startsWith is the same value), your array will only ever contain the last item in the fileName array.
Here is where I will start guessing at your intent. I assume that each String in fileName, is one path that should be then next image in the array of the animation for that particular direction, so what you need is a separate index into each array:
int upArrayIndex = 0, downArrayIndex = 0,
leftArrayIndex = 0, rightArrayIndex = 0;
for (String file : fileName) {
String path = PATH + file + EXT;
if (file.startsWith("u")) {
up[upArrayIndex++] = ImageIO.read(new File(path));
} else if(file.startsWith("d")) {
down[downArrayIndex++] = ImageIO.read(new File(path));
} else if (file.startsWith("l")) {
left[leftArrayIndex++] = ImageIO.read(new File(path));
} else if (file.startsWith("r")) {
right[rightArrayIndex++] = ImageIO.read(new File(path));
}
}
I hope this is on the right track for the question you are asking, or at least gets you an idea where to start.
Here's a non-answer answer. Set a breakpoint in this method with a debugger. Are you running this code in an IDE like Eclipse? Root causing this problem will be much easier when you actually see the execution flow of your program - and its an essential tool for any developer who wants to truly understand some given code. As a side note, I think your problem has to do with arrayLength.

How can I play a WAV file using Java?

I send WAV files using a client and server, but I want to play the WAV when it received. I try this method but it did not work:
Runtime.getRuntime().exec("C:\\Documents and Settings\\Administratore\\Desktop\\gradpro\\test1\\s1.wav") ;
This the exception that I get:
"Error! It didn't work! java.io.IOException: Cannot run program "C:\Documents": CreateProcess error=193, %1 is not a valid Win32 application"
What am I doing wrong?
You need to execute the audio player program (probably windows media player or something similar) and then pass the filename (the full path to the file) in as a parameter:
String wavPlayer = "/path/to/winmediaplayer.exe";
String fileToPlay = "/path/to/wav/file.wav";
Runtime.getRuntime().exec(wavPlayer, new String[]{fileToPlay}) ;
That should work.
What's wrong with Javas built in WAV playback support? You can play it back using AudioClip:
private void playBackClip(String fileName) {
try {
AudioInputStream soundStream = null;
if (fileName.startsWith("res:")) {
soundStream = AudioSystem.getAudioInputStream(
Object.class.getResourceAsStream(fileName.substring(4)));
} else {
File audioFile = resMap.get(fileName);
soundStream = AudioSystem.getAudioInputStream(audioFile);
}
AudioFormat streamFormat = soundStream.getFormat();
DataLine.Info clipInfo = new DataLine.Info(Clip.class,
streamFormat);
Clip clip = (Clip) AudioSystem.getLine(clipInfo);
soundClip = clip;
clip.open(soundStream);
clip.setLoopPoints(0, -1);
clip.start();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
Is the use of the default audio player mandatory?
If not you might want to look into Java's AudioSystem.
Instead of specifying the media player to use, let windows look it up for you:
String comspec = System.getenv().get("ComSpec");
String fileToPlay = "/path/to/wav/file.wav";
Runtime.getRuntime().exec(comspec, new String[]{"/c", "start", fileToPlay}) ;
You are basically doing something like:
cmd.exe /c start path_to_wav_file.wav
To see all the options start gives you (start is a built-in operation of cmd.exe, not a stand-alone program, which is why you have to run cmd.exe instead of a 'start.exe'), do
start /h
Old question, but for the record:
java.awt.Desktop.getDesktop().open(new java.io.File(my_filename));
Try:
Runtime.getRuntime().exec("'C:\Documents and Settings\Administratore\Desktop\gradpro\test1\s1.wav'") ;
Note the extra single quotations. I'm not even sure if your method will work, but give that a go.

Categories