Java windowbuilder multiple audiofiles in one window - java

I have a question about my code, first of all little pre information about what it is going...
A Graphic Design friend of mine, has an exhibition/project from her University to influence the ppl with acoustic drugs (the topic of the exhibition is drugs..)
She wanted to have an interface, where a user can push a button and listen to an acoustic drug. further the user should have the opportunity, to mix up the sounds like kokain and heroin and stop either all by repushing the buttons each or just one button for stopping one title.
My code has follow problems. at the time i debug the code, my second listen button is not shown, u have to push the left bot of the window that the button is visible, and u can start one title and stop it, but if u play two sounds in same time, u can stop one, if u stop the second one its shown that its stopped but its actually not.
I would be happy if somebody could help me in my case.
Here the code:
package test;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFrame;
public class c extends JFrame {
String lsd="/Users/shaggy/Desktop/Lsd.wav";
JButton btnPlaySoundLSD=new JButton("Listen");
Clip clip = null;
String koka ="/Users/shaggy/Desktop/Kokain.wav";
JButton btnPlaySoundKokain=new JButton("Listen");
public c(){
btnPlaySoundLSD.setBounds(0, 0, 250, 240);
btnPlaySoundLSD.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
JButton b=(JButton)arg0.getSource();
// play the sound clip
if(b.getText().equals("Listen")){
b.setText("Stop");
btnPlaySoundCLickLSD();
} else if(btnPlaySoundLSD.getText().equals("Stop")) {
b.setText("Listen");
clip.stop();
}
} catch (LineUnavailableException | IOException
| UnsupportedAudioFileException e) {
e.printStackTrace();
}
}
});
setSize(500, 500);
getContentPane().setLayout(null);
getContentPane().add(btnPlaySoundLSD);
setVisible(true);
btnPlaySoundKokain.setBounds(0, 238, 250, 240);
btnPlaySoundKokain.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg1) {
try {
JButton b=(JButton)arg1.getSource();
// play the sound clip
if(b.getText().equals("Listen")){
b.setText("Stop");
btnPlaySoundCLickKokain();
} else if(btnPlaySoundKokain.getText().equals("Stop")) {
b.setText("Listen");
clip.stop();
}
} catch (LineUnavailableException | IOException
| UnsupportedAudioFileException e) {
e.printStackTrace();
}
}
});
setSize(500, 500);
getContentPane().setLayout(null);
getContentPane().add(btnPlaySoundKokain);
setVisible(true);
}
private void btnPlaySoundCLickKokain() throws LineUnavailableException, IOException, UnsupportedAudioFileException{
File soundFile = new File(koka);
AudioInputStream sound = AudioSystem.getAudioInputStream(soundFile);
DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
clip = (Clip) AudioSystem.getLine(info);
clip.open(sound);
clip.addLineListener(new LineListener() {
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
System.out.println("stop");
event.getLine().close();
}
}
});
clip.start();
}
private void btnPlaySoundCLickLSD() throws LineUnavailableException, IOException, UnsupportedAudioFileException{
File soundFile = new File(lsd);
AudioInputStream sound = AudioSystem.getAudioInputStream(soundFile);
DataLine.Info info = new DataLine.Info(Clip.class, sound.getFormat());
clip = (Clip) AudioSystem.getLine(info);
clip.open(sound);
clip.addLineListener(new LineListener() {
public void update(LineEvent event) {
if (event.getType() == LineEvent.Type.STOP) {
System.out.println("stop");
event.getLine().close();
}
}
});
clip.start();
}
public static void main(String[] args) {
c cc=new c();
}
}

Related

java audio playing wont stop

okay, I have this problem: my audio starts playing correctly, but it wont stop even after "clip.stop()" or "clip.close()" ... do you have any idea what to do to stop it? (i could accept even muting it, I am really desperate)
public class Main {
//audio playing
public static void audio(boolean a) {
try {
File file = new File("textures/Main_theme.wav");
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(file));
if(a == true){
// this loads correctly, but wont stop music
clip.stop();
System.out.println(a);
}
else{
clip.start();
}
} catch (Exception e) {
System.err.println("Put the music.wav file in the sound folder if you want to play background music, only optional!");
}
}
private static String arg;
public static void main(String[] args){
//picture loading ... ignorable now
arg = "textures/ccc.gif";
JFrame f = new JFrame();
JPanel p = new JPanel();
JLabel l = new JLabel();
ImageIcon icon = new ImageIcon(arg);
f.setSize(480, 360);
f.setVisible(true);
l.setIcon(icon);
p.add(l);
f.getContentPane().add(p);
f.setLocationRelativeTo(null);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//calling audio method to play sound (works)
audio(false);
//should stop music and run another class
KeyListener action = new KeyListener()
{
#Override
public void keyPressed(KeyEvent e) {
//trying to stop music
f.dispose();
try {
Menu.menu(args);
Main.audio(true);
} catch (IOException e1) {
//rest of code ... ignorable
e1.printStackTrace();
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
};
f.addKeyListener( action );
}
}
You need to step back for a second and think about what you're doing.
You're creating a Clip and you're playing it. At some point in the future, you create a new Clip and try and stop. What connection does these two Clips have in common? How are they connected? The answer is, they're not. It's quite reasonable to load the same file into to sepearate Clips and play them individually.
Instead, you need to stop the instance of the Clip you started earlier.
Because I'm lazy, I'd start by encapsulating the audio functionality into a simple class.
public class Audio {
private Clip clip;
protected Audio() {
}
public Audio(File source) throws LineUnavailableException, MalformedURLException, IOException, UnsupportedAudioFileException {
this(source.toURI().toURL());
}
public Audio(URL source) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
this(source.openStream());
}
public Audio(InputStream source) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
init(source);
}
protected void init(File source) throws LineUnavailableException, MalformedURLException, IOException, UnsupportedAudioFileException {
init(source.toURI().toURL());
}
protected void init(URL source) throws IOException, LineUnavailableException, UnsupportedAudioFileException {
init(source.openStream());
}
protected void init(InputStream source) throws LineUnavailableException, IOException, UnsupportedAudioFileException {
clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(source));
}
public void setRepeats(boolean repeats) {
clip.loop(repeats ? Clip.LOOP_CONTINUOUSLY : 1);
}
public void reset() {
clip.stop();
clip.setFramePosition(0);
}
public void play() {
clip.start();
}
public void stop() {
clip.stop();
}
public boolean isPlaying() {
return clip.isActive();
}
}
"Why?" you ask, because now I can create subclass which represent specific sounds and load them, without needing to care or remember what the source of the audio is, for example...
public class MainTheme extends Audio {
public MainTheme() throws LineUnavailableException, MalformedURLException, IOException, UnsupportedAudioFileException {
init(getClass().getResource("textures/Main_theme.wav"));
}
}
Now, I can easily create the "main theme" audio whenever I need to without having to care about what the source of it is
This also means I can pass the MainTheme to other parts of the program which expect an instance of Audio and off load the management simply
Then you just need to create an instance of the class and start/stop it as required, for example...
package test;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JButton btn = new JButton("Click");
btn.addActionListener(new ActionListener() {
private Audio audio;
#Override
public void actionPerformed(ActionEvent e) {
try {
if (audio == null) {
audio = new MainTheme();
}
if (audio.isPlaying()) {
audio.stop();
} else {
audio.play();
}
} catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) {
ex.printStackTrace();
}
}
});
add(btn);
}
}
}

Background Music for a Java game

So I've been asked to help with a Java game and I've been given the Audio role. I get the audio to play but I need to get it to where I can stop the audio and start up a new audio string within another file that's calling it. Here's what I have;
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
import javax.swing.*;
public class SoundTest{
// Constructor
public static void Run(String pen)throws InterruptedException {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Test Sound");
f.setSize(300, 200);
f.setVisible(false);
try {
// Open an audio input stream.
File soundFile = new File(pen);
AudioInputStream audioIn = AudioSystem.getAudioInputStream(soundFile);
Clip clip = AudioSystem.getClip();
clip.open(audioIn);
clip.start();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
}
and I have this that calls it
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
import javax.swing.*;
public class SoundCall{
public static void main(String[] args)throws InterruptedException {
JFrame f = new JFrame();
SoundTest sound = new SoundTest();
sound.Run("Jskee_-_I_Am_Pharaoh_.wav");
JOptionPane.showMessageDialog(f,"Window","Cracker",JOptionPane.PLAIN_MESSAGE);
sound.stop;
sound.Run("Rejekt_-_Crank.wav");
}
}
First of all, declare your Clip outside of the Run function, like this: Clip clip; then just do clip = AudioSystem.getClip(); and finally, make a stop function in your SoundTest class that looks like this:
public boolean stop(int id) {
if (clips.get(id-1) != null) {
clips.get(id-1).stop();
return true;
}
return false;
}
Returning a boolean is for checking, so that your application is sure if it has stopped the music or not. This is what your full SoundTest file will look like afterwards:
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
import javax.swing.*;
public class SoundTest{
private ArrayList<Clip> clips = new ArrayList<Clip>();
// Constructor
public void Run(String pen)throws InterruptedException {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Test Sound");
f.setSize(300, 200);
f.setVisible(false);
try {
// Open an audio input stream.
File soundFile = new File(pen);
AudioInputStream audioIn = AudioSystem.getAudioInputStream(soundFile);
Clip clip = AudioSystem.getClip();
clip.open(audioIn);
clip.start();
clips.add(clip);
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
public boolean stop(int id) {
if (clips.get(id-1) != null) {
clips.get(id-1).stop();
return true;
}
return false;
}
}
And in your SoundCall class, simply do
if(sound.stop(1)) { //1 is an id, I made it so that it starts at 1, not 0.
System.out.println("Audio stopped.");
} else {
System.out.println("Audio has not stopped.");
}
The id is when the clip was called, kinda. If it was the first clip to be executed, the id is 1, if it was the second the id is 2 etc.

How to loop a sound while button is pressed and stop when released?

I've tried to search similiar question to this, but couldn't find. I don't know how i can stop my sound when button is released, and also, i don't know how to loop sound only one by one, when i hold button it plays again while previous loop is still playing, and the sound is becoming a loop from ∞ sounds.
Here's the code:
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Component;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.net.MalformedURLException;
import java.util.ArrayList;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class test {
String b[]={"Q","W","E","R","T","Y","U","I","O","P","A","S","D","F","G","H","J","K","L","Z","X","C","V","B","N","M"};
Action[] actions = new AbstractAction[26];
public test() throws Exception {
JFrame frame = new JFrame();
JButton[] buttons = new JButton[26];
for(int i = 0; i < buttons.length; i++) {
buttons[i] = new JButton(b[i]);
buttons[i].setSize(80, 80);
buttons[i].addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
System.out.println(e.getKeyChar());
playSound(new File("loopbase/loop1/"+e.getKeyChar()+".wav"));
}
public void keyReleased(KeyEvent e){
}
});
frame.add(buttons[i]);
}
JPanel contentPane = (JPanel)frame.getContentPane();
frame.setLayout(new GridLayout(3, 5, 5, 3));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
try {
new test();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
public void playSound(File soundName)
{
try
{
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundName.getAbsoluteFile( ));
Clip clip = AudioSystem.getClip( );
clip.open(audioInputStream);
clip.start( );
}
catch(Exception ex)
{
System.out.println("Error with playing sound.");
ex.printStackTrace( );
}
}
}
Anyone can help me with this issue?
I don't know how i can stop my sound when button is released?
You can stop the the clip by using DataLine#stop(). Just keep the reference of last played clip and call below line to stop it.
clip.stop();
Note: You can store it somewhere in static variable.
Sample code:
private static Clip clip;
...
public void keyReleased(KeyEvent e) {
if (clip != null) {
clip.stop();
}
}
...
public void playSound(File soundName) {
...
clip = AudioSystem.getClip();
...
}
When I hold the Button it plays again while previous loop is still playing.
This is because for every keyPress you are creating a new File object. That should be avoided.
To stop sound:
I would add a boolean parameter to playsound method. And depending upon the parameter passed I would call clip.start() or clip.stop() (superclass DataLine has a stop method) .
Call playsound(filename,false); in keyReleased.
public void playSound(File soundName , boolean start)
{
try
{
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundName.getAbsoluteFile( ));
Clip clip = AudioSystem.getClip( );
clip.open(audioInputStream);
if(start == true)
clip.start();
else
clip.stop();
}
catch(Exception ex)
{
System.out.println("Error with playing sound.");
ex.printStackTrace( );
}
}

AudioInputStream is not working

I'm trying to play a .wav sound every time the user presses a button, but an exception gets thrown:
Exception in thread "Thread-0" java.lang.IllegalArgumentException: Invalid format
at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.createStream(PulseAudioDataLine.java:142)
at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.open(PulseAudioDataLine.java:99)
at org.classpath.icedtea.pulseaudio.PulseAudioDataLine.open(PulseAudioDataLine.java:283)
at org.classpath.icedtea.pulseaudio.PulseAudioClip.open(PulseAudioClip.java:402)
at org.classpath.icedtea.pulseaudio.PulseAudioClip.open(PulseAudioClip.java:453)
at Uber.play(Uber.java:534)
at Uber$5.run(Uber.java:340)
at java.lang.Thread.run(Thread.java:724)
Here's the code:
//Play Audio File
public void play(String file) throws LineUnavailableException, UnsupportedAudioFileException, IOException
{
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File(file));
Clip clip = AudioSystem.getClip();
clip.open(inputStream);
clip.start();
}
I managed to get it working.
This is the code that I used. Keep in mind that I needed this just to play a short beep.wav sound. It seems to have some trouble with longer sound files. Let me know if it works for you guys and if you manage to play longer sounds with this code.
public void play(String file) throws LineUnavailableException, UnsupportedAudioFileException, IOException
{
try
{
AudioInputStream inputStream = AudioSystem.getAudioInputStream(this.getClass().getResource(file));
AudioFormat format = inputStream.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
Clip clip = (Clip)AudioSystem.getLine(info);
clip.open(inputStream);
clip.start();
}
catch (IOException | LineUnavailableException | UnsupportedAudioFileException e1)
{
e1.printStackTrace();
}
}
It's something wrong with the file path you are passing. When I use your same code getting the file from a JFileChooser it works fine. Test this out.
Also see the Javasound wiki tag for working with unsupported audio file types
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.SwingUtilities;
public class TestAudio {
public TestAudio() {
JButton button = new JButton("Choose file");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser();
File file = null;
int returnVal = chooser.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = chooser.getSelectedFile();
}
String fileName = file.getAbsolutePath();
try {
play(fileName);
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
JFrame frame = new JFrame();
frame.add(button);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void play(String file) throws LineUnavailableException, UnsupportedAudioFileException, IOException {
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new File(file));
Clip clip = AudioSystem.getClip();
clip.open(inputStream);
clip.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TestAudio();
}
});
}
}

Images and Sound Won't Load at the Same Time (Java)

I'm making a game which is using sound and images. The weirdest thing is happening. When I load sound, my image won't appear. However, when I don't load my sound, my image does appear. Here is my code:
package com.gbp.chucknorris;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Title extends JPanel implements Runnable {
private static final long serialVersionUID = 1L;
public Thread thread;
private BufferedImage logo;
private Clip clip, titleClip;
public Title() {
super();
loadSound();
loadImages();
bind();
setBackground(Color.WHITE);
}
private void loadSound() {
File f = new File("res/sounds/title.wav");
AudioInputStream stream = null;
try {
stream = AudioSystem.getAudioInputStream(f);
} catch (UnsupportedAudioFileException | IOException e) {
e.printStackTrace();
}
DataLine.Info info = new DataLine.Info(Clip.class, stream.getFormat());
try {
clip = (Clip) AudioSystem.getLine(info);
} catch (LineUnavailableException e) {
e.printStackTrace();
}
try {
clip.open(stream);
} catch (LineUnavailableException | IOException e) {
e.printStackTrace();
}
File title = new File("res/sounds/theme.wav");
AudioInputStream titleStream = null;
try {
titleStream = AudioSystem.getAudioInputStream(title);
} catch (UnsupportedAudioFileException | IOException e) {
e.printStackTrace();
}
DataLine.Info titleInfo = new DataLine.Info(Clip.class, titleStream.getFormat());
try {
titleClip = (Clip) AudioSystem.getLine(titleInfo);
titleClip.open(titleStream);
} catch (LineUnavailableException | IOException e) {
e.printStackTrace();
}
titleClip.loop(Clip.LOOP_CONTINUOUSLY);
}
private void bind() {
InputMap im = getInputMap();
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke("DOWN"), "down");
am.put("down", new AbstractAction() {
private static final long serialVersionUID = 1L;
#Override
public void actionPerformed(ActionEvent e) {
}
});
}
private void loadImages() {
try {
logo = ImageIO.read(new File("res/pics/MenuPanel.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
while (true) {
repaint();
}
}
public void addNotify() {
super.addNotify();
thread = new Thread(this);
thread.start();
}
public void paint(Graphics g) {
super.paint(g);
g.drawImage(logo, 0, 0, null);
}
}
Thanks in advance!
You need to learn to use background threading such as a SwingWorker so as not to tie up the event thread, the EDT, when loading and playing sounds. You can read up on how to use this here: Lesson: Concurrency in Swing.
Edit: I wouldn't recommend doing this:
#Override
public void run() {
while (true) {
repaint();
}
}

Categories