VCO*_*ODE 5 audio android 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;
}
}
Run Code Online (Sandbox Code Playgroud)
我注意到同样的问题。setStereoVolume
可以在 Android 4.3 模拟器上运行,但不能在 Android 4.0.3 设备上运行。
我调查了 Android 4.0.3 AudioTrack.java 源代码,发现如果我setStereoVolume
在调用 AudioTrack 之前调用,则ERROR_INVALID_OPERATION
由于 mState 值无效而无法返回。
public int setStereoVolume(float leftVolume, float rightVolume) {
if (mState != STATE_INITIALIZED) {
return ERROR_INVALID_OPERATION;
}
...
}
Run Code Online (Sandbox Code Playgroud)
然后我改变了通话顺序并在通话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;
}
...
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4190 次 |
最近记录: |