2016-04-18 12 views
0

多くの似たような質問がありましたが、私はそれらの多くを読んでいましたが、動作させることができませんでした。私がタイトルで言ったように、私は1つの8ビットと1つの16ビットpcmモノファイルを1つのステレオウェーブファイルにマージしたいが、別々のチャンネル、左側のものと右側のチャンネルのものにマージしたい。8bitと16bitのpcmファイルをandroidの別々のオーディオチャンネルにマージする方法

これまでのところ、私が何をしても、次の2つの問題が発生しました。 1出力ファイルの別々のチャネルに書き込むことはできません。

private void WriteWaveFileHeader(
     FileOutputStream out, long totalAudioLen, 
     long totalDataLen, long longSampleRate, int channels, 
     long byteRate) throws IOException { 

    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) (channels * RECORDER_BPP/8); // block align 
    header[33] = 0; 
    header[34] = (byte) RECORDER_BPP; // bits per sample 
    header[35] = 0; 
    header[36] = 'd'; 
    header[37] = 'a'; 
    header[38] = 't'; 
    header[39] = 'a'; 
    header[40] = (byte) (totalAudioLen & 0xff); 
    header[41] = (byte) ((totalAudioLen >> 8) & 0xff); 
    header[42] = (byte) ((totalAudioLen >> 16) & 0xff); 
    header[43] = (byte) ((totalAudioLen >> 24) & 0xff); 

    out.write(header, 0, 44); 
} 

I:ここで

new Thread(new Runnable() { 
     @Override 
     public void run() { 
      int channels = 2; 
      RECORDER_BPP = 16; 
      int RECORDER_SAMPLERATE = 44100; 
      int minBufferSize = AudioTrack.getMinBufferSize(maxCaptureRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); 

      byte[] data = new byte[minBufferSize]; 
      long longSampleRate = RECORDER_SAMPLERATE; 
      long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8; 

      try { 
       FileInputStream in1 = new FileInputStream(rawAudio1); 
       FileInputStream in2 = new FileInputStream(rawAudio2); 
       FileOutputStream out = new FileOutputStream(wavAudio); 
       long totalAudioLen = in1.getChannel().size(); 
       long totalDataLen = totalAudioLen + 36; 

       WriteWaveFileHeader(out, totalAudioLen, totalDataLen, 
         longSampleRate, channels, byteRate); 

       while(in1.read(data) != -1){ 
        out.write(data); 

        //2nd channel ?! // unsuccessful 
        in2.read(data); 
        out.write(data); 
       } 

       in1.close(); 
       in2.close(); 
       out.close(); 
      } catch (Exception e) { 
       Log.d("EEE-2ch", e.getMessage()); 
      } 
     } 
}).start(); 

とヘッダ部分です:ファイルの -2-オンは、( "RECORDER_BPP" は8または16であるか否か)

私のコードは、ノイズのように書かれることになりますありがとうございました。

+0

ステレオPCMデータはインターリーブされます(L R L R L Rなど)ので、一度に1つのサンプルを読み書きする必要があります。また、8ビットのサンプルでは、​​ラウドネスを維持したい場合はスケーリングを適用する必要があります。 – Michael

+0

@Michaelありがとうございますが、これらの処理方法に関するサンプルコードをいくつか教えていただけますか?私は正直なところ、オーディオファイルを扱う経験はありませんし、あなたが言ったことをよく理解していませんでした。ありがとう –

答えて

0

出力データをインターリーブする必要があります。つまり、in1から1つのサンプルを読み込み、出力に書き込んだ後、1​​つのサンプルを読み込む必要がありますin2から出力してください。 in2は8ビットのオーディオなので、8ビットのサンプルを読み込み、16ビットを書き出す必要があります。

byte[] data = new byte[2]; 
while(in1.read(data) != -1) { // read 2 bytes 
    out.write(data);   // write 2 bytes (L) 
    in2.read(data, 0, 1);  // read 1 byte 
    data[1] = 0;    // set the other byte to zero 
    // if this is the wrong byte order then do this 
    // data[1] = data[0]; 
    // data[0] = 0; 
    out.write(data);   // write 2 bytes (R) 
} 

このコードされIN1が16ビットオーディオのファイルであることを前提としています。それが間違っている場合、あなたは少しそれを再加工する必要があります。

+0

ありがとう。私はそれをできるだけ早く試してみます:) –

+0

実際には左右のチャンネルを分けていましたが、8bitファイルが書き込まれたチャンネルは完全なノイズです。 wavファイルへの書き込み中にRECORDER_BPP = 16に設定されていることが原因です。私はあなたが言ったようにバイト順序を変更しましたが、他のバイトは空で何も書きません。私はpcmファイルをチェックし、彼らは大丈夫です。任意のアイデアをどのようにこれを修正するには? –

+0

もう一つのバイトが何を意味するのかよく分かりません。 2番目のチャンネルのために何をする必要があるかは、1バイトを読み取った後、左にシフトすることによって2バイトとして書き出します。したがって、ファイル内のサンプル値が0x43だった場合、0x4300を書き出しています - voilaの8ビット値は16ビット値に変わります。 – jaket

関連する問題