gpt4 book ai didi

Java(声音)- 将 2D int 数组转换为字节数组

转载 作者:行者123 更新时间:2023-12-02 04:45:03 27 4
gpt4 key购买 nike

我正在尝试混合 2 个音频剪辑(相同格式、相同长度)。对于每个剪辑,我将它们转换为字节数组,将这些字节数组转换为 2D int 数组,添加它们,然后将新的 2D int 数组转换为字节数组,然后将其写入磁盘。这非常有效......仅在一个 channel 上。我创建的文件(在本例中为 test.wav)仅左耳有声音。在我的程序中,我有一个方法可以将 2D int tab 存储到 txt 文件中。我尝试分析 test.wav,将其转换为字节数组,然后转换为 2D int 数组,就像我用来转换原始剪辑的方式一样。我得到两个 vector ,每个 vector 对应一个音频 channel 。在我的第一个 vector 中,我得到了我应该拥有的东西,添加了两个剪辑的左 channel ,但在我的第二个 vector (右 channel )中,我得到了一系列 -1 和 0。我猜我的 TabToByte 方法有问题,但我无法指出它。

任何帮助将不胜感激!提前致谢。

代码:

    public class Main {
public static void main (String[] args) {

//My audio clips
String wavFile1 = "C:\\Users\\Alban.Alban-PC\\Documents\\Java\\Generateur-de-musiques-commerciales\\Samples\\Fa.wav";
String wavFile2 = "C:\\Users\\Alban.Alban-PC\\Documents\\Java\\Generateur-de-musiques-commerciales\\Samples\\Drum beat.wav";

try {

AudioInputStream clip1 = AudioSystem.getAudioInputStream(new File(wavFile1));
AudioInputStream clip2 = AudioSystem.getAudioInputStream(new File(wavFile2));
//frameLength of each clip
int frameLength1 = (int) clip1.getFrameLength();
int frameLength2 = (int) clip2.getFrameLength();
//Frame size = 4 because I'm using 2-channels with 16-bits encoded sound
int frameSize1 = (int) clip1.getFormat().getFrameSize();
int frameSize2 = (int) clip2.getFormat().getFrameSize();
//Number of channels = 2
int numChannels = clip1.getFormat().getChannels();

//byte array to store my entier clips
byte[] eightBitByteArray1 = new byte[frameLength1 * frameSize1];
byte[] eightBitByteArray2 = new byte[frameLength2 * frameSize2];

//Converts my clips into chosen byte arrays
clip1.read(eightBitByteArray1);
clip2.read(eightBitByteArray2);

//I want to store my clip samples in 2D int arrays
int[][] toReturn1 = new int[numChannels][frameLength1];
int[][] toReturn2 = new int[numChannels][frameLength2];
int[][] toReturn = new int[numChannels][frameLength2];

//I convert each byte array into 2D int arrays
toReturn1 = ByteToTab(eightBitByteArray1);
toReturn2 = ByteToTab(eightBitByteArray2);

//I add my 2 int arrays
//This is equivalent to mixing my clips
toReturn = addTab(toReturn1, toReturn2);

//I convert my new int array into a new byte array
byte[] mix = TabToByte(toReturn);


//I store my 2D int arrays in txt files to see if I get proper results
fichierTxt(toReturn1, "do.txt");
fichierTxt(toReturn2, "drum.txt");
fichierTxt(toReturn, "mix.txt");

//I create an inputStream with my new byte array
InputStream byteArray = new ByteArrayInputStream(mix);
//I create a new clip
AudioInputStream ais = new AudioInputStream(byteArray,
clip1.getFormat(), clip1.getFrameLength());
//I write it on the disk
AudioSystem.write(ais,
AudioFileFormat.Type.WAVE,
new File("C:\\Users\\Alban.Alban-PC\\Documents\\Java\\test.wav"));

} catch (UnsupportedAudioFileException e) {
} catch (IOException e) {e.printStackTrace(); }


}

//Transforms 2 bytes into a single int
public static int getSixteenBitSample(int high, int low) {
return (high << 8) + (low & 0x00ff);
}

//Creates a byte array from a 2D int array
public static byte[] TabToByte (int[][] tab) {
byte[] b = new byte[tab[0].length*4];
int count = 0;
for (int i = 0; i < tab[0].length; i ++){
for (int j = 0; j <tab.length; j++){
for (int k = 0; k < 2; k++){
b[count] = (byte)(tab[j][i] >>> (count * 8));
count++;
}
}
}
return b;
}

//Creates a 2D int array from a byte array
public static int[][] ByteToTab (byte[] array) {
int sampleIndex = 0;
int[][] toReturn = new int [2][array.length/4];

for (int t = 0; t < array.length;) {
for (int channel = 0; channel < 2; channel++) {
int low = (int) array[t];
t++;
int high = (int) array[t];
t++;
int sample = getSixteenBitSample(high, low);
toReturn[channel][sampleIndex] = sample;
}
sampleIndex++;
}
return toReturn;
}


//Ajouter 2 tableaux de même dimension entre eux
public static int[][] addTab(int[][] tab1, int[][] tab2) {
int[][] tab = new int[tab1.length][tab1[0].length];
for (int i = 0; i < tab1.length; i ++) {
for (int j = 0; j < tab1[0].length; j++) {
tab [i][j] = tab1[i][j]+tab2[i][j];
}
}
return tab;
}


//To write a 2D tab into a txt file
public static void fichierTxt(int[][] tab, String s) {
try {
String s1 = "C:\\Users\\Alban.Alban-PC\\Documents\\Java\\";
String st = s1 +s;
File fichier = new File(st);
fichier.createNewFile();
FileWriter fichierWrite = new FileWriter(fichier);
for (int i = 0; i < tab.length; i++){
fichierWrite.write("[ ");
for (int j = 0; j < tab[i].length; j ++){
fichierWrite.write(tab[i][j]+" ");
}
fichierWrite.write("]");
fichierWrite.write(System.lineSeparator());
}
fichierWrite.close();
} catch (Exception e) {}
}
}

最佳答案

你已经

b[count] = (byte)(tab[j][i] >>> (count * 8));
count++;

你应该有

b[count] = (byte)(tab[j][i] >>> (k * 8));
count++;

您可能想向下移动 08

count * 8 移动会得到奇怪的结果:( jls )

[…] only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.

关于Java(声音)- 将 2D int 数组转换为字节数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29728002/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com