2014-11-12 5 views
1

Я пытался добавить код в свое приложение, чтобы преобразовать мои записанные файлы pcm в файлы .wav. У меня есть код для записи заголовка, но по какой-то причине, когда я проигрываю преобразованный .wav-файл через аудиоплеер, все, что вы можете услышать, это шум.Преобразование pcm в .wav - noisy

Это код для моего метода преобразования:

public void writeWavHeader(){ 
    try { 
     File pcmFile = new File(Environment.getExternalStorageDirectory() + File.separator + "TimeShiftRecorder" + File.separator + "Recording.pcm"); 
     File wavFile = new File(Environment.getExternalStorageDirectory() + File.separator + "TimeShiftRecorder" + File.separator + "Recording_test.wav"); 
     OutputStream os = new FileOutputStream(wavFile); 
     BufferedOutputStream bos = new BufferedOutputStream(os); 
     DataOutputStream out = new DataOutputStream(bos); 
     FileInputStream fis = new FileInputStream(pcmFile); 
     InputStream bis = new BufferedInputStream(fis); 
     DataInputStream dis = new DataInputStream(bis); 

     short mBitsPerSample = 16; 
     long audioLength = fis.getChannel().size(); 
     long byteRate = sampleRate * bitsPerSample/8 * channels; 
     short format = 1; 
     long totalDataLen = audioLength + 36; 
     long longSampleRate = 44100; 
     byte byteBitsPerSample = (byte) bitsPerSample; // = 16 
     byte[] header = new byte[44]; 

     header[0] = 'R'; // RIFF/WAVE header 
     header[1] = 'I'; 
     header[2] = 'F'; 
     header[3] = 'F'; 
     header[4] = (byte) (totalDataLen & 0xff); 
     header[5] = (byte) ((totalDataLen >> 8) & 0xff); 
     header[6] = (byte) ((totalDataLen >> 16) & 0xff); 
     header[7] = (byte) ((totalDataLen >> 24) & 0xff); 
     header[8] = 'W'; 
     header[9] = 'A'; 
     header[10] = 'V'; 
     header[11] = 'E'; 
     header[12] = 'f'; // 'fmt ' chunk 
     header[13] = 'm'; 
     header[14] = 't'; 
     header[15] = ' '; 
     header[16] = 16; // 4 bytes: size of 'fmt ' chunk 
     header[17] = 0; 
     header[18] = 0; 
     header[19] = 0; 
     header[20] = 1; // format = 1 
     header[21] = 0; 
     header[22] = (byte) channels; 
     header[23] = 0; 
     header[24] = (byte) (longSampleRate & 0xff); 
     header[25] = (byte) ((longSampleRate >> 8) & 0xff); 
     header[26] = (byte) ((longSampleRate >> 16) & 0xff); 
     header[27] = (byte) ((longSampleRate >> 24) & 0xff); 
     header[28] = (byte) (byteRate & 0xff); 
     header[29] = (byte) ((byteRate >> 8) & 0xff); 
     header[30] = (byte) ((byteRate >> 16) & 0xff); 
     header[31] = (byte) ((byteRate >> 24) & 0xff); 
     header[32] = (byte) (bitsPerSample/8*channels); // block align 
     header[33] = 0; 
     header[34] = byteBitsPerSample; // bits per sample 
     header[35] = 0; 
     header[36] = 'd'; 
     header[37] = 'a'; 
     header[38] = 't'; 
     header[39] = 'a'; 
     header[40] = (byte) (audioLength & 0xff); 
     header[41] = (byte) ((audioLength >> 8) & 0xff); 
     header[42] = (byte) ((audioLength >> 16) & 0xff); 
     header[43] = (byte) ((audioLength >> 24) & 0xff); 
     out.write(header, 0, 44); 


     while (dis.available() > 0) { 
      out.write(dis.read()); 
     } 
     dis.close(); 
     out.close(); 
     //testHeader(); 

    }catch(IOException e){ 
     Log.v("recordService", "IOException"); 
    } 

} 

Из всех примеров я могу найти в Интернете, этот заголовок должен быть правильным.

Если кто-то мог бы помочь мне с тем, где я ошибся, я был бы очень благодарен.

Благодаря Corey :)

+0

Попробуйте прочитать файл .wav с чем-то, что может интерпретировать исходные данные PCM в исходном формате. Что должно случиться, так это то, что вы получаете небольшой шум, поскольку он неправильно истолковывает ваш заголовок как аудио, а затем правильно воспроизводит следующий звук. Если нет, у вас возникли проблемы с данными, как вы их скопировали или каким-то образом запустили его с нечетным, а не смещенным. Но если играть в него как сырое аудио, это работает, тогда у вас, вероятно, проблема с заголовком. –

+0

Вы уверены, что файл PCM малоподвижный? – jaket

ответ

0

Обычно WAV хранит формат каждого образца с 16 битами информации (через два байта памяти). Убедитесь, что вы читаете PCM и пишите в WAV с этим. Один байт может обрабатывать только 256 различных значений на выборку (обычно берут 44100 раз в секунду), что делает 8-битный формат низкой точности. Вместо этого, с 16 бит памяти, у вас есть 2^16 возможных разных значений, которых достаточно для звука с качеством CD. При написании такого кода удобно иметь две программы: (1) конвертировать PCM в WAV, а другой (2) конвертировать WAV обратно в PCM. Таким образом, вы можете использовать (2) для чтения известного хорошего WAV в PCM в качестве исходных данных, чтобы затем использовать (1) для вывода WAV, а затем сравнить WAV для равенства.

Также убедитесь, что вы читаете/записываете в двоичные файлы, а не в обычный режим.

В вашем случае, поскольку формат WAV - это просто данные PCM с заголовком, прикрепленным к передней части файла, если вы читаете ваш PCM в виде двоичного файла, выведите заголовок в новый WAV-файл, а затем напишите буфер памяти как бинарный к WAV, вы должны быть на своем пути.

Смежные вопросы