6

リソースフォルダーに2つのPCMサウンドファイルがあります。inputstream を使用して bytearray に変換しました。

次に、music1 と music2 を正規化して追加し、バイト配列出力に出力して処理しました。最後に、出力配列を置き、それを AudioTrack にフィードします。

明らかに何も聞こえないし、何かがおかしい。

 private void mixSound() throws IOException {

    InputStream in1=getResources().openRawResource(R.raw.cheerapp2);      
    InputStream in2=getResources().openRawResource(R.raw.buzzer2);

     byte[] music1 = null;
     music1= new byte[in1.available()]; 
     music1=convertStreamToByteArray(in1);
     in1.close();


     byte[] music2 = null;
     music2= new byte[in2.available()]; 
     music2=convertStreamToByteArray(in2);
     in2.close();

     byte[] output = new byte[music1.length];

     audioTrack.play();

     for(int i=0; i < output.length; i++){

         float samplef1 = music1[i] / 128.0f;      //     2^7=128
         float samplef2 = music2[i] / 128.0f;


         float mixed = samplef1 + samplef2;
         // reduce the volume a bit:
         mixed *= 0.8;
         // hard clipping
         if (mixed > 1.0f) mixed = 1.0f;
         if (mixed < -1.0f) mixed = -1.0f;
        byte outputSample = (byte)(mixed * 128.0f);
         output[i] = outputSample;
         audioTrack.write(output, 0, i);
      }   //for loop


      public static byte[] convertStreamToByteArray(InputStream is) throws IOException {



    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buff = new byte[10240];
    int i = Integer.MAX_VALUE;
    while ((i = is.read(buff, 0, buff.length)) > 0) {
        baos.write(buff, 0, i);
    }

    return baos.toByteArray(); // be sure to close InputStream in calling function

}
4

1 に答える 1

10

私はあなたのコードを試しました(私自身のいくつかのオーディオファイルに置き換えました)。このように AudioTrack インスタンスを初期化しました。うまくいけば、これはあなたが行った方法と似ています。

AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, 44100, AudioTrack.MODE_STREAM);

そして実行してみました。それは甲高い音を立て、時間が経つにつれて低くなりました。コードを確認したところ、問題は、mixSound() メソッドのループの反復ごとに、出力バイト配列全体を audioTrack に書き込んでいることです。

この線

 audioTrack.write(output, 0, i);

ループの外に移動し、に変更する必要があります

 audioTrack.write(output, 0, output.length);

したがって、両方のファイルを混合して出力バイト配列にし、一度にすべてを書き込みます。

したがって、機能する mixSound メソッドのコードは次のようになります。

private void mixSound() throws IOException {
    AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, 44100, AudioTrack.MODE_STREAM);

    InputStream in1=getResources().openRawResource(R.raw.track1);      
    InputStream in2=getResources().openRawResource(R.raw.track2);

    byte[] music1 = null;
    music1= new byte[in1.available()]; 
    music1=convertStreamToByteArray(in1);
    in1.close();


    byte[] music2 = null;
    music2= new byte[in2.available()]; 
    music2=convertStreamToByteArray(in2);
    in2.close();

    byte[] output = new byte[music1.length];

    audioTrack.play();

    for(int i=0; i < output.length; i++){

        float samplef1 = music1[i] / 128.0f;      //     2^7=128
        float samplef2 = music2[i] / 128.0f;


        float mixed = samplef1 + samplef2;
        // reduce the volume a bit:
        mixed *= 0.8;
        // hard clipping
        if (mixed > 1.0f) mixed = 1.0f;

        if (mixed < -1.0f) mixed = -1.0f;

        byte outputSample = (byte)(mixed * 128.0f);
        output[i] = outputSample;

    }   //for loop
    audioTrack.write(output, 0, output.length);

}
于 2013-02-27T21:53:59.020 に答える