【问题标题】:Unexpected sound output from AudioTrack来自 AudioTrack 的意外声音输出
【发布时间】:2014-04-27 21:50:48
【问题描述】:

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

当我运行以下代码时,输​​出声音会定期发生“咔嗒声”(急剧的声压变化)——大约每秒 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();
}
}

【问题讨论】:

    标签: android audiotrack


    【解决方案1】:

    看起来您正在用正弦波填充整个 samples 缓冲区 - 如果 bufferSize 不是您生成的频率的倍数,那么当下一个样本开始播放 - 这可能是导致爆音的原因。

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

    解决办法是改变

    audioTrack.write(samples, 0, bufferSize);
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-08
      相关资源
      最近更新 更多