Android - AudioTrack setStereoVolume() 不工作

标签 android audio android-emulator

我有一个类使用 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;
    }
}

最佳答案

我注意到了同样的问题。 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,它开始正常工作。看起来像 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;
     }
     ...
}

关于Android - AudioTrack setStereoVolume() 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10462364/

相关文章:

android - Fragment UI 使用抽屉导航

c++ - Qt和声音处理

android - 警告 : no dns servers found

android - CORS + Android Webview,不适用于设备(​​但适用于模拟器)

java - 无法将带有类型参数的 Java 类重写为 Kotlin

android - NotificationListenerService 获取通知图标?

android - 在抽屉导航中切换 fragment 时短黑闪烁

iphone - OpenAL 初始化问题,仅限 iPod(?)

android - Android Mediaplayer不会停止

android - 在模拟器中更改电话号码 - Android 开发