Web Audio ile ilgili SSS

Boris Smus

Geçtiğimiz birkaç ay içinde WebKit Web Audio API, web'deki oyunlar ve ses uygulamaları için ilgi çekici bir platform olarak ortaya çıktı. Geliştiriciler bu yeni teknolojiye aşina oldukça benzer sorular sormaya başladım. Bu hızlı güncelleme, Web Audio API deneyiminizi daha keyifli hale getirmek için sık sorulan sorulardan bazılarını ele alma girişimidir.

S: Yardım edelim, ses çıkaramıyorum!

Y: Web Audio API'sını kullanmaya yeni başladıysanız başlangıç eğiticisine veya Eren'in kullanıcı etkileşimine dayalı ses çalma tarifine göz atın.

S. Kaç ses bağlamına sahip olmalıyım?

Y: Genellikle, her sayfaya bir AudioContext eklemeniz gerekir ve tek bir ses bağlamı buna bağlı birçok düğümü destekleyebilir. Tek bir sayfaya birden çok AudioContexts ekleyebilirsiniz, ancak bu bir performans isabetine yol açabilir.

S: Elimde bir AudioBufferSourceNode var. Az önce noteOn() ile çaldım ve tekrar oynatmak istiyorum ama noteOn() hiçbir şey yapmıyor! Yardıma ihtiyacım var.

C: Kaynak düğümün oynatılması bittiğinde, daha fazla oynatılamaz. Temel arabelleği tekrar oynatmak için yeni bir AudioBufferSourceNode oluşturup noteOn() çağrısı yapmanız gerekir.

Kaynak düğümün yeniden oluşturulması verimsiz gibi görünse de kaynak düğümler bu kalıp için yoğun şekilde optimize edilmiştir. Ayrıca, AudioBuffer'ı kullanmaya devam ederseniz aynı sesi tekrar çalmak için öğeden başka bir istekte bulunmanız gerekmez. Bu kalıbı tekrarlamanız gerekirse playSound(buffer) gibi basit bir yardımcı işlevle oynatmayı özetleyin.

S: Ses çalarken neden her seferinde yeni bir kaynak düğüm oluşturmanız gerekir?

C: Bu mimarinin amacı, ses öğesini oynatma durumundan ayırmaktır. Plak oyuncusu benzetmesi yapacak olursak, tamponlar kayıt ve oyun kafalarının kullandığı kaynaklara benzer. Birçok uygulama, aynı tamponun birden fazla sürümünü eşzamanlı olarak oynattığından bu kalıp çok önemlidir.

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

C: MediaElementAudioSourceNode hazırlanıyor. Bu özellik, mevcut olduğunda genel hatlarıyla aşağıdaki gibi çalışır (ses etiketi aracılığıyla çalan bir örneğe filtre efekti eklenir):

<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 ek güncellemede takip edilir. Bu kurulumda mediaSourceNode.noteOn() işlevini çağırmanıza gerek yoktur, çalmayı ses etiketi kontrol eder.

S: Mikrofondan ne zaman ses alabilirim?

Y: Bunun ses girişi bölümü getUserMedia ile WebRTC'nin bir parçası olarak uygulanacak ve Web Audio API'sında özel bir kaynak düğüm olarak kullanılabilir. createMediaElementSource ile birlikte çalışır.

S: Bir AudioSourceNode oyununun oynamasının bittiğini nasıl kontrol edebilirim?

C: Web Audio API'sı bu işlevi desteklemediğinden şu anda bir JavaScript zamanlayıcısı kullanmanız gerekmektedir. Getting Started with Web Audio API eğiticisinde yer alan aşağıdaki snippet'te bunun için bir örnek verilmiştir:

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

Web Audio API'sının daha doğru bir geri çağırma uygulamasını sağlamak için açık bir hata vardır.

S: Seslerin yüklenmesi 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ıma ihtiyacım var.**

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

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

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

S: Harika bir Web Audio API uygulaması geliştirdim ama çalıştığı sekme arka plana gittiğinde sesler tuhaf geliyor!

C: Bunun nedeni büyük olasılıkla, sayfa arka plana alındığında 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ğine bakın.

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

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

Y: Kaynak düğümdeki playbackRate öğesini değiştirin.

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

Y: Web Audio API'sının ses bağlamında PitchNode'u olabilir, ancak bunun uygulanması zordur. Bunun nedeni, ses topluluğunda basit bir perde değiştirme algoritmasının olmamasıdır. Bilinen teknikler, özellikle perde kaymasının fazla olduğu durumlarda kusurlar oluşturur. Bu sorunla başa çıkmak için iki tür yaklaşım vardır:

  • Tekrarlanan segment yankısı yapılarına neden olan zaman alanı algoritmaları.
  • Yankı uyandıran ses yapılarına neden olan frekans alanı teknikleri.

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

S: Seçtiğim örnek hızında nasıl AudioContext oluşturabilirim?

C: Şu anda bu konu için herhangi bir destek sağlanmamaktadır, ancak konuyla ilgileniyoruz. Bu özellik isteğine bakın.

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