我正在创建wav文件的副本,但输出wav文件比原始文件大几倍。(例如,对于130 kB的文件,复制的文件是83.6 MB) 从原始波形文件中提取的数据大小本身非常大。 不知道我做错了什么。
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
try {
long myChunkSize;
long mySubChunk1Size;
int myFormat;
long myChannels;
long mySampleRate;
long myByteRate;
int myBlockAlign;
int myBitsPerSample;
long myDataSize;
byte[] myData;
long extensionbyte;
byte[] tmpLong = new byte[4];
byte[] tmpInt = new byte[2];
DataInputStream inFile = new DataInputStream(new
FileInputStream("/home/therising/Rear_Center.wav"));
String chunkID = "" + (char) inFile.readByte() + (char)
inFile.readByte() + (char) inFile.readByte() + (char) inFile.readByte();
inFile.read(tmpLong); // read the ChunkSize
myChunkSize = bytesToLong(tmpLong);
String format = ""+ (char) inFile.readByte() + (char)
inFile.readByte() + (char) inFile.readByte() + (char) inFile.readByte();
String subChunk1ID = "" + (char) inFile.readByte() + (char)
inFile.readByte() + (char) inFile.readByte() + (char) inFile.readByte();
inFile.read(tmpLong); // read the SubChunk1Size
mySubChunk1Size = bytesToLong(tmpLong);
inFile.read(tmpInt); // read the audio format.should be 1 for PCM
myFormat = byteArrayToInt(tmpInt);
inFile.read(tmpInt); // read the # of channels (1 or 2)
myChannels = byteArrayToInt(tmpInt);
inFile.read(tmpLong); // read the samplerate
mySampleRate = bytesToLong(tmpLong);
inFile.read(tmpLong); // read the byterate
myByteRate = bytesToLong(tmpLong);
inFile.read(tmpInt); // read the blockalign
myBlockAlign = byteArrayToInt(tmpInt);
inFile.read(tmpInt); // read the bitspersample
myBitsPerSample = byteArrayToInt(tmpInt);
inFile.readByte();
// print what we've read so far
System.out.println("format"+format+"chunkID"+chunkID+"SubChunk1ID:"
+ subChunk1ID + " SubChunk1Size:" + mySubChunk1Size + " AudioFormat:" +
myFormat + " Channels:" + myChannels + " SampleRate:" + mySampleRate);
// read the data chunk header - reading this IS necessary, because
not all wav files will have the data chunk here - for now, we're just
assuming that the data chunk is here
String dataChunkID = "" + (char) inFile.readByte() + (char)
inFile.readByte() + (char) inFile.readByte() + (char) inFile.readByte();
System.out.println("
myByteRate"+myByteRate+"myChunkSize"+myChunkSize+"myBlockAlign"+
myBlockAlign+"myBitsPerSample"+myBitsPerSample+"dc"+dataChunkID);
inFile.read(tmpLong); // read the size of the data
myDataSize = bytesToLong(tmpLong);
System.out.println(" ds"+myDataSize);
// read the data chunk
myData = new byte[(int) myDataSize];
inFile.read(myData);
//System.out.println(" da"+myData.toString());
// close the input stream
DataOutputStream outFile = new DataOutputStream(new
FileOutputStream("/home/therising/my.wav" ));
// write the wav file per the wav file format
outFile.writeBytes("RIFF"); // 00 - RIFF
outFile.write(intToByteArray((int) myChunkSize), 0, 4);
//04-howbigis the rest of this file?
outFile.writeBytes("WAVE"); // 08 - WAVE
outFile.writeBytes("fmt "); // 12 - fmt
outFile.write(intToByteArray((int) mySubChunk1Size), 0, 4);
// 16 - size of this chunk
outFile.write(shortToByteArray((short) myFormat), 0, 2);
// 20 - what is the audio format? 1 for PCM = Pulse Code Modulation
outFile.write(shortToByteArray((short) myChannels), 0, 2);
// 22 - mono or stereo? 1 or 2? (or 5 or ???)
outFile.write(intToByteArray((int) mySampleRate), 0, 4);
//24 - samples per second (numbers per second)
outFile.write(intToByteArray((int) myByteRate), 0, 4);
// 28 - bytes per second
outFile.write(shortToByteArray((short) myBlockAlign), 0, 2);
// 32 - # of bytes in one sample, for all channels
outFile.write(shortToByteArray((short) myBitsPerSample), 0, 2);
// 34 - how many bits in a sample(number)? usually 16 or 24
// outFile.writeBytes(blank);
outFile.writeBytes("data"); // 36 - data
outFile.write(intToByteArray((int) myDataSize), 0, 4); // 40 - how big is this data chunk
outFile.write(myData);
inFile.close();
}
System.out.println("done");
} catch (FileNotFoundException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
public byte[] shortToByteArray(short data) {
return new byte[]{(byte) (data & 0xff), (byte) ((data >>> 8) & 0xff)};
}
public static int byteArrayToInt(byte[] b)
{
int value = 0;
for (int i = 0; i < 2; i++) {
int shift = (i) * 8;
value += (b[i] & 0x000000FF) << shift;
}
return value;
}
public static byte[] intToByteArray(int a)
{
return new byte[] {
(byte) ((a >> 24) & 0xFF),
(byte) ((a >> 16) & 0xFF),
(byte) ((a >> 8) & 0xFF),
(byte) (a & 0xFF)
};
}
public long bytesToLong(byte[] by)
{
long value = 0;
for (int i = 0; i < by.length; i++)
{
value = (value << 8) + (by[i] & 0xff);
}
return value;
}
答案 0 :(得分:2)
WAV文件是little-endian,但是你的intToByteArray
和bytesToLong
认为它是big-endian。
这可能会导致您遇到的问题 - 因为大小经过此转换,字节顺序向后。小数字会变大,反之亦然。
所以,例如。
public static byte[] intToByteArray(int a)
{
return new byte[] {
(byte) ((a >> 24) & 0xFF),
(byte) ((a >> 16) & 0xFF),
(byte) ((a >> 8) & 0xFF),
(byte) ((a ) & 0xFF),
};
}
public long bytesToLong(byte[] by)
{
long value = 0;
for (int i = 0; i < by.length; i++)
{
value |= ( by[i] & 0xFF ) << ( i * 8 );
}
return value;
}