5

我有一个类使用 AudioTrack 来生成每个特定频率的声音。一切正常,但现在我想对其进行自定义,以便我只能在耳机的右侧播放声音,或者只能在耳机的左侧播放。(右耳或左耳)

所以我发现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;
    }
}
4

1 回答 1

1

我注意到了同样的问题。setStereoVolume正在使用 Android 4.3 模拟器,但不适用于 Android 4.0.3 设备。

我调查了 Android 4.0.3 AudioTrack.java 源代码,发现如果我在为 AudioTrack 调用write 之前调用它,由于 mState 值无效setStereoVolume,它无法返回。ERROR_INVALID_OPERATION

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

然后我改变了通话顺序并在通话setStereoVolume后添加audioTrack.write,它开始正常工作。看起来 write 方法修改了 mState 值

public int write(byte[] audioData,int offsetInBytes, int sizeInBytes) {
     if ((mDataLoadMode == MODE_STATIC)
          && (mState == STATE_NO_STATIC_DATA)
          && (sizeInBytes > 0)) {
          mState = STATE_INITIALIZED;
     }
     ...
}
于 2014-05-01T09:12:14.247 回答