2013-01-23 10 views
11

this method (shown below)を使用してバイト配列にwavファイルを読み込んでいます。これでバイト配列内に格納されたので、音量を変更したいと思います。オーディオ:バイト配列のサンプルの音量を変更する

private byte[] getAudioFileData(final String filePath) { 
    byte[] data = null; 
    try { 
    final ByteArrayOutputStream baout = new ByteArrayOutputStream(); 
    final File file = new File(filePath); 
    final AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file); 

    byte[] buffer = new byte[4096]; 
    int c; 
    while ((c = audioInputStream.read(buffer, 0, buffer.length)) != -1) { 
     baout.write(buffer, 0, c); 
    } 
    audioInputStream.close(); 
    baout.close(); 
    data = baout.toByteArray(); 
    } catch (Exception e) { 
    e.printStackTrace(); 
    } 
    return data; 
} 

編集:要求ごとオーディオフォーマットに関するいくつかの情報:

PCM_SIGNED 44100.0ヘルツ、16ビット、モノラル、2バイト/フレーム、リトルエンディアン

から物理学のクラス正弦波の振幅を0と1の間の数で乗算することで正弦波の振幅を変えることができることを思い出しました。

編集:更新されたコードの16ビットサンプルのため:私はvolumeaudioSampleを掛けた場合、音が大きく歪んでいる

private byte[] adjustVolume(byte[] audioSamples, double volume) { 
    byte[] array = new byte[audioSamples.length]; 
    for (int i = 0; i < array.length; i+=2) { 
     // convert byte pair to int 
     int audioSample = (int) ((audioSamples[i+1] & 0xff) << 8) | (audioSamples[i] & 0xff); 

     audioSample = (int) (audioSample * volume); 

     // convert back 
     array[i] = (byte) audioSample; 
     array[i+1] = (byte) (audioSample >> 8); 

    } 
    return array; 
} 

。私がしていない場合、両方の配列をArrays.compare(array, audioSample)と比較すると、バイト配列がint型に正しく変換されていると結論づけることができます。

誰かが私を助けることができますか?私はここで何が間違っていますか?ありがとうございました! :)

+0

を.stackexchange.com – egrunin

+0

1)より良いヘルプを早く得るために、[SSCCE](http://sscce.org/)を投稿してください。 2) 'audioInputStream.getFormat()'を報告してください。 –

+0

@egruninありがとう!それをコピーして貼り付けたり、トピックを移動するためのルールは何ですか? – Macks

答えて

7

あなたは8ビットモノラルオーディオを読んでいますか?それ以外の場合、1バイトは1サンプルに等しくなく、各バイトを拡大/縮小できません。例えば。 16ビットデータの場合、すべてのバイトのペアを16ビット整数として解析し、それをスケーリングして2バイトとして書き戻す必要があります。

+1

ありがとうございます。私のオーディオのサンプルサイズは16ビットです。私はバイト配列を正しく変換する方法を読んで、私がそれをやり遂げたら私のフィードバックをお伝えします。 – Macks

+0

ねえ。 :)私は最終的に私のバイト配列をintとbackに正しく​​変換することができました。しかし、私の音に「音量」を掛ければ、私の音は以前よりずっとひどく歪んでいます。私は質問のコードを更新しました。あなたは見ていただけますか?それは素晴らしいだろう。ありがとうございました! :) – Macks

+1

ちょっと見てみましたが、負の値を正しく扱っていないと思われます(32ビットのint型に変換すると、 'short'を使用できますか?)。 javaの符号付き整数は2の補数であることに注意してください。 – johusman

1

1バイトが1サンプルであることを確認してください。この書式仕様では、サンプルが2つのバイトを持つように見えます。ヘッダーを変更しないようにすることを忘れないでください。

WAVE PCM soundfile format

+0

ありがとうございました。私は質問の中で私のコードを更新しましたが、それはまだ動作していません。 : – Macks

6

int型での問題は、Javaでint型のサイズは4バイトであり、サンプルサイズは2バイト

これは、コードに働いている:あなたは、DSP上で、より良い答えを得る可能性があります

private byte[] adjustVolume(byte[] audioSamples, float volume) { 
     byte[] array = new byte[audioSamples.length]; 
     for (int i = 0; i < array.length; i+=2) { 
      // convert byte pair to int 
      short buf1 = audioSamples[i+1]; 
      short buf2 = audioSamples[i]; 

      buf1 = (short) ((buf1 & 0xff) << 8); 
      buf2 = (short) (buf2 & 0xff); 

      short res= (short) (buf1 | buf2); 
      res = (short) (res * volume); 

      // convert back 
      array[i] = (byte) res; 
      array[i+1] = (byte) (res >> 8); 

     } 
     return array; 
} 
+0

ステレオ音量をコントロールすることも可能でしょうか? – nadous

+0

PCMが16ビットLLR LL RR LL RR LL(各文字は1バイト)であることを知ったらかなり簡単に4を増やして再利用しますあなたのコード。 – nadous

関連する問題