編集:コードとプレーヤー(Github上)を少し整理して、頻度を設定しやすくしました
Karplus Strong 弦合成アルゴリズムを使用して弦を合成しようとしていますが、弦を正しくチューニングできません。誰にもアイデアはありますか?
上記のリンクのように、コードは Github にあります: https://github.com/achalddave/Audio-API-Frequency-Generator (関連するビットは にありますstrings.js
)。
Wiki には次の図があります。
基本的に、私はノイズを生成し、それが出力され、同時に遅延フィルターに送られます。遅延フィルタはローパス フィルタに接続され、出力と混合されます。ウィキペディアによると、遅延は N サンプルである必要があります。ここで、N はサンプリング周波数を基本周波数で割ったものです ( N = f_s/f_0
)。
私のコードからの抜粋:
ノイズの生成 ( bufferSize
2048 ですが、それほど重要ではありません)
var buffer = context.createBuffer(1, bufferSize, context.sampleRate);
var bufferSource = context.createBufferSource();
bufferSource.buffer = buffer;
var bufferData = buffer.getChannelData(0);
for (var i = 0; i < delaySamples+1; i++) {
bufferData[i] = 2*(Math.random()-0.5); // random noise from -1 to 1
}
遅延ノードを作成する
var delayNode = context.createDelayNode();
f_s/f_0
サンプル分遅延する必要があります。ただし、遅延ノードは遅延を秒単位で取るため、それを 1 秒あたりのサンプル数で割る必要があり(f_s/f_0) / f_s
ます1/f_0
。
var delaySeconds = 1/(frequency);
delayNode.delayTime.value = delaySeconds;
ローパス フィルターを作成します (私が知る限り、周波数カットオフは周波数に影響を与えるべきではなく、文字列が自然に聞こえるかどうかの問題です):
var lowpassFilter = context.createBiquadFilter();
lowpassFilter.type = lowpassFilter.LOWPASS; // explicitly set type
lowpassFilter.frequency.value = 20000; // make things sound better
ノイズを出力と遅延ノードに接続します (destination = context.destination
と は前に定義されています)。
bufferSource.connect(destination);
bufferSource.connect(delayNode);
遅延をローパス フィルターに接続します。
delayNode.connect(lowpassFilter);
ローパスを出力に接続し、遅延に戻します*:
lowpassFilter.connect(destination);
lowpassFilter.connect(delayNode);
誰にもアイデアはありますか?問題が自分のコードなのか、アルゴリズムの解釈なのか、API の理解なのか、(可能性は低いですが) API 自体の問題なのか、わかりません。
*Github では、実際にはローパスと出力の間に Gain Node がありますが、実際には出力に大きな違いはありません。