How to split a Wav file into channels in java?

£可爱£侵袭症+ 提交于 2019-12-08 05:55:29

问题


I would like to write a Java program to split a wav file into channels. The input would be a wav file, and the output would be as many wav files as there are channels. I can read a wav file in Java but, how can I split it into channels?


回答1:


Found a pretty easy way of doing it, not sure how computationally efficient it is though...

public void splitByteArray (byte [] fileContent, byte [] fileContentLeft, byte [] fileContentRight) {

    for (int i = 0; i < fileContent.length; i += 4) {

        fileContentLeft[i] = fileContent[i];
        fileContentLeft[i + 1] = fileContent[i + 1];
        fileContentRight[i + 2] = fileContent[i + 2];
        fileContentRight[i + 3] = fileContent[i + 3];

    }
}



回答2:


The Wave header includes fields for the sample size (in bits) for each sample and the number of channels encoded within the wave file.

With this information in hand, you can split the channels: The sample data in a wave file contains the samples for each channel interleaved.

I.e. if you had two channels (A,B) you have sA1, sB1, sA2, SB2, sA3, sB3 - first a sample for A, then one for B, then one for A again and so on. That means if you have the sample size, i.e. 16 bit you read 2 bytes from the file which belong to channel A, then 2 bytes that belong to channel B and so on.




回答3:


If you have a 16 bit depth, so that means each sample will take 2 bytes. That means the left channel data will be in bytes {0,1}, {4,5}... and so on.

In my project, I used AudioRecord recording stereo sound from two internal microphones.

private int audioSource = MediaRecorder.AudioSource.MIC;   
private static int sampleRateInHz = 44100;  
private static int channelConfig = AudioFormat.CHANNEL_IN_STEREO;  
private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;  

readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);   
for(int i = 0; i < readsize/2; i = i + 2)
{

      leftChannelAudioData[i] = audiodata[2*i];
      leftChannelAudioData[i+1] = audiodata[2*i+1]; 
      rightChannelAudioData[i] =  audiodata[2*i+2];
      rightChannelAudioData[i+1] = audiodata[2*i+3];
}

Then I got the two channels from the stereo sound.

Hope this would help!




回答4:


Here is a complete example:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;

public class ChannelSplitter {

    public static void main(String[] args) throws Exception {

        String filename = "test.wav";

        File sourceFile = new File(filename);
        File leftTargetFile = new File("left_"+filename);
        File rightTargetFile = new File("right_"+filename);

        AudioFileFormat fileFormat = AudioSystem.getAudioFileFormat(sourceFile);
        AudioFileFormat.Type targetFileType = fileFormat.getType();
        AudioFormat audioFormat = fileFormat.getFormat();

        AudioInputStream inputAIS = AudioSystem.getAudioInputStream(sourceFile);

        ByteArrayOutputStream leftbaos = new ByteArrayOutputStream();
        ByteArrayOutputStream rightbaos = new ByteArrayOutputStream();

        byte[] bytes = new byte[(audioFormat.getSampleSizeInBits()/8)*2];

        while (true) {

            int readsize = inputAIS.read(bytes);   

            if(readsize==-1){
                break;
            }

            rightbaos.write(bytes,0,bytes.length/2);
            leftbaos.write(bytes,bytes.length/2,bytes.length/2);
        }

        byte[] leftData = leftbaos.toByteArray();
        byte[] rightData = rightbaos.toByteArray();

        AudioFormat outFormat = new AudioFormat(audioFormat.getEncoding(),audioFormat.getSampleRate(),audioFormat.getSampleSizeInBits(),1,audioFormat.getFrameSize()/2, audioFormat.getFrameRate(),audioFormat.isBigEndian());

        ByteArrayInputStream leftbais = new ByteArrayInputStream(leftData);
        AudioInputStream leftoutputAIS = new AudioInputStream(leftbais, outFormat, leftData.length / outFormat.getFrameSize());
        AudioSystem.write(leftoutputAIS, targetFileType, leftTargetFile);

        ByteArrayInputStream rightbais = new ByteArrayInputStream(rightData);
        AudioInputStream rightoutputAIS = new AudioInputStream(rightbais, outFormat, rightData.length / outFormat.getFrameSize());
        AudioSystem.write(rightoutputAIS, targetFileType, rightTargetFile);
    }
}


来源:https://stackoverflow.com/questions/5766445/how-to-split-a-wav-file-into-channels-in-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!