Android - AudioTrack setStereoVolume () not working

I have a class that uses AudioTrack to generate sound at a specific frequency. Everything works fine, but now I want to tune it so that I can only play sound on the right side of the headphones or only on the left side of the headphones. (right or left ear)

So, I found that AudioTrack has this method: setStereoVolume() , however, when I configure it, for example, like this: audioTrack.setStereoVolume(1.0f, 0.0f) , I expect that only my left side of the headphones will sound, and the right side should be dumb, but it is ineffective. I hear sound at the same volume on the right and left side of the headphones.

I am checking the return value of setStreamVolume() and it is 0, which is SUCCESS, but I still don’t hear the difference.

Do you know why it does not work, or an alternative way, as I can point out, to play sound only on the left or right side of the headphones?

Here is the code that generates the sound:

 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
source share
1 answer

I noticed the same problem. setStereoVolume worked on an Android 4.3 emulator, but did not work on an Android 4.0.3 device.

I examined the source of Android 4.0.3 AudioTrack.java and found that if I call setStereoVolume before the record for AudioTrack is called, it does not work, returning ERROR_INVALID_OPERATION due to an invalid mState value.

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

Then I changed the call sequence and added setStereoVolume after calling audioTrack.write and it started working fine. It looks like the write method changes the value of mState

 public int write(byte[] audioData,int offsetInBytes, int sizeInBytes) { if ((mDataLoadMode == MODE_STATIC) && (mState == STATE_NO_STATIC_DATA) && (sizeInBytes > 0)) { mState = STATE_INITIALIZED; } ... } 
+1
source

Source: https://habr.com/ru/post/1410854/


All Articles