5

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

そのため、 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;
    }
}
4

1 に答える 1

1

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

Android 4.0.3 の AudioTrack.java ソースを調べたところ、setStereoVolumeAudioTrack の書き込みが呼び出される前に呼び出すERROR_INVALID_OPERATIONと、無効な mState 値のために返されないことがわかりました。

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

次に、呼び出しのシーケンスを変更setStereoVolumeし、呼び出しの後に追加するaudioTrack.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 に答える