问题
First of all thanks everyone for helping me with my previous questions.
In the following code I am taking two frequencies alternatively and writing them into a .wav format, to run it in my Windows Media Player, for a specific time given by the user. What I want is to understand how to loop those frequencies to run alternatively for that specified time, like the Ambulance's siren, and in my program both frequencies are getting played just once, alternatively. For example, if I am specifying the time as 10 seconds, then both the frequencies run for 5 seconds each at a stretch. But what I want is that the 1st frequency to run for a second or two seconds(as the user specifies) and then the 2nd frequency to run for that similar second and then again the 1st frequency and it should keep on going till the specified time.
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
public class AudioWrite2New {
public static void main(String[] args) throws IOException, InterruptedException, LineUnavailableException {
Scanner in = new Scanner(System.in);
final double SAMPLING_RATE = 44100; // Audio sampling rate
int time = in.nextInt(); //Time specified by user in seconds
// int time2 = in.nextByte();
int frequency1 = in.nextInt(); //Frequency1 specified by the user in hz
int frequency2 = in.nextInt(); //Frequency2 specified by the user in hz
float buffer[] = new float[(int) (time/2 * SAMPLING_RATE)]; //Size of buffer[], which in case of 10 seconds is 441000
float buffer1[] = new float[(int) (time/2 * SAMPLING_RATE)]; //Size of buffer1[], which in case of 10 seconds is 441000
for (int sample = 0; sample < buffer.length; sample++) {
double cycle = sample / SAMPLING_RATE; //Fraction of cycle between samples
buffer[sample] = (float) (Math.sin(2 * Math.PI * frequency1 * cycle));
//buffer1[sample] = (float) (Math.sin(2 * Math.PI * frequency2 * cycle));
}
for (int sample = 0; sample < buffer1.length; sample++) {
double cycle = sample / SAMPLING_RATE; //Fraction of cycle between samples
//buffer[sample] = (float) (Math.sin(2 * Math.PI * frequency1 * cycle));
buffer1[sample] = (float) (Math.sin(2 * Math.PI * frequency2 * cycle));
}
//System.out.println(buffer[1]);
byte byteBuffer[] = new byte[buffer.length * 2]; //Size of byteBuffer, in this case 882000
byte byteBuffer1[] = new byte[buffer1.length * 2]; //Size of byteBuffer, in this case 882000
int count = 0;
for (int i = 0; i < byteBuffer.length; i++) {
final int x = (int) (buffer[count++] * Short.MAX_VALUE);
byteBuffer[i++] = (byte) x;
byteBuffer[i] = (byte) (x / 256);
}
count = 0;
for (int i = 0; i < byteBuffer1.length; i++) {
final int x = (int) (buffer1[count++] * Short.MAX_VALUE);
byteBuffer1[i++] = (byte) x;
byteBuffer1[i] = (byte) (x / 256);
}
//For merging the two frequencies
byte[] merge = new byte[byteBuffer.length + byteBuffer1.length];
System.arraycopy(byteBuffer, 0, merge, 0, byteBuffer.length);
System.arraycopy(byteBuffer1, 0, merge, byteBuffer.length, byteBuffer1.length);
File out = new File("E:/RecordAudio17.wav"); //The path where user want the file data to be written
//Construct an audio format, using 44100hz sampling rate, 16 bit samples, mono, and big
// endian byte ordering
AudioFormat format = new AudioFormat((float) SAMPLING_RATE, 16, 1, true, false);
// It uses bytebuffer as its buffer array that contains bytes that may be read from the stream.
ByteArrayInputStream bais = new ByteArrayInputStream(merge);
//Constructs an audio input stream that has the requested format and length in sample frames, using audio data
//from the specified input stream.
AudioInputStream audioInputStream = new AudioInputStream(bais, format, buffer1.length + buffer.length);
//Writes a stream of bytes representing an audio file of the specified file type to the external file provided.
AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, out);
audioInputStream.close(); //Closes this audio input stream
}
}
And as I am quite new in Java and JavaSounds, therefore sometimes I might ask few foolish or irrelevant questions. So please bear with me as that is the only way in which I can learn. Thanks.
回答1:
I resolved it. Although there is one minor part that I need to handle. I will update it as soon as I am done with it.
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
public class AudioWrite2New {
public static void main(String[] args) throws IOException, InterruptedException, LineUnavailableException {
Scanner in = new Scanner(System.in);
final double SAMPLING_RATE = 44100; // Audio sampling rate
int time = in.nextInt(); //Time specified by user in milliseconds
int time2 = in.nextByte();
int frequency1 = in.nextInt(); //Frequency1 specified by the user in hz
int frequency2 = in.nextInt(); //Frequency2 specified by the user in hz
float buffer[] = new float[((int) (time * SAMPLING_RATE))/1000]; //Size of buffer[], which in case of 10 seconds is 441000
float buffer1[] = new float[((int) (time * SAMPLING_RATE))/1000]; //Size of buffer1[], which in case of 10 seconds is 441000
//for (int a = 1; a <= time2 / 2; a++) {
for (int sample = 0; sample < buffer.length; sample++) {
double cycle = sample / SAMPLING_RATE; //Fraction of cycle between samples
buffer[sample] = (float) (Math.sin(2 * Math.PI * frequency1 * cycle));
//buffer1[sample] = (float) (Math.sin(2 * Math.PI * frequency2 * cycle));
}
for (int sample = 0; sample < buffer1.length; sample++) {
double cycle = sample / SAMPLING_RATE; //Fraction of cycle between samples
//buffer[sample] = (float) (Math.sin(2 * Math.PI * frequency1 * cycle));
buffer1[sample] = (float) (Math.sin(2 * Math.PI * frequency2 * cycle));
}
//System.out.println(buffer[1]);
byte byteBuffer[] = new byte[buffer.length * 2]; //Size of byteBuffer, in this case 882000
byte byteBuffer1[] = new byte[buffer1.length * 2]; //Size of byteBuffer, in this case 882000
int count = 0;
for (int i = 0; i < byteBuffer.length; i++) {
final int x = (int) (buffer[count++] * Short.MAX_VALUE);
byteBuffer[i++] = (byte) x;
byteBuffer[i] = (byte) (x / 256);
}
count = 0;
for (int i = 0; i < byteBuffer1.length; i++) {
final int x = (int) (buffer1[count++] * Short.MAX_VALUE);
byteBuffer1[i++] = (byte) x;
byteBuffer1[i] = (byte) (x / 256);
}
int iterations = (1000*time2)/(2*time);
byte[] merge = new byte[iterations*(byteBuffer.length + byteBuffer1.length)];
for (int i = 0; i<iterations; i++)
{
//arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
//For merging the two frequencies
System.arraycopy(byteBuffer, 0, merge, 0+i*(byteBuffer.length + byteBuffer1.length), byteBuffer.length);
System.arraycopy(byteBuffer1, 0, merge, byteBuffer.length+i*(byteBuffer.length + byteBuffer1.length), byteBuffer1.length);
}
File out = new File("E:/RecordAudio17.wav"); //The path where user want the file data to be written
//Construct an audio format, using 44100hz sampling rate, 16 bit samples, mono, and big
// endian byte ordering
AudioFormat format = new AudioFormat((float) SAMPLING_RATE, 16, 1, true, false);
// It uses bytebuffer as its buffer array that contains bytes that may be read from the stream.
ByteArrayInputStream bais = new ByteArrayInputStream(merge);
//Constructs an audio input stream that has the requested format and length in sample frames, using audio data
//from the specified input stream.
AudioInputStream audioInputStream = new AudioInputStream(bais, format, (buffer1.length + buffer.length) * (time2/4));
//Writes a stream of bytes representing an audio file of the specified file type to the external file provided.
AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, out);
//}
//audioInputStream.close(); //Closes this audio input stream
}
}
来源:https://stackoverflow.com/questions/40838808/how-can-i-loop-a-sound-without-using-clip-in-java-before-writing-it-into-a-fil