Пример чтения / записи wav файлов на Android Java

2017/05/03

Возникла у меня задача чтения - записи wav файлов на android для тестированя работы алгоритма VAD - Voice Activity Detection. Так как зачастую wav файлы содержат несжатые PCM данные, то для получения семплов можно просто побайтно читать файл. Ниже показан пример кода, который читает wav файл в массив семплов, уменьшает громкость в четыре раза, и записывает новые данные в другой wav файл.

File rfile = new File(Environment.getExternalStorageDirectory() + File.separator + "music.wav");
File wfile = new File(Environment.getExternalStorageDirectory() + File.separator + "music2.wav");

byte[] header = new byte[44];
byte[] byteInput = new byte[(int)rfile.length() - 44];
short[] input = new short[(int)(byteInput.length / 2f)];

try{
    FileInputStream fis = new FileInputStream(rfile);
    fis.read(header, 0, header.length);
    fis.read(byteInput, 44, byteInput.length - 45);
    ByteBuffer.wrap(byteInput).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(input);
}catch(Exception e){
    e.printStackTrace();
}

ByteBuffer outBuf = ByteBuffer.allocate(2*input.length);
outBuf.order(ByteOrder.LITTLE_ENDIAN);

for (int i = 0; i < input.length; i++)
{
    short sample = input[i]/4;
    outBuf.putShort(sample);
}

try{
    FileOutputStream fos = new FileOutputStream(wfile);
    fos.write(header, 0, header.length);
    fos.write(outBuf.array(), 44, outBuf.array().length - 45);
    fos.flush();
    fos.close();
}catch(Exception e){
    e.printStackTrace();
}

Первые 44 байт wav файла - заголовок. Его читаем в отдельный массив header. Потом идут собственно сами семплы. Преобразование массива байтов в массив типа short делаем с помощью ByteBuffer. Далее каждый семпл делим на 4, и записываем итоговый массив в файл "music2.wav". Метаданные, частота дискретизации, длительность записи не поменялась, поэтому во второй файл применяем eader, считанный из первого файла.

Category: General Tagged: android