How do I combine/merge two wav files into one wav file?

前端 未结 2 770
隐瞒了意图╮
隐瞒了意图╮ 2020-12-09 06:54

How can I merge two wav files using java?

I tried this but it didn\'t work correctly, is their any other way to do it?

相关标签:
2条回答
  • 2020-12-09 07:24

    Merge implies mixing, but it sounds like you mean concatenation here.

    To concatenate with silence in the middle you need to insert a number of frames of silence into the file. A silent frame is one where every channel has a "0" - if you are using signed samples this is literally a 0, for unsigned, it is maxvalue/2.

    Each frame will have one sample for each channel. So to generate one second of silence in CD format, you would insert 44100 (hz) * 2 (channels per frame) = 88200 16 bit signed ints with a value of 0 each. I am not sure how to access the raw file abstracted by the Java audio abstractions, but that is the data to insert.

    0 讨论(0)
  • 2020-12-09 07:43

    If you work with the bytes of a wav file directly you can use the same strategy in any programming language. For this example I'll assume the two source files have the same bitrate/numchannels and are the same length/size. (if not you can probably edit them before starting the merge).

    First look over the wav specificaiton, I found a good one at a stanford course website:

    Common header lengths are 44 or 46 bytes.

    If you want to concatenate two files (ie play one wav then the other in a single file):

    1. find out what format your wav files are
    2. chop off the first 44/46 bytes which are the headers, the remainder of the file is the data
    3. create a new file and stick one of the headers in that.

      new wav file = {header} = {44/46} bytes long

    4. add the two data parts from the original files

      new wav file = {header + data1 + data2 } = {44/46 + size(data1) + size(data2)} bytes long

    5. modify your header in two places to reflect the new file's length.

      a. modify bytes 4+4 (ie. 4 bytes starting at offset 4). The new value should be a hexadecimal number representing the size of the new wav file in bytes {44/46 + size(data1) + size(data2)} - 8bytes.

      b. modify bytes 40+4 or 42+4 (the 4 bytes starting at offset 40 or 42, depending on if you have a 44byte header or 46 byte header). The new value should be a hexadecimal number representing the total size of the new wav file. ie {44/46 + size(data1) + size(data2)}

    If you want to instead merge or mix the two files (so that they both play at the same time then):

    1. you won't have to edit the header if both files are the same length.
    2. starting at byte 44/46 you will have to edit each sample to be the value in data1 + the value in data2. so for example if your SampleRate was 8 bits you would modify 1 byte, if your sample rate was 16bits you would modify 2 bytes. the rest of the file is just Samples of 1/2bytes storing an int value representing the waveform of the sound at that time.

      a. For each of the remaining samples in the file grab the 1/2 byte hex string and get the int value from both files data1 and data2.

      b. add the 1/2 byte integers together convert the result back to hexadecimal and use that value in your output file.

      c. You normally have to divide that number by 2 to get an average value that fits back in the original 1/2byte sample block. I was getting distortion when i tried it in objc(probably related to signed or unsigned ints) and just skipped the division part since it will only likely be a problem if you are merging very loud sounds together. ie when data1 + data2 is larger than 1/2 bytes the sound will clip. There was a discussion about the clipping issue here and you may want to try one of those clipping techniques.

    0 讨论(0)
提交回复
热议问题