输出wav文件的大小比原始大几倍

时间:2015-04-08 05:50:14

标签: java audio wav

我正在创建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;
}                       

1 个答案:

答案 0 :(得分:2)

WAV文件是little-endian,但是你的intToByteArraybytesToLong认为它是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;
}