Hi I have following java programme that play some sounds.I want to play sounds in order for example after ending of sound1 i want to play sound2 and then sound3 the following is my java code and function of playing sound .
private void playsound(String file)
{
try {
crit = AudioSystem.getClip();
AudioInputStream inputStream1 = AudioSystem.getAudioInputStream(this.getClass().getResource(file));
crit.open(inputStream1);
//if(!crit.isOpen())
{
crit.start();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
and calling it as following
playsound("/sounds/filesound1.au");
playsound("/sounds/filesound2.au");
playsound("/sounds/filesound3.au");
the programme is plying sound in parallel which I don't want.I want to play in order
Regards
I got the following code from somewhere that I can't remember right now but it plays the music consequently:
public static void play(ArrayList<String> files){
byte[] buffer = new byte[4096];
for (String filePath : files) {
File file = new File(filePath);
try {
AudioInputStream is = AudioSystem.getAudioInputStream(file);
AudioFormat format = is.getFormat();
SourceDataLine line = AudioSystem.getSourceDataLine(format);
line.open(format);
line.start();
while (is.available() > 0) {
int len = is.read(buffer);
line.write(buffer, 0, len);
}
line.drain();
line.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
The reason this plays the files consequently and not all at the same time is because write blocks until the requested amount of data has been written. This applies even if the requested amount of data to write is greater than the data line's buffer size.
Make sure to include drain() from the code above. drain() waits for the buffer to empty before it close()s.
Related
Using Java is it possible to capture the speaker output? This output is not being generated by my program but rather by other running applications. Can this be done with Java or will I need to resort to C/C++?
I had a Java based app. that used Java Sound to tap into the sound flowing through the system to make a trace of it. It worked well on my own (Windows based) machine, but failed completely on some others.
It was determined that in order to get it working on those machines, would take nothing short of an audio loop-back in either software or hardware (e.g. connect a lead from the speaker 'out' jack to the microphone 'in' jack).
Since all I really wanted to do was plot the trace for music, and I figured how to play the target format (MP3) in Java, it became unnecessary to pursue the other option further.
(And I also heard that Java Sound on Mac. was horribly broken, but I never looked closely into it.)
Java is not the best tool when dealing with the OS. If you need/want to use it for this task, probably you will end using Java Native Interface (JNI), linking to libraries compiled in other languages (probably c/c++).
Take an AUX cable, connect to HEADPHONE JACK and other end to MICROPHONE JACK and run this code
https://www.codejava.net/coding/capture-and-record-sound-into-wav-file-with-java-sound-api
import javax.sound.sampled.*;
import java.io.*;
public class JavaSoundRecorder {
// record duration, in milliseconds
static final long RECORD_TIME = 60000; // 1 minute
// path of the wav file
File wavFile = new File("E:/Test/RecordAudio.wav");
// format of audio file
AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE;
// the line from which audio data is captured
TargetDataLine line;
/**
* Defines an audio format
*/
AudioFormat getAudioFormat() {
float sampleRate = 16000;
int sampleSizeInBits = 8;
int channels = 2;
boolean signed = true;
boolean bigEndian = true;
AudioFormat format = new AudioFormat(sampleRate, sampleSizeInBits,
channels, signed, bigEndian);
return format;
}
/**
* Captures the sound and record into a WAV file
*/
void start() {
try {
AudioFormat format = getAudioFormat();
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
// checks if system supports the data line
if (!AudioSystem.isLineSupported(info)) {
System.out.println("Line not supported");
System.exit(0);
}
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.start(); // start capturing
System.out.println("Start capturing...");
AudioInputStream ais = new AudioInputStream(line);
System.out.println("Start recording...");
// start recording
AudioSystem.write(ais, fileType, wavFile);
} catch (LineUnavailableException ex) {
ex.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
/**
* Closes the target data line to finish capturing and recording
*/
void finish() {
line.stop();
line.close();
System.out.println("Finished");
}
/**
* Entry to run the program
*/
public static void main(String[] args) {
final JavaSoundRecorder recorder = new JavaSoundRecorder();
// creates a new thread that waits for a specified
// of time before stopping
Thread stopper = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(RECORD_TIME);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
recorder.finish();
}
});
stopper.start();
// start recording
recorder.start();
}
}
I am trying to get two .wav files, convert them to the same audio format and then concatenate. I need only concatenated files and delete the others. The problem is that I can not delete them because AudioInputStreams are not closed. After debugging I discovered that streams are not closed after execution of this method:
private static void convertFilesToSameAudioFormat(String fileName1, String fileName2) {
try (AudioInputStream clip = AudioSystem.getAudioInputStream(new File(fileName2));
AudioInputStream clip1 = AudioSystem.getAudioInputStream(new File(fileName1));
AudioInputStream clip2 = AudioSystem.getAudioInputStream(clip1.getFormat(), clip);) {
AudioSystem.write(clip2,
AudioFileFormat.Type.WAVE,
new File("temp.wav"));
} catch (Exception e) {
e.printStackTrace();
}
}
So after the execution of this method clip, clip1, clip2 can not be deleted, because they are used by the program.
Using Java is it possible to capture the speaker output? This output is not being generated by my program but rather by other running applications. Can this be done with Java or will I need to resort to C/C++?
I had a Java based app. that used Java Sound to tap into the sound flowing through the system to make a trace of it. It worked well on my own (Windows based) machine, but failed completely on some others.
It was determined that in order to get it working on those machines, would take nothing short of an audio loop-back in either software or hardware (e.g. connect a lead from the speaker 'out' jack to the microphone 'in' jack).
Since all I really wanted to do was plot the trace for music, and I figured how to play the target format (MP3) in Java, it became unnecessary to pursue the other option further.
(And I also heard that Java Sound on Mac. was horribly broken, but I never looked closely into it.)
Java is not the best tool when dealing with the OS. If you need/want to use it for this task, probably you will end using Java Native Interface (JNI), linking to libraries compiled in other languages (probably c/c++).
Take an AUX cable, connect to HEADPHONE JACK and other end to MICROPHONE JACK and run this code
https://www.codejava.net/coding/capture-and-record-sound-into-wav-file-with-java-sound-api
import javax.sound.sampled.*;
import java.io.*;
public class JavaSoundRecorder {
// record duration, in milliseconds
static final long RECORD_TIME = 60000; // 1 minute
// path of the wav file
File wavFile = new File("E:/Test/RecordAudio.wav");
// format of audio file
AudioFileFormat.Type fileType = AudioFileFormat.Type.WAVE;
// the line from which audio data is captured
TargetDataLine line;
/**
* Defines an audio format
*/
AudioFormat getAudioFormat() {
float sampleRate = 16000;
int sampleSizeInBits = 8;
int channels = 2;
boolean signed = true;
boolean bigEndian = true;
AudioFormat format = new AudioFormat(sampleRate, sampleSizeInBits,
channels, signed, bigEndian);
return format;
}
/**
* Captures the sound and record into a WAV file
*/
void start() {
try {
AudioFormat format = getAudioFormat();
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
// checks if system supports the data line
if (!AudioSystem.isLineSupported(info)) {
System.out.println("Line not supported");
System.exit(0);
}
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.start(); // start capturing
System.out.println("Start capturing...");
AudioInputStream ais = new AudioInputStream(line);
System.out.println("Start recording...");
// start recording
AudioSystem.write(ais, fileType, wavFile);
} catch (LineUnavailableException ex) {
ex.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
/**
* Closes the target data line to finish capturing and recording
*/
void finish() {
line.stop();
line.close();
System.out.println("Finished");
}
/**
* Entry to run the program
*/
public static void main(String[] args) {
final JavaSoundRecorder recorder = new JavaSoundRecorder();
// creates a new thread that waits for a specified
// of time before stopping
Thread stopper = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(RECORD_TIME);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
recorder.finish();
}
});
stopper.start();
// start recording
recorder.start();
}
}
So, I'm working on a project for class wherein we have to have a game with background music. I'm trying to play a .wav file as background music, but since I can't use clips (too short for a music file) I have to play with the AudioStream.
In my first implementation, the game would hang until the song finished, so I threw it into its own thread to try and alleviate that. Currently, the game plays very slowly while the song plays. I'm not sure what I need to do to make this thread play nice with my animator thread, because we we're never formally taught threads. Below is my background music player class, please someone tell me what I've done wrong that makes it hog all the system resources.
public class BGMusicPlayer implements Runnable {
File file;
AudioInputStream in;
SourceDataLine line;
int frameSize;
byte[] buffer = new byte [32 * 1024];
Thread player;
boolean playing = false;
boolean fileNotOver = true;
public BGMusicPlayer (File inputFile){
try{
file = inputFile;
in = AudioSystem.getAudioInputStream (inputFile);
AudioFormat format = in.getFormat();
frameSize = format.getFrameSize();
DataLine.Info info =new DataLine.Info (SourceDataLine.class, format);
line = (SourceDataLine) AudioSystem.getLine (info);
line.open();
player = new Thread (this);
player.start();
}
catch(Exception e){
System.out.println("That is not a valid file. No music for you.");
}
}
public void run() {
int readPoint = 0;
int bytesRead = 0;
player.setPriority(Thread.MIN_PRIORITY);
while (fileNotOver) {
if (playing) {
try {
bytesRead = in.read (buffer,
readPoint,
buffer.length - readPoint);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (bytesRead == -1) {
fileNotOver = false;
break;
}
int leftover = bytesRead % frameSize;
// send to line
line.write (buffer, readPoint, bytesRead-leftover);
// save the leftover bytes
System.arraycopy (buffer, bytesRead,
buffer, 0,
leftover);
readPoint = leftover;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void start() {
playing = true;
if(!player.isAlive())
player.start();
line.start();
}
public void stop() {
playing = false;
line.stop();
}
}
You are pretty close, but there are a couple of unusual things that maybe are contributing to the performance problem.
First off, if you are just playing back a .wav, there shouldn't really be a need to deal with any "readpoint" but a value of 0, and there shouldn't really be a need for a "leftover" computation. When you do the write, it should simply be the same number of bytes that were read in (return value of the read() method).
I'm also unclear why you are doing the ArrayCopy. Can you lose that?
Setting the Thread to low priority, and putting a Sleep--I guess you were hoping those would slow down the audio processing to allow more of your game to process? I've never seen this done before and it is really unusual if it is truly needed. I really recommend getting rid of these as well.
I'm curious where your audio file is coming from. Your not streaming it over the web, are you?
By the way, the way you get your input from a File and place it into an InputStream very likely won't work with Java7. A lot of folks are reporting a bug with that. It turns out it is more correct and efficient to generate a URL from the File, and then get the AudioInputStream using the URL as the argument rather than the file. The error that can come up is a "Mark/Reset" error. (A search on that will show its come up a number of times here.)
Even though the sun.audio API says that .wav is a supported file apparently the one that I had must not have been. a .aiff file is now working but not in this way I found a better way thats a little more complicated though.
String strFilename = "C:\\Documents and Settings\\gkehoe\\Network\\GIM\\Explode.aiff";
File soundFile = new File(strFilename);
AudioInputStream audioInputStream = null;
try
{
audioInputStream = AudioSystem.getAudioInputStream(soundFile);
}
catch (Exception e)
{
e.printStackTrace();
}
AudioFormat audioFormat = audioInputStream.getFormat();
SourceDataLine line = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class,
audioFormat);
try
{
line = (SourceDataLine) AudioSystem.getLine(info);
/*
The line is there, but it is not yet ready to
receive audio data. We have to open the line.
*/
line.open(audioFormat);
}
catch (LineUnavailableException e)
{
e.printStackTrace();
System.exit(1);
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
line.start();
int nBytesRead = 0;
byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
while (nBytesRead != -1)
{
try
{
nBytesRead = audioInputStream.read(abData, 0, abData.length);
}
catch (IOException e)
{
e.printStackTrace();
}
if (nBytesRead >= 0)
{
int nBytesWritten = line.write(abData, 0, nBytesRead);
}
}
line.drain();
/*
All data are played. We can close the shop.
*/
line.close();
According to source code it is not recognized as supported file format.
Wav files are supported, but there are many variables, and some of them are not supported.
For example, you might get an unrecognized format exception if the wav is encoded at 48000 instead of 44100, or at 24 or 32 bits instead of 16 bit encoding.
What exact error did you get?
What are the specs (properties) of the wav file?
It is possible to convert from one wav to a compatible wav using a tool such as Audacity. A format that I use for wav files has the following properties:
16-bit encoding
little endian
44100 sample rate
stereo
I didn't really look closely at the code example itself. I like this playback example.