你假設有相同的正弦波產生的每一次,但因爲有使用phase
變量和正弦波並不總是完全適合在緩衝區中,在每次迭代中產生不同的正弦波,稍微偏移一點。
每次都不會產生正弦波會導致正弦波中斷。
我會用鋸齒波而不是正弦波嘗試一些可視化。想象的緩衝區大小爲16和波值範圍從A到H.
// Old way
phase = 0 phase = 2 phase = 4
ABCDEFGHGFEDCBAB|CDEFGHGFEDCBABCD|EFGHGFEDCBABCDEF....
// New way
phase = 0 phase = 0 phase = 0
ABCDEFGHGFEDCBAB|ABCDEFGHGFEDCBAB|ABCDEFGHGFEDCBAB....
注意,有僅圍繞緩衝器的邊緣,其中的聲音是「畸形」(例如AB|AB
代替AB|CD
)小片。這就是爲什麼大多數時候它聽起來正確,在兩次之間出現一些令人不安的短暫「點擊」。
對於一些極少數情況,如果緩衝區長度是波長的倍數或phase
與以前的迭代值具有相同的值,那麼您可能確實會跳過生成緩衝區,但無法每次都這樣做。
編輯:看generate_sine功能怎麼看phase
改變:
static void generate_sine(const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset,
int count, double *_phase)
{
static double max_phase = 2. * M_PI;
double phase = *_phase;
double step = max_phase*freq/(double)rate;
[...]
phase += step;
if (phase >= max_phase)
phase -= max_phase;
}
*_phase = phase;
}
EDIT2:此圖片可能是一個更好/更清晰的可視化:
你也許可以使用HTTP ://codegolf.stackexchange.com/questions/951/print-triangle-wave-of-numbers更好的例子:) – ninjalj 2011-05-07 11:29:54
@ninjalj:謝謝,但我現在決定添加一個圖像。更好的是一個交互式小程序,你可以改變緩衝區長度並聽聲音,但我想這是過度的:) – schnaader 2011-05-07 11:47:03
謝謝你們的幫助。我剛剛開始看到緩衝區長度結束時的相位值是關鍵因素。然後基於您的確認,我應該能夠創建一個單獨的緩衝區,通過確保緩衝區的開始和結束時該階段始終爲0,可以連續重播。 – 2011-05-07 12:40:38