【问题标题】:Android Audiotrack clicks before and after soundAndroid Audiotrack 在声音前后点击
【发布时间】:2016-04-14 13:46:42
【问题描述】:

我正在使合成器能够生成三种基本类型的声音,并且当我播放声音时,在它完成播放之前和之后会发生点击。而且我不知道为什么。

发生在每种类型的声音中.. 正弦最响亮。

这是我用来生成声音的代码

int amp = 32767;
double phase = 0.0;

protected void onCreate(Bundle savedInstanceState) {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        AudioManager myAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        String nativeParam = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
        sampleRate = Integer.parseInt(nativeParam);
        nativeParam = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
        bufSize = Integer.parseInt(nativeParam);
    }
    else {
        sampleRate = 44100;
        bufSize = AudioTrack.getMinBufferSize(sampleRate,
                AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
    }

    audioOutput = new AudioOutput();
    audioOutput.Start(sampleRate, bufSize);

    samples = new short[bufSize];    // buffer size is 512

    playTask.execute();
}

class PlayTask extends AsyncTask<Object, Void, Void> {
    @Override
    protected Void doInBackground(Object[] params) {
        android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);

        while (!this.isCancelled()) {
            while (touched) {
                generateTone();
                audioOutput.write(samples, 0, samples.length);
            }
        }
        return null;
    }
}

private void generateTone() {
    double phaseIncrement = (2 * Math.PI) / sampleRate;
    switch (currentShape) {
        case SINE:
            for (int i = 0; i < bufSize; i++) {
                samples[i] = (short) (amp * Math.sin(phase));
                phase += phaseIncrement * freq;
                if (phase > 2 * Math.PI)
                    phase -= 2 * Math.PI;
            }
            break;
        case SAWTOOTH:
            for (int i = 0; i < bufSize; i++) {
                samples[i] = (short) (amp * (phase - amp));
                phase += phaseIncrement * freq;
                if (phase > 2 * Math.PI)
                    phase -= 2 * Math.PI;
            }
            break;
        case SQUARE:
            for (int i = 0; i < bufSize; i++) {
                if (phase < Math.PI)
                    samples[i] = (short) amp;
                else
                    samples[i] = (short) -amp;
                phase += phaseIncrement * freq;
                if (phase > 2 * Math.PI)
                    phase -= 2 * Math.PI;
            }
            break;
    }
}

public class AudioOutput {
    private AudioTrack mAudioTrack;
    private int mFrameRate;

    public void Start(int sampleRate, int bufferSize) {
        Stop();
        mFrameRate = sampleRate;
        mAudioTrack = createAudioTrack(bufferSize);

        mAudioTrack.play();
    }

    private AudioTrack createAudioTrack(int buffsize) {
        return new AudioTrack(AudioManager.STREAM_MUSIC,
                mFrameRate, AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT, buffsize,
                AudioTrack.MODE_STREAM);
    }

    public int write(short[] buffer, int offset, int length) {
        return write = mAudioTrack.write(buffer, offset, length);
    }

    public void Stop() {
        if (mAudioTrack != null) {
            mAudioTrack.stop();
            mAudioTrack.release();
            mAudioTrack = null;
        }
    }
}

音频示例:https://soundcloud.com/syntey/sinewavetest

有人知道哪里有问题吗?

谢谢

【问题讨论】:

  • 你能给个实际波形文件的链接吗?我认为看它比听它可以收集到更多信息。
  • 您是否在未列出的代码中的任何位置进行淡入/淡出?生成的信号显然具有某种包络。正弦也有很多失真。
  • 不,每个生成声音的代码都在这篇文章中
  • 淡化可能来自麦克风录音,我打印了缓冲区内容,没关系。那个结局是唯一困扰我的事情

标签: android audio signal-processing audiotrack


【解决方案1】:

您不会在零交叉处开始和结束每个缓冲区。每个缓冲器开始处的随机相位可能会在第一个样本中产生太尖锐的上升时间瞬变。将第一个和最后几十个样本从零到零逐渐变细(升余弦锥)也可能会有所帮助。

【讨论】:

  • 我将重置阶段修复为 0,但我无法弄清楚这一点。你知道一些逐渐变细的编程例子吗?我试图找到一些东西,但什么也没有……谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 2012-10-11
  • 2012-08-29
  • 2013-09-09
  • 1970-01-01
  • 2013-08-29
  • 1970-01-01
相关资源
最近更新 更多