如何将Wav文件拆分为java中的通道?

我想编写一个Java程序将wav文件拆分为通道。 输入将是一个wav文件,输出将是与通道一样多的wav文件。 我可以用Java读取一个wav文件,但是,如何将其拆分为通道?

如果您有16位深度,那么这意味着每个样本将占用2个字节。 这意味着左声道数据将以字节{0,1},{4,5} …等等。

在我的项目中,我使用AudioRecord录制来自两个内置麦克风的立体声。

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]; } 

然后我从立体声中得到了两个声道。

希望这会有所帮助!

Wave标头包括每个样本的样本大小(以位为单位)的字段以及在wave文件中编码的通道数。

掌握此信息后,您可以拆分通道:波形文件中的样本数据包含交错的每个通道的样本。

即如果你有两个通道(A,B)你有sA1,sB1,sA2,SB2,sA3,sB3 – 首先是A的样本,然后是B的一个样本,然后是A的一个样本,依此类推。 这意味着如果您有样本大小,即16位,您从文件中读取属于通道A的2个字节,那么2个字节属于通道B,依此类推。

这是一个完整的例子:

 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); } } 

找到了一种非常简单的方法,但不确定它的计算效率如何……

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]; } }