2012-05-05 5 views
3

AudioTrackを使用して特定の周波数ごとにサウンドを生成するクラスがあります。すべてうまく動作しますが、ヘッドフォンの右側でのみ、またはヘッドフォンの左側でのみ再生できるようにカスタマイズしたいと考えています。 (右または左の耳)Android - AudioTrack setStereoVolume()が動作しない

私はAudioTrackにこのような方法があることを発見しました:setStereoVolume()しかし、これを設定すると、例えば:audioTrack.setStereoVolume(1.0f, 0.0f)のように、私はヘッドフォンの左側が鳴るはずです右側はミュートでなければなりませんが、それは不完全です。ヘッドフォンの左右の同じ音量で聞こえる。

戻り値がsetStreamVolume()であることを確認しています。これはSUCCESSと等しい0ですが、まだ違いはわかりません。

なぜ動作しないのか、ヘッドフォンの左右どちらかの音だけを再生するように指定する方法を知っていますか?

は、ここで音を生成するコードです:

public class SoundGenerator extends AsyncTask<Float, Void, Void> { 
    final int SAMPLE_RATE = 11025; 
    boolean playing=false; 

    @Override 
    protected Void doInBackground(Float... params) { 

     float frequency=params[0]; 

     int minSize = AudioTrack.getMinBufferSize(SAMPLE_RATE, 
       AudioFormat.CHANNEL_CONFIGURATION_STEREO, 
       AudioFormat.ENCODING_PCM_16BIT); 

     AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
       SAMPLE_RATE, AudioFormat.CHANNEL_CONFIGURATION_STEREO, 
       AudioFormat.ENCODING_PCM_16BIT, minSize, 
       AudioTrack.MODE_STREAM); 

     short[] buffer = new short[minSize]; 

     float angular_frequency = (float) (2 * Math.PI) * frequency/SAMPLE_RATE; 
     float angle = 0; 

     audioTrack.play(); 
     int stereo=audioTrack.setStereoVolume(1.0f, 0.0f); 

       Log.d("GREC", "Stereo vol: "+stereo); 


     while (playing) { 

      for (int i = 0; i < buffer.length; i++) { 
       buffer[i] = (short) (Short.MAX_VALUE * ((float) Math.sin(angle))); 
       angle += angular_frequency; 
      } 
      audioTrack.write(buffer, 0, buffer.length); 
     } 
     Log.d(Globals.TAG, "Stopping the tone generator..."); 
     audioTrack.stop(); 
     audioTrack.release(); 

     return null; 
    } 

    public void keepPlaying(boolean flag){ 
     playing=flag; 
    } 
} 
+1

私はこの問題を自分で見つけました。それはエミュレータでは動作しませんが、実際のデバイスで正常に動作したようです。 – VCODE

答えて

0

私は同じ問題を気づきました。 setStereoVolumeはAndroid 4.3エミュレータで動作していましたが、Android 4.0.3デバイスでは動作しませんでした。

私はAndroid 4.0.3 AudioTrack.javaソースを調査しましたが、AudioTrackの書き込みが呼び出される前にsetStereoVolumeを呼び出すと、無効なmState値のためERROR_INVALID_OPERATIONが返されます。

public int setStereoVolume(float leftVolume, float rightVolume) { 
     if (mState != STATE_INITIALIZED) { 
      return ERROR_INVALID_OPERATION; 
     } 
... 
} 

次に私が呼び出しのシーケンスを変更し、audioTrack.write呼び出しの後setStereoVolumeを追加し、それが正常に動作し始めました。書き込みメソッドがmState値を変更するように見える

public int write(byte[] audioData,int offsetInBytes, int sizeInBytes) { 
    if ((mDataLoadMode == MODE_STATIC) 
      && (mState == STATE_NO_STATIC_DATA) 
      && (sizeInBytes > 0)) { 
      mState = STATE_INITIALIZED; 
    } 
    ... 
} 
関連する問題