2012-05-05 60 views
3

我有一個類使用AudioTrack來產生每個特定頻率的聲音。一切工作正常,但現在我想定製它,以便我只能在耳機的右側播放聲音,或者只在耳機的左側播放聲音。 (右,或左耳)Android - AudioTrack setStereoVolume()不工作

所以我發現AudioTrack有一個這樣的方法:setStereoVolume(),但是,當我配置它,例如像這樣:audioTrack.setStereoVolume(1.0f, 0.0f),我期待只有我的耳機左側聲音,右側應該靜音,但沒有效果。我可以在耳機的左右兩側聽到相同音量的聲音。

我檢查了setStreamVolume()的返回值,它是0,這與SUCCESS相等,但我仍然沒有聽到差異。

你知道它爲什麼不工作,或者我可以指定只在耳機的左側或右側播放聲音嗎?

下面是產生聲音的代碼:我已經注意到了同樣的問題

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,它將無法返回ERROR_INVALID_OPERATION,因爲mState值無效。

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; 
    } 
    ... 
}