Sound problems in Java - java

I have some questions about playing sound in Java and I hope you can help me out.
1. How can I stop a playing sound with a "Stop" button?
2. How can I slow down (or cooldown time) a sound?
3. I want to create a option frame where I can adjust volume and have mute option, how can I do that?
This is my code:
private void BGM() {
try {
File file = new File(AppPath + "\\src\\BGM.wav");
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(file));
clip.start();
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
Any help will be greatly appreciated, and, Have a nice day!

You're working in an Object Oriented programming lanuage, so let's take advantage of that and encapsulate the management of the clip/audio into a simple class...
public class AudioPlayer {
private Clip clip;
public AudioPlayer(URL url) throws IOException, LineUnavailableException, UnsupportedAudioFileException {
clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(url.openStream()));
}
public boolean isPlaying() {
return clip != null && clip.isRunning();
}
public void play() {
if (clip != null && !clip.isRunning()) {
clip.start();
}
}
public void stop() {
if (clip != null && clip.isRunning()) {
clip.stop();
}
}
public void dispose() {
try {
clip.close();
} finally {
clip = null;
}
}
}
Now, to use it, you need to create a class instance field which will allow you to access the value from anywhere within the class you want to use it...
private AudioPlayer bgmPlayer;
Then, when you need it, you create an instance of AudioPlayer and assign it to this variable
try {
bgmPlayer = new AudioPlayer(getClass().getResource("/BGM.wav"));
} catch (IOException | LineUnavailableException | UnsupportedAudioFileException ex) {
ex.printStackTrace();
}
Now, when you need to, you simply call bgmPlayer.play() or bgmPlayer.stop()

Related

Java threads:Comminucation between 3 java threads

So I have 3 threads,
A thread which downloads audio and the audio schedule object from the internet.
A thread which plays the audio according to the audio schedule.
And a web socket "notification" listener that listens for messages that say we have to download new audio and schedule as our current one is outdated.
The program flow is as follows:
On application startup: The ScheduleDownloader starts,downloads audio and schedule file.Once completed it needs to tell the audio player "hey the files are ready and here is the schedule" and it doesnt need to do anything for now
The audio player starts and continuously loops with no exit condition.
The web socket listener starts,when it gets a message.It should tell the schedule downloader "You need to start again as there is new files you need to download",it doesnt need to send any data to the schedule downloaded,just start it up again.The music should remain playing.Once it is done it should now restart the audio player thread with the new schedule.
Here is what I have so far,I am not sure how to get ScheduleDownloader to tell AudioPlayer "the files are ready and you need to start,here is the schedule" or "you need to restart with the new schedule,here it is" or how to get the listener to say "ScheduleDownloader you need to start again"
public class ScheduleDownloader extends Thread {
private Thread t;
private String threadName;
String username;
String password;
public ScheduleDownloader(String username,String password,String threadName){
this.username = username;
this.password = password;
this.threadName= threadName;
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}}
public void run() {
try {
Schedule schedule= null;
while(schedule == null){
System.out.println("Searching for schedule");
schedule= getTodaysSchedule();
}
System.out.println("Schedule Found");
boolean result = false;
while(result == false){
result = downloadFiles(schedule);
}
System.out.println("Files Downloaded");
} catch (IOException e) {
e.printStackTrace();
}
}
public Schedule getTodaysSchedule() throws IOException {
Schedule schedule = null;
CredentialsProvider provider = new BasicCredentialsProvider();
UsernamePasswordCredentials credentials
= new UsernamePasswordCredentials(username,password);
provider.setCredentials(AuthScope.ANY, credentials);
String url = "http://localhost:5000/api/schedule/today";
HttpClient httpClient = HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build(); //Use this instead
HttpGet request = new HttpGet(url);
HttpResponse response = httpClient.execute(request);
//read content response body
if (response.getStatusLine().getStatusCode() != 200) {
System.out.println("sorry error:" + response.getStatusLine().getStatusCode());
} else {
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
//change json response to java objects
Gson gson = new Gson();
schedule = gson.fromJson(String.valueOf(result),Schedule.class);
}
return schedule;
}
public static boolean downloadFiles(Schedule schedule) {
//get the music
for(int i =0;i<schedule.getMusicScheduleItems().size();i++){
downloadOneFile("shoutloudaudio","music/" +
schedule.getMusicScheduleItems().get(i).getMusic().getId()+
"-music.wav");
}
//get the advertisements
for(int i =0;i<schedule.getAdvertisementScheduleItems().size();i++){
downloadOneFile("shoutloudaudio","advertisements/" +
schedule.getAdvertisementScheduleItems().get(i).getAdvertisement().getId()+
"-advertisement.wav");
}
return true;
}
public static boolean downloadOneFile(String bucketName,String key) {
if( new File(key.split("/")[1]).isFile()){
//check if we have it already and dont need to download it
System.out.println(key + " alraeady exits");
return true;
}
AWSCredentials awsCredentials = new BasicAWSCredentials(
"removed",
"removed"
);
AmazonS3 s3client = AmazonS3ClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.withRegion(Regions.EU_WEST_1)
.build();
S3Object s3object = s3client.getObject(bucketName, key);
S3ObjectInputStream inputStream = s3object.getObjectContent();
InputStream reader = new BufferedInputStream(
inputStream);
File file = new File(key.split("/")[1]);//save the file as whats after the / in key
OutputStream writer = null;
try {
writer = new BufferedOutputStream(new FileOutputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}
int read = -1;
try {
while ((read = reader.read()) != -1) {
writer.write(read);
}
writer.flush();
writer.close();
}catch(IOException e){
e.printStackTrace();
return false;
}
return true;
}
}
AudioPlayer
public class AudioPlayer extends Thread {
Long currentFrameMusic;
Long currentFrameAdvertisement;
Clip clipMusic;
Clip clipAdvertisement;
private Thread t;
// current status of clip
String statusMusic;
String statusAdvertisement;
static AudioInputStream musicInputStream;
static AudioInputStream advertisementInputStream;
static String filePath;
Schedule schedule;
// constructor to initialize streams and clip
public AudioPlayer(Schedule schedule)
throws UnsupportedAudioFileException,
IOException, LineUnavailableException
{
//setup audio stream for music first
// create AudioInputStream object
this.schedule = schedule;
appendMusicFiles(schedule);
// create clip reference
clipMusic = AudioSystem.getClip();
// open audioInputStream to the clip
clipMusic.open(musicInputStream);
clipMusic.loop(Clip.LOOP_CONTINUOUSLY);
}
public void run(){
playMusic();
try {
checkShouldWePlayAnAdvertisement();
} catch (IOException e) {
e.printStackTrace();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void start(){
t = new Thread (this, "AudioPlayerThread");
t.start ();
}
public void start2() throws IOException, UnsupportedAudioFileException, LineUnavailableException, InterruptedException {
playMusic();
checkShouldWePlayAnAdvertisement();
}
public void playMusic()
{
//start the clip
clipMusic.start();
statusMusic = "play";
}
// Method to pause the audio
public void pauseMusic()
{
if (statusMusic.equals("paused"))
{
System.out.println("audio is already paused");
return;
}
this.currentFrameMusic =
this.clipMusic.getMicrosecondPosition();
clipMusic.stop();
statusMusic = "paused";
System.out.println("pausing music");
}
// Method to resume the audio
public void resumeAudioMusic() throws UnsupportedAudioFileException,
IOException, LineUnavailableException
{
if (statusMusic.equals("play"))
{
System.out.println("Audio is already "+
"being played");
return;
}
clipMusic.close();
resetAudioStreamMusic();
clipMusic.setMicrosecondPosition(currentFrameMusic);
System.out.println("resuming music");
this.playMusic();
}
// Method to restart the audio
public void restartMusic() throws IOException, LineUnavailableException,
UnsupportedAudioFileException
{
clipMusic.stop();
clipMusic.close();
resetAudioStreamMusic();
currentFrameMusic = 0L;
clipMusic.setMicrosecondPosition(0);
this.playMusic();
}
// Method to stop the audio
public void stopMusic() throws UnsupportedAudioFileException,
IOException, LineUnavailableException
{
currentFrameMusic = 0L;
clipMusic.stop();
clipMusic.close();
}
public void resetAudioStreamMusic() throws UnsupportedAudioFileException, IOException,
LineUnavailableException
{
clipMusic = AudioSystem.getClip();
appendMusicFiles(schedule);
// open audioInputStream to the clip
clipMusic.open(musicInputStream);
clipMusic.loop(Clip.LOOP_CONTINUOUSLY);
}
public static void appendMusicFiles(Schedule schedule) throws IOException, UnsupportedAudioFileException {
//add the first audio file to stream
AudioInputStream appendedFiles = AudioSystem.getAudioInputStream(
new File(schedule.getMusicScheduleItems().get(0).getMusic()
.getId() + "-music.wav"));
//loop through an combine
for(int i =1;i<schedule.getMusicScheduleItems().size();i++){
File file= new File(schedule.getMusicScheduleItems().get(i).getMusic()
.getId() + "-music.wav");
AudioInputStream toBeAppended = AudioSystem.getAudioInputStream(file);
//append them
appendedFiles =
new AudioInputStream(
new SequenceInputStream(appendedFiles, toBeAppended),
appendedFiles.getFormat(),
appendedFiles.getFrameLength() + toBeAppended.getFrameLength());
}
musicInputStream = appendedFiles;
}
//advertisement methods
public void playAdvertisements() throws LineUnavailableException, IOException, InterruptedException {
clipAdvertisement = AudioSystem.getClip();
// open audioInputStream to the clip
clipAdvertisement.open(advertisementInputStream);
System.out.println(clipAdvertisement.getMicrosecondLength());
//start the clip
clipAdvertisement.start();
Thread.sleep(clipAdvertisement.getMicrosecondLength() / 1000);
statusAdvertisement = "play";
System.out.println("playing advertisements");
}
// Method to pause the audio
public void pauseAdvertisements()
{
if (statusAdvertisement.equals("paused"))
{
System.out.println("audio is already paused");
return;
}
this.currentFrameAdvertisement =
this.clipAdvertisement.getMicrosecondPosition();
clipAdvertisement.stop();
statusAdvertisement = "paused";
}
// Method to resume the audio
public void resumeAudioAdvertisement() throws UnsupportedAudioFileException,
IOException, LineUnavailableException, InterruptedException {
if (statusAdvertisement.equals("play"))
{
System.out.println("Audio is already "+
"being played");
return;
}
clipAdvertisement.close();
resetAudioStreamAdvertisement();
clipAdvertisement.setMicrosecondPosition(currentFrameMusic);
this.playAdvertisements();
}
// Method to restart the audio
public void restartAdvertisement() throws IOException, LineUnavailableException,
UnsupportedAudioFileException, InterruptedException {
clipAdvertisement.stop();
clipAdvertisement.close();
resetAudioStreamAdvertisement();
currentFrameAdvertisement = 0L;
clipAdvertisement.setMicrosecondPosition(0);
this.playAdvertisements();
}
// Method to stop the audio
public void stopAdvertisement() throws UnsupportedAudioFileException,
IOException, LineUnavailableException, InterruptedException {
currentFrameAdvertisement = 0L;
clipAdvertisement.stop();
clipAdvertisement.close();
System.out.println("stopping advertisement");
}
public void resetAudioStreamAdvertisement() throws UnsupportedAudioFileException, IOException,
LineUnavailableException
{
advertisementInputStream = AudioSystem.getAudioInputStream(
new File(filePath).getAbsoluteFile());
clipAdvertisement.open(musicInputStream);
clipAdvertisement.loop(Clip.LOOP_CONTINUOUSLY);
}
public static void appendAdvertisementFiles(List<Advertisement> advertisementItems) throws IOException, UnsupportedAudioFileException {
//add the first audio file to stream
AudioInputStream appendedFiles = AudioSystem.getAudioInputStream(
new File(advertisementItems.get(0)
.getId() + "-advertisement.wav"));
//loop through an combine
for(int i =1;i<advertisementItems.size();i++){
File file= new File(advertisementItems.get(i)
.getId() + "-advertisement.wav");
AudioInputStream toBeAppended = AudioSystem.getAudioInputStream(file);
//append them
appendedFiles =
new AudioInputStream(
new SequenceInputStream(appendedFiles, toBeAppended),
appendedFiles.getFormat(),
appendedFiles.getFrameLength() + toBeAppended.getFrameLength());
}
advertisementInputStream = appendedFiles;
}
public void checkShouldWePlayAnAdvertisement() throws IOException, UnsupportedAudioFileException, LineUnavailableException, InterruptedException {
ArrayList<String> playedAtTimes = new ArrayList<>();
ArrayList<Advertisement> advertisementsToBePlayed = new ArrayList<>();
boolean found;
//played at times is used to keep track of what time we played advertisements
//so when the loop reruns and the time hasnt changed it doesnt play it again
while(true){
found = false;
ZonedDateTime zdt = ZonedDateTime.now();
String timeHHMM =zdt.toString().substring(11,16);
for(int i =0;i<schedule.getAdvertisementScheduleItems().size();i++)
{
if(schedule.getAdvertisementScheduleItems().get(i).getTimes()
.contains(timeHHMM))
{
//this item should be played now
if(playedAtTimes.contains(timeHHMM)){
//we already played this,but the time hasnt changed when the loop ran again
}else{
advertisementsToBePlayed.add(schedule.getAdvertisementScheduleItems().get(i).getAdvertisement());
found = true;
}
}
}
if(found== true){
playedAtTimes.add(timeHHMM);
appendAdvertisementFiles(advertisementsToBePlayed);
pauseMusic();
playAdvertisements();
stopAdvertisement();
resumeAudioMusic();
}
}
}
}
IotClient(part of listener)
public class IotClient extends Thread {
Thread t;
String username;
public IotClient(String username) {
this.username = username;
}
public void run(){
String clientEndpoint = "removve"; // replace <prefix> and <region> with your own
String clientId = "1"; // replace with your own client ID. Use unique client IDs for concurrent connections.
// AWS IAM credentials could be retrieved from AWS Cognito, STS, or other secure sources
AWSIotMqttClient client = new AWSIotMqttClient(clientEndpoint, clientId, "remove", "remove");
// optional parameters can be set before connect()
try {
client.connect();
} catch (AWSIotException e) {
e.printStackTrace();
}
AWSIotQos qos = AWSIotQos.QOS0;
AWSIotTopic topic = new MyTopic("schedule/"+ username, qos);
try {
client.subscribe(topic, true);
} catch (AWSIotException e) {
e.printStackTrace();
}
while(true){
}
}
public void start(){
if (t == null) {
t = new Thread (this, "IotClientThread");
t.start ();
}
}
MyTopic(part of listener)
public class MyTopic extends AWSIotTopic {
public MyTopic(String topic, AWSIotQos qos) {
super(topic, qos);
}
#Override
public void onMessage(AWSIotMessage message) {
System.out.println("Message recieved from topic: "+ message.getStringPayload());
}
}
Threads communicate via shared references to messages 'containers' objects in memory. That could be as simple as mere mutable field of a shared instance of some class, or more typical collection like list, map, but especially queues.
ArrayBlockingQueue is a good shared reference. There would be a queue for each message direction from one thread to another. If you had 3 threads that could truly talks to each other, you would have 3 pairs, thus 6 queues (2 for each pair). However, it is often the case that messages flow only in one direction, so you might save a few.
Now, the core of these communications is a mechanism to wait for some message (reader/consumer), and notify when a message is pushed (writer/producer).
Of course, you can learn (penty of tutorials out there) from the bottom going up, from the primitive wait/notify, or you can jump into classes like ArrayBlockingQueue which abstract the wait/notify of messages into take()/put(). I recommend starting from the bottom as things will make sense more rapidly when you meet other classes in java.util.concurrent.*
I cannot give you code, it would be largely not understandable at your level without having learned the basic of ITC (inter-thread communications).
Good learning!
PS: there are many pitfalls on the way, like thread safety, atomicity of writes, lock free algorithms, deadlocks, livelocks, starvation. Just the multi queue example above can lead to circular dependencies on message arrival, particularly when queue get full and block. This is a science!

Resource is not grabbed when exporting to .JAR

I'm trying to get a better understanding of Java by creating a small 2D game. I feel like the best way to learning is by struggling, so I try not to get help on any problems I have; I just solve them myself. However, I've tried almost everything any I can't get my background music to play in my exported version of my game. All the images work and everything else pulled using the " getClass()" method works, but the music doesn't.
Sorry I have to put all of the code from my BackgroundMusicManager class, but because I want to do things without help, my first version of my programs are usually very messy and require a lot of optimization. In short, you kinda have to see where things are called and initialized and whatnot to really see how the things work.
package com.cs.dd.audioManager;
import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import javax.sound.sampled.*;
import com.nickgirga.dd.main.*;
import sun.applet.Main;
public class BackgroundMusicManager implements Runnable {
//URLs
public URL mmBgMusicURL = getClass().getResource("/audio/backgroundMusic/casual.wav");
//Files
public File[] bgMusics = { new File(mmBgMusicURL.getFile()) };
public File bgMusic = bgMusics[0];
private static Clip clip;
public static int newGameState;
public static boolean enabled = true;
public static boolean asPlaying = false;
public static Thread bgMusicPlayer = new Thread(new BackgroundMusicManager());
public void play () {
if (enabled) {
try {
if (bgMusic != null) clip = AudioSystem.getClip();
if (bgMusic != null) clip.open(AudioSystem.getAudioInputStream(bgMusic));
if (bgMusic != null) clip.start();
//System.out.println(bgMusics[0].getAbsolutePath());
loopChecker();
bgMusicPlayer.wait();
} catch (LineUnavailableException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (Exception e) {
//e.printStackTrace();
}
}
}
public void loopChecker () {
while (true) {
if (clip.getMicrosecondPosition() >= clip.getMicrosecondLength()) {
bgMusicPlayer.notify();
}
if (!(GameState.state == newGameState)) {
setClip();
}
}
}
public void setClip () {
//System.out.println("setClip");
newGameState = GameState.state;
if (GameState.state == 0) {
clip.stop();
bgMusic = bgMusics[0];
bgMusicPlayer.notify();
} else {
if (GameState.state == 1) {
clip.stop();
bgMusic = bgMusics[0];
bgMusicPlayer.notify();
} else {
clip.stop();
bgMusic = null;
bgMusicPlayer.notify();
}
}
}
#Override
public void run() {
while (true) {
play();
}
}
}
After exporting this as a JAR with the libraries packed into it, the console reads:
java.io.FileNotFoundException: audio\backgroundMusic\casual.wav (The system cannot find the path specified)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at com.sun.media.sound.WaveFloatFileReader.getAudioInputStream(Unknown Source)
at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
at com.cs.dd.audioManager.BackgroundMusicManager.play(BackgroundMusicManager.java:33)
at com.cs.dd.audioManager.BackgroundMusicManager.run(BackgroundMusicManager.java:89)
at java.lang.Thread.run(Unknown Source)
I extracted the JAR and found the file exactly where the FileNotFoundException points, so I'm left very confused. The audio works while running in Eclipse. The images still show in the export. Why will it work with the images, but not the audio?
Any help is very appreciated! Thank you!!!
Instead of
getClass().getResource("/audio/backgroundMusic/casual.wav");
use
getClass().getClassLoader().getResourceAsStream("/audio/backgroundMusic/casual.wav")
In this way it will look from the root, not from the path of the current invoking class

AudioClip is not working, and it should

I have been trying to play a sound in java and I am stuck.
public class Audioapp extends JApplet
{
public class Sound{
public AudioClip song;
public URL songPath;
Sound(){
try{
songPath = new URL(getCodeBase(), "leftfordeath.wav");
song = Applet.newAudioClip(songPath);
}
catch (Exception e) {}
}
public void playSoundOnce(){
song.play();
}
}
public void init(){
Sound test = new Sound();
test.playSoundOnce();
}
}
When I call init from my main, it says there is a nullPointerExeption on song.play();
what am I doing wrong, please help...
try substituting this code where you have the playsoundOnce code and see how you get on.
public void playSoundOnce()
{
try
{
InputStream inputStream = getClass().getResourceAsStream(leftfordeath.wav);
AudioStream audioStream = new AudioStream(inputStream);
AudioPlayer.player.start(audioStream);
}
catch (Exception e)
{
if (debugFileWriter!=null) e.printStackTrace(debugFileWriter);
}
}

Buzzing on Exit

I'm trying to build a game that uses sound effects. I haven't dealt with the Java API before so I may be making some mistakes. That said though, the effects work great — my only problem is that I get a strange buzzing sound for maybe a second whenever my program exits.
Any idea how I might get rid of it? Right now I'm trying to kill any playing sounds just before the exit takes place with the killLoop() method, but that isn't getting me anywhere.
I'd appreciate your help!
public class Sound
{
private AudioInputStream audio;
private Clip clip;
public Sound(String location)
{
try {
audio = AudioSystem.getAudioInputStream(new File(location));
clip = AudioSystem.getClip();
clip.open(audio);
}
catch(UnsupportedAudioFileException uae) {
System.out.println(uae);
}
catch(IOException ioe) {
System.out.println(ioe);
}
catch(LineUnavailableException lua) {
System.out.println(lua);
}
}
public void play()
{
clip.setFramePosition(0);
clip.start();
}
public void loop()
{
clip.loop(clip.LOOP_CONTINUOUSLY);
}
public void killLoop()
{
clip.stop();
clip.close();
}
}
public class Athenaeum
{
public static void main(String[] args) throws IOException
{
final Game game = new Game();
GUI athenaeumGui = new GUI(game);
athenaeumGui.setSize(GUI.FRAME_WIDTH, GUI.FRAME_HEIGHT);
athenaeumGui.setTitle("Athenaeum");
athenaeumGui.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
athenaeumGui.setLocationRelativeTo(null);
athenaeumGui.setMinimumSize(new Dimension(GUI.FRAME_WIDTH, GUI.FRAME_HEIGHT));
athenaeumGui.buildGui();
athenaeumGui.setVisible(true);
athenaeumGui.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we)
{
game.killAudio(); // method calls Sound.killLoop()
System.exit(0);
}
});
}
}
In Java api, they say that the AudioInputStream class has a ".close()" method that "Closes this audio input stream and releases any system resources associated with the stream". Maybe this is something you can try.

Clip not playing any sound

Well, the title says all, I tried playing a wav file using javax.sound and nothing is happening. I have tried many different files without any luck.
public static void main(String[] args) throws IOException, UnsupportedAudioFileException, LineUnavailableException
{
File in = new File("C:\\Users\\Sandra\\Desktop\\music\\rags.wav");
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(in);
Clip play = AudioSystem.getClip();
play.open(audioInputStream);
FloatControl volume= (FloatControl) play.getControl(FloatControl.Type.MASTER_GAIN);
volume.setValue(1.0f); // Reduce volume by 10 decibels.
play.start();
}
As, has already begin stated, you need to prevent the main thread from exiting, as this will cause the JVM to terminate.
Clip#start is not a blocking call, meaning that it will return (soon) after it is called.
I have no doubt that there are many ways to approach this problem and this is just a simple example of one of them.
public class PlayMusic {
public static void main(String[] args) throws InterruptedException {
Clip play = null;
try {
File in = new File("C:\\Users\\Public\\Music\\Sample Music\\Kalimba.wav");
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(in);
play = AudioSystem.getClip();
play.open(audioInputStream);
FloatControl volume = (FloatControl) play.getControl(FloatControl.Type.MASTER_GAIN);
volume.setValue(1.0f); // Reduce volume by 10 decibels.
play.start();
// Loop until the Clip is not longer running.
// We loop this way to allow the line to fill, otherwise isRunning will
// return false
//do {
// Thread.sleep(15);
//} while (play.isRunning());
play.drain();
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException ex) {
ex.printStackTrace();
} finally {
try {
play.close();
} catch (Exception exp) {
}
}
System.out.println("...");
}
}
The actual solution will depend on your needs.
Java's sound Clip requires an active Thread to play the audio input file otherwise the application exits before the file can be played. You could add
JOptionPane.showMessageDialog(null, "Click OK to stop music");
after calling start.
The proper way to play the audio clip is to drain the line as explained in Playing Back Audio.
So your main should look like this:
public static void main(String[] args) throws IOException,
UnsupportedAudioFileException, LineUnavailableException
{
File in = new File("C:\\Users\\Sandra\\Desktop\\music\\rags.wav");
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(in);
Clip play = AudioSystem.getClip();
play.open(audioInputStream);
FloatControl volume= (FloatControl) play.getControl(FloatControl.Type.MASTER_GAIN);
volume.setValue(1.0f); // Reduce volume by 10 decibels.
play.start();
play.drain();
play.close();
}
play.drain() blocks until all the data is played.
Here playing a clip
public static void main(String[] args) throws Exception {
File in = new File("C:\\Users\\Sandra\\Desktop\\music\\rags.wav");
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(in);
Clip play = AudioSystem.getClip();
play.open(audioInputStream);
FloatControl volume= (FloatControl)play.getControl(FloatControl.Type.MASTER_GAIN);
volume.setValue(1.0f); // Reduce volume by 10 decibels.
play.start();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// A GUI element to prevent the Clip's daemon Thread
// from terminating at the end of the main()
JOptionPane.showMessageDialog(null, "Close to exit!");
}
});
}
Your program is terminating before the sound has the time to be played. I would do play.start(); in some threading way (invokeLater, ...), and also find a way to wait until the sound has finished (Reimeus suggested one).
A lead :
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
...
play.start();
JOptionPane.showMessageDialog(null, "Click OK to stop music");
}
});
}
If you just want to play an audio, here's a way.
The audioFileDirectory String variable needs the correct path to your audio file, otherwise an exception will be thrown and the program won't run.
Example of having the right audio file directory in a project if using an IDE:
Make a folder inside src folder, e.g: "music" and put an audio file there
audioFileDirectory = "/music/name_of_audio_file";
The important part for an audio to play is that the main thread of the program needs somehow to be "alive", so the line
Thread.sleep(audio.getMicrosecondLength()/1000);
is where the main thread is "alive", and the argument audio.getMicrosecondLength()/1000 is the time that will be "alive", which is the whole length of the audio file.
public class AudioTest
{
void playAudio() throws Exception
{
String audioFileDirectory = "your_audioFileDirectory";
InputStream is = getClass().getResourceAsStream(audioFileDirectory);
BufferedInputStream bis = new BufferedInputStream(is);
AudioInputStream ais = AudioSystem.getAudioInputStream(bis);
Clip audio = AudioSystem.getClip();
audio.open(ais);
audio.loop(Clip.LOOP_CONTINUOUSLY);
audio.start();
Thread.sleep(audio.getMicrosecondLength()/1000);
audio.close();
} // end playAudio
public static void main(String[] args)
{
try
{
new AudioTest().playAudio();
}
catch (Exception e)
{
System.out.println("Class: " + e.getClass().getName());
System.out.println("\nMessage:\n" + e.getMessage() + "\n");
e.printStackTrace();
}
} // end main
} // end class AudioTest

Categories