停止PCM样本导致单击

停止PCM样本导致单击,c,audio,wav,pcm,waveform,C,Audio,Wav,Pcm,Waveform,我正在从样本数组生成一个wav文件。我注意到,如果我开始然后停止复制波形,它会产生“咔嗒”的声音。这里有一个简单的例子,我周期性地复制一个正弦波,然后没有声音(44100 hz的16位有符号立体声pcm): int c,计数器=0; short*wavdat=malloc(numberOfSamples*2); 对于(c=0;c

我正在从样本数组生成一个wav文件。我注意到,如果我开始然后停止复制波形,它会产生“咔嗒”的声音。这里有一个简单的例子,我周期性地复制一个正弦波,然后没有声音(44100 hz的16位有符号立体声pcm):

int c,计数器=0;
short*wavdat=malloc(numberOfSamples*2);
对于(c=0;c
以下是audacity中的波形,放大到正弦波被切断的位置:

末端的尖刺似乎是我听到咔嗒声的原因。为什么这会导致咔嗒声而不是瞬间停止?我怎样才能在没有咔哒声的情况下停止声音?我需要在一个准确的时间停止复制样本,所以我不确定我是否可以将它们淡出

这个问题发生在我身上,即使波形复杂得多(比如停止语音剪辑)


如果有人感兴趣,这里是录制的声音文件:

在过零点停止采样。这将消除尖峰

PCM波形中的任何突然尖峰实际上都是咔嗒声


如果您事先知道要复制多少个样本,您可以提前开始淡出它们——0.05秒的线性截止斜率是一个很好的起点。

过零截断比峰值截断好得多,但它仍然会带来不必要的噪音。这似乎是避免点击的唯一方法。谢谢你有没有可能把所有的代码都传递出去?我很想看看整个wave文件是如何建立的。我自己没有写WAV写代码,我从一个简单的C++函数中得到的:好的,谢谢链接。
int c, counter = 0;
short *wavdat = malloc(numberOfSamples * 2);
for(c = 0; c < numberOfSamples * 2; c += 2){
    counter++;
    if(counter % 10000 < 5000){
        wavdat[c] = sinf(counter * .1f) * 16000;
        wavdat[c+1] = wavdat[c];
    }else{
        wavdat[c] = wavdat[c+1] = 0;
    }
}