gpt4 book ai didi

android - AudioTrack 的意外声音输出

转载 作者:行者123 更新时间:2023-11-29 21:09:47 25 4
gpt4 key购买 nike

我正在尝试播放连续的正弦波流。当我按住按钮时,正弦波的频率会发生变化。一旦我松开按钮,它就会恢复正常频率。

当我运行以下代码时,输​​出声音会定期出现“咔嗒声”(尖锐的声压变化)——每秒大约 5 次咔嗒声——而不是播放纯正弦音调。

一个有趣的行为是,当我按住 C5 按钮时没有点击。但是当我按住 C4 按钮时,咔嗒声仍然存在。

这个问题的原因是什么?

public class MainActivity extends Activity {
Thread t;
private Button buttonC4, buttonC5;

float buttonC4_val = 0;
float buttonC5_val = 0;

int sr = 44100;
boolean isRunning = true;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// button initialization
buttonC4 = (Button) this.findViewById(R.id.button_c4);
buttonC5 = (Button) this.findViewById(R.id.button_c5);

buttonC4.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
//insert code here
buttonC4_val = 300;
buttonC4.setText("You Clicked ME!!!");
return true;
case MotionEvent.ACTION_UP:
//insert code here
buttonC4_val = 0;
buttonC4.setText("C4");
return true;
}
return false;
}
});

buttonC5.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
//insert code here
buttonC5_val = 500;
buttonC5.setText("You Clicked ME!!!");
return true;
case MotionEvent.ACTION_UP:
//insert code here
buttonC5_val = 0;
buttonC5.setText("C5");
return true;
}
return false;
}
});

t = new Thread() {
public void run() {
setPriority(Thread.MAX_PRIORITY);

int bufferSize = AudioTrack.getMinBufferSize(sr,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);

AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sr,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize,
AudioTrack.MODE_STREAM);

audioTrack.play();

// synthesis loop
while(isRunning){
double upFreq = (double) buttonC4_val + (double) buttonC5_val;
short samples[] = new short[bufferSize];
int amp = 10000;
double twopi = 8.*Math.atan(1.);
double fr = 440.f;
double ph = 0.0;
fr = 440 + upFreq;

for(int i=0; i < bufferSize; i++){
samples[i] = (short) (amp*Math.sin(ph));
ph += twopi*fr/sr;
}

audioTrack.write(samples, 0, bufferSize);
}
audioTrack.stop();
audioTrack.release();
}
};
t.start();
}
}

最佳答案

看起来您正在用正弦波填充整个 samples 缓冲区 - 如果 bufferSize 不是您生成的频率的倍数,那么您当下一个样本开始播放时,我们将部分通过波浪 - 这可能是导致流行音乐的原因。

Amazing diagram

您可以通过更改 bufferSize 来测试它并查看它是否改变了弹出频率。更大的缓冲区应该意味着这些样本不匹配发生的频率更低,因此弹出的频率应该更低。

解决办法是改变

audioTrack.write(samples, 0, bufferSize);

bufferSize 替换为缓冲区中最后一个 0 交叉点的位置。

关于android - AudioTrack 的意外声音输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23329487/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com