Web Audio ile ilgili SSS

Boris Smus

Son birkaç ay içinde WebKit Web Audio API, web'deki oyunlar ve ses uygulamaları için ilgi çekici bir platform haline geldi. Geliştiriciler bu araçla tanıştıkça benzer soruların tekrar tekrar gündeme geldiğini duyuyorum. Bu kısa güncelleme, Web Audio API ile ilgili deneyiminizi daha keyifli hale getirmek için sık sorulan sorulardan bazılarını yanıtlama amaçlıdır.

S: Yardım, ses çıkaramıyorum.

C: Web Audio API'de yeniyseniz başlangıç eğitimine veya Eric'in kullanıcı etkileşimine dayalı ses çalma tarifine göz atın.

S. Kaç ses bağlamı kullanmalıyım?

C: Genellikle sayfa başına bir AudioContext eklemeniz gerekir. Tek bir ses bağlamı, kendisine bağlı birçok düğümü destekleyebilir. Tek bir sayfaya birden fazla AudioContext ekleyebilirsiniz ancak bu, performans kaybına neden olabilir.

S: noteOn() ile oynattığım bir AudioBufferSourceNode'um var. Tekrar oynatmak istiyorum ancak noteOn() hiçbir şey yapmıyor. Yardıma ihtiyacım var.

C: Bir kaynak düğüm oynatmayı bitirdikten sonra daha fazla oynatamaz. Temel arabelleği tekrar oynatmak için yeni bir AudioBufferSourceNode oluşturmanız ve noteOn() işlevini çağırmanız gerekir.

Kaynak düğümünü yeniden oluşturmak verimsiz görünse de kaynak düğümleri bu kalıp için büyük ölçüde optimize edilmiştir. Ayrıca, AudioBuffer için bir tutamak tutarsanız aynı sesi tekrar çalmak için öğeye başka bir istek göndermeniz gerekmez. Bu kalıbı tekrarlamanız gerekiyorsa oynatmayı playSound(buffer) gibi basit bir yardımcı işlevle kapsülleyin.

S: Bir sesi oynatırken neden her seferinde yeni bir kaynak düğümü oluşturmanız gerekir?

C: Bu mimarinin amacı, ses öğesini oynatma durumundan ayırmaktır. Pikap benzetmesini kullanırsak arabellekler plaklara, kaynaklar ise oynatma kafalarına benzer. Birçok uygulamada aynı arabelleğin birden fazla sürümü aynı anda oynatıldığı için bu kalıp gereklidir.

S: audio ve video etiketlerindeki sesleri nasıl işleyebilirim?

C: MediaElementAudioSourceNode üzerinde çalışıyoruz. Bu özellik kullanıma sunulduğunda, yaklaşık olarak aşağıdaki gibi çalışır (ses etiketi aracılığıyla çalınan bir kesit için filtre efekti ekler):

<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);

Bu özellik bu crbug üzerinden takip edilmektedir. Bu kurulumda mediaSourceNode.noteOn() çağrısına gerek olmadığını, ses etiketinin oynatmayı kontrol ettiğini unutmayın.

S: Mikrofondan ne zaman ses alabilirim?

C: Bunun ses girişi kısmı, getUserMedia kullanılarak WebRTC'nin bir parçası olarak uygulanacak ve Web Audio API'de özel bir kaynak düğümü olarak kullanılabilecektir. createMediaElementSource ile birlikte çalışır.

S: Bir AudioSourceNode'ün oynatılmasının ne zaman sona erdiğini nasıl kontrol edebilirim?

C: Web Audio API bu işlevi desteklemediğinden şu anda JavaScript zamanlayıcı kullanmanız gerekiyor. Web Audio API'yi kullanmaya başlama konulu eğitimdeki aşağıdaki snippet, bu işlemin nasıl yapıldığına dair bir örnektir:

// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
    console.log('playback finished');
}, buffer.duration * 1000);

Web Audio API'nin daha doğru bir geri çağırma işlevi uygulaması için açık bir hata vardır.

S: Yükleme sesleri, kullanıcı arayüzü iş parçacığının tamamının kilitlenmesine neden oluyor ve kullanıcı arayüzüm yanıt vermiyor. Yardım edin!**

C: Ana iş parçacığının engellenmesini önlemek için eşzamansız yükleme için decodeAudioData API'yi kullanın. Bu örneği inceleyin.

S: Web Audio API, sesleri gerçek zamanlıdan daha hızlı işlemek için kullanılabilir mi?

C: Evet, çözüm üzerinde çalışılıyor. Lütfen bizi takip etmeye devam edin!

S: Harika bir Web Audio API uygulaması oluşturdum ancak çalıştığı sekme arka plana geçtiğinde sesler garip bir hal alıyor.

C: Bunun nedeni muhtemelen sayfa arka planda olduğunda farklı davranan setTimeouts kullanmanızdır. Gelecekte Web Audio API, web sesinin dahili zamanlayıcısını (context.currentTime özelliği) kullanarak belirli zamanlarda geri çağırma yapabilecek. Daha fazla bilgi için lütfen bu özellik isteğini inceleyin.

Genel olarak, uygulamanız arka plana gittiğinde oynatmayı durdurmak iyi bir fikir olabilir. Sayfa Görünürlüğü API'sini kullanarak bir sayfanın arka plana ne zaman gittiğini algılayabilirsiniz.

S: Web Audio API'yi kullanarak bir sesin perdesini nasıl değiştirebilirim?

C: Kaynak düğümdeki playbackRate değerini değiştirin.

S: Hızı değiştirmeden perdeyi değiştirebilir miyim?

C: Web Audio API'de ses bağlamında bir PitchNode olabilir ancak bunun uygulanması zordur. Bunun nedeni, ses topluluğunda düz bir perde değiştirme algoritmasının olmamasıdır. Bilinen teknikler, özellikle perde kaymasının büyük olduğu durumlarda yapaylık oluşturur. Bu sorunu çözmek için iki tür yaklaşım vardır:

  • Tekrarlanan segment yankı yapılarına neden olan zaman alanı algoritmaları.
  • Yankılı ses kusurlarına neden olan frekans alanı teknikleri.

Bu teknikleri uygulamak için yerel bir düğüm olmasa da JavaScriptAudioNode ile yapabilirsiniz. Bu kod snippet'i başlangıç noktası olarak kullanılabilir.

S: İstediğim örnekleme hızında bir AudioContext nasıl oluşturabilirim?

C: Şu anda bu özellik için destek sunulmamaktadır ancak konuyla ilgili çalışmalarımız devam etmektedir. Bu özellik isteğine bakın.

Başka sorularınız varsa web-audio etiketini kullanarak StackOverflow'da sorabilirsiniz.