Audio 如何查找2D字节数组的长度以及如何在ByteArrayInputStream中使用该2D字节数组
首先,在下面的代码中,我尝试使用“byteBuffer[0].length”查找2D字节数组的长度,但实际上它不起作用。当我打印“byteBuffer[0].length”时,它将输出为4,而不是882000,根据我传递的参数,882000应该是正确的输出。那么我如何在循环中迭代它呢 其次,我想在“ByteArrayInputStream”中传递“byteBuffer”,但在“ByteArrayInputStream”中,我们不能传递2D数组。那么有没有一种附加值并在那里使用的方法呢?我还需要交替传递'Frequency1'和'Frequency2'的值,并将它们保存为.wav格式,以便我可以在媒体播放器中相应地播放它们。例如:救护车的警报器Audio 如何查找2D字节数组的长度以及如何在ByteArrayInputStream中使用该2D字节数组,audio,javasound,java,javax.sound.sampled,Audio,Javasound,Java,Javax.sound.sampled,首先,在下面的代码中,我尝试使用“byteBuffer[0].length”查找2D字节数组的长度,但实际上它不起作用。当我打印“byteBuffer[0].length”时,它将输出为4,而不是882000,根据我传递的参数,882000应该是正确的输出。那么我如何在循环中迭代它呢 其次,我想在“ByteArrayInputStream”中传递“byteBuffer”,但在“ByteArrayInputStream”中,我们不能传递2D数组。那么有没有一种附加值并在那里使用的方法呢?我还需要交
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
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;
public class AudioPlay {
public static void main(String[] args) throws IOException {
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 frequency1 = in.nextInt(); //Frequency specified by the user in hz
int frequency2 = in.nextInt();
//Size of buffer, in case time is 10 seconds it will be [2][441000]
float buffer[][] = new float[2][(int) (time * SAMPLING_RATE)];
for (int sample = 0; sample < buffer[0].length; sample++) {
double cycle = sample / SAMPLING_RATE; //Fraction of cycle between samples
buffer[0][sample] = (float) (Math.sin(2 * Math.PI * frequency1 * cycle)); //Storing value at every index of 1st row
buffer[1][sample] = (float) (Math.sin(2 * Math.PI * frequency2 * cycle)); //Storing value at every index of 2nd row
}
//Size of byteBuffer, in case time is 10sec it will be [2][882000]
byte byteBuffer[][] = new byte[2][(int)(buffer.length * 2)];
System.out.println(byteBuffer[0].length); // Giving wrong output
int count = 0;
for (int j = 0; j < byteBuffer.length; j++) {
for (int i = 0; i < byteBuffer[0].length; i++) {
final int x = (int) ((buffer[j][count++]) * Short.MAX_VALUE);
byteBuffer[j][i++] = (byte) x;
byteBuffer[j][i] = (byte) (x / 256); //Total Value of Byte
}
}
File out = new File("E:/RecordAudio7.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(byteBuffer[0]);
//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, 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
}
import java.io.ByteArrayInputStream;
导入java.io.ByteArrayOutputStream;
导入java.io.File;
导入java.io.IOException;
导入java.util.Scanner;
导入javax.sound.sampled.AudioFileFormat;
导入javax.sound.sampled.AudioFormat;
导入javax.sound.sampled.AudioInputStream;
导入javax.sound.sampled.AudioSystem;
公营音乐剧{
公共静态void main(字符串[]args)引发IOException{
扫描仪输入=新扫描仪(系统输入);
最终双采样率=44100;//音频采样率
int time=in.nextInt();//用户以秒为单位指定的时间
int frequency1=in.nextInt();//用户以hz为单位指定的频率
int frequency2=in.nextInt();
//缓冲区大小,如果时间为10秒,则为[2][441000]
浮点缓冲区[][]=新浮点[2][(int)(时间*采样率)];
对于(int-sample=0;sample
}我找到了问题第一部分的答案。 代码中只有一个小改动:
byte byteBuffer[][] = new byte[2][(int)(buffer[0].length * 2)];
而不是
byte byteBuffer[][] = new byte[2][(int)(buffer.length * 2)];
用字节缓冲声明
不正确
您使用的是buffer.length
,它是2,这就是为什么输出是4
使用buffer[0]。长度*2
而不是buffer.length*2
,如下所示:
byte byteBuffer[][] = new byte[2][(int)(buffer[0].length * 2)];
对于第二部分,(将2D数组传递到ByteArrayInputStream)
可以将2D元素放入一个1D长的数组中
其中长度将等于byteBuffer[0]。长度*byteBuffer.length
您可以使用类似以下内容的System.arraycopy()
:
int newArrayLength = byteBuffer.length*byteBuffer[0].length;
byte oneArray[] = new byte[newArrayLength];
//arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
for(int b=0;b<byteBuffer.length;b++){
System.arraycopy(byteBuffer[b], 0, oneArray, (b*byteBuffer[b].length), byteBuffer[b].length)
}
并将oneArray
用于您的ByteArrayInputStream
注意:如果你的应用程序在这一步之后将继续运行,最好释放为byteBuffer
分配的内存,因为它不再需要了,因为你将使用oneArray
,你可以通过取消引用来释放内存
byteBuffer=null代码>非常感谢@Yazan,但我的问题还没有解决。我创建的.wav文件实际上根本不产生声音,但我认为这是因为我使用的是2D数组。如前所述,我正在使用1D阵列为1个频率编写相同的代码,并且工作正常。因此,现在我再次重新思考整个逻辑,使用1D数组来处理2个频率,我可以在.wav文件中添加这些频率。非常感谢您的建议和帮助。@vibhavchadda我对wav文件不太确定,但我认为有两种类型,单声道和立体声,您可能需要使用立体声?“如果可能,请…”。问一个问题。此外,请不要张贴要求的“购物清单”。问答网站也是如此,而不是服务台。“还有一个问题,我再也懒得修理了。”安德烈·霍姆普森:好的,先生。我会记住这一切的。谢谢
[][][][][][][]...[][][][][][][]...[][][][][][][]...