Как разбить WAV-файл на каналы в Java? - PullRequest
1 голос
/ 23 апреля 2011

Я хотел бы написать программу на Java для разделения файла wav на каналы. На входе будет wav-файл, а на выходе будет столько же wav-файлов, сколько имеется каналов. Я могу прочитать файл WAV на Java, но как я могу разделить его на каналы?

Ответы [ 4 ]

4 голосов
/ 24 апреля 2011

Заголовок Wave включает в себя поля для размера выборки (в битах) для каждой выборки и количества каналов, закодированных в файле волны.

Имея эту информацию в руках, вы можете разделить каналы: Данные сэмплов в волновом файле содержат сэмплы для каждого чередующегося канала.

Т.е., если у вас было два канала (A, B)у вас есть sA1, sB1, sA2, SB2, sA3, sB3 - сначала выборка для A, затем одна для B, затем еще одна для A и так далее.Это означает, что если у вас есть размер выборки, то есть 16 бит, вы читаете 2 байта из файла, которые принадлежат каналу A, затем 2 байта, которые принадлежат каналу B и т. Д.

1 голос
/ 15 декабря 2013

Если у вас глубина 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];
}

Затем я получил два канала стереозвука.

Надеюсь, это поможет!

0 голосов
/ 09 июля 2018

Нашел довольно простой способ сделать это, хотя не уверен, насколько он эффективен в вычислительном отношении ...

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

    }
}
0 голосов
/ 20 сентября 2016

Вот полный пример:

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