Edit: oczyścić kod i odtwarzacz (na Github) trochę tak, że łatwiej jest ustawić częstotliwośćWeb Audio: Synteza Karplus Strong String
jestem trying to synthesize ciągów za pomocą algorytmu z Karplus Strong string synthesis, ale mogę” t uzyskać ciąg, aby odpowiednio dostroić. Czy ktokolwiek ma jakiś pomysł?
Jak podano powyżej, kod znajduje się na Github: https://github.com/achalddave/Audio-API-Frequency-Generator (odpowiednie bity są w strings.js
).
Wiki ma następujący schemat:
Więc zasadniczo generować hałas, który następnie pobiera dane wyjściowe i wysłany do filtra opóźnienia jednocześnie. Filtr opóźniający jest podłączony do filtra dolnoprzepustowego, który następnie jest mieszany z wyjściem. Według Wikipedii opóźnienie powinno wynosić N próbek, gdzie N jest częstotliwością próbkowania podzieloną przez częstotliwość podstawową (N = f_s/f_0
).
Fragmenty z mojego kodu:
generowania hałasu (bufferSize
jest 2048, ale to nie powinno mieć znaczenia, zbyt dużo)
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
}
Utwórz węzeł opóźnienia
var delayNode = context.createDelayNode();
Czekamy opóźnić o f_s/f_0
próbek. Jednak węzeł opóźnienia przyjmuje opóźnienie w sekundach, więc musimy podzielić to przez próbki na sekundę, a otrzymamy (f_s/f_0)/f_s
, który jest tylko 1/f_0
.
var delaySeconds = 1/(frequency);
delayNode.delayTime.value = delaySeconds;
Utwórz filtr dolnoprzepustowy (odcięcia częstotliwości, o ile wiem, nie powinno mieć wpływu na częstotliwość i jest bardziej kwestia tego, czy ciąg „brzmi” naturalne):
var lowpassFilter = context.createBiquadFilter();
lowpassFilter.type = lowpassFilter.LOWPASS; // explicitly set type
lowpassFilter.frequency.value = 20000; // make things sound better
Połączyć szumu do produkcji i węzła opóźnienia (destination = context.destination
i zdefiniowano wcześniej)
bufferSource.connect(destination);
bufferSource.connect(delayNode);
połączyć opóźnienie do filtra dolnoprzepustowego:
delayNode.connect(lowpassFilter);
Podłączyć dolnoprzepustowy na wyjście i powrót do opóźnienia *:
lowpassFilter.connect(destination);
lowpassFilter.connect(delayNode);
Czy ktoś ma jakieś pomysły? Nie mogę się dowiedzieć, czy problemem jest mój kod, moja interpretacja algorytmu, moje zrozumienie API, czy (choć jest to najmniej prawdopodobne) problem z samym API.
* Należy pamiętać, że na Github, tam faktycznie węzeł Zysk między dolnoprzepustowy i wyjście, ale to naprawdę nie robi dużą różnicę w wydajności.
Po prostu bawiam się tym i naprawdę nie wiem, co robię. Ale spróbuj ustawić częstotliwość na 241. Na moim Macu, który tworzy dziwny hałas. Może to ci coś mówi? Wydajesz się dużo bardziej biegły w zakresie matematyki i teorii. :) –
Hm, to interesujące. Szczerze mówiąc, poza jednym kursem EE nie jestem zbyt obeznany z teorią, tak wiele z tego składa się razem i pyta. Dzięki za pomoc, to może dać trochę wglądu, jeśli zajrzę więcej. –
To prawdopodobnie nie jest problem, ponieważ myślę, że Lowpass jest domyślny, ale powinieneś prawdopodobnie ustawić swój typ filtra jawnie w kodzie ... coś jak 'lowpassFilter.type = lowpassFilter.LOWPASS'. –