Web Ses API'sı: Kod Yazabildiğiniz Zaman Neden Oluşturun?

Yayınlanan: 2022-03-11

Web ses API'sinin ilk taslağı 2011 yılında W3C'de ortaya çıktı. Web sayfalarındaki ses uzun süredir destekleniyor olsa da, web tarayıcısından ses üretmenin uygun bir yolu oldukça yakın zamana kadar mevcut değildi. Bunu kişisel olarak Google Chrome'a ​​bağlıyorum, çünkü Google'ın ilgisine gelince, tarayıcı bilgisayarın en önemli parçası olmaya başladı. Hatırlarsınız, web tarayıcısı alanı Google Chrome ortaya çıkana kadar pek değişmeye başlamamıştı. Bu süre içinde bir web sayfasında ses kullanmış olsaydınız, bu kötü bir tasarım kararı olurdu. Ancak web deneyleri fikri ortaya çıktığından, web sesi yeniden anlam kazanmaya başladı. Web tarayıcıları günümüzde sanatsal ifade için başka bir araçtır ve web tarayıcısındaki video ve ses bunda hayati bir rol oynar.

Web Ses API'sı: Kod Yazabildiğiniz Zaman Neden Oluşturun?

Web Ses API'sı: Kod Yazabildiğiniz Zaman Neden Oluşturun?
Cıvıldamak

Web Ses API'sı hala geliştirme aşamasında olduğundan bazı amaçlar için kullanmak oldukça zor olabilir, ancak işleri kolaylaştırmak için bir dizi JavaScript kitaplığı zaten mevcut. Bu durumda size Tone.js adlı bir kitaplık kullanarak Web Audio API'sine nasıl başlayacağınızı göstereceğim. Bununla, tarayıcınızın ses ihtiyaçlarının çoğunu yalnızca temel bilgileri öğrenerek karşılayabileceksiniz.

Merhaba Web Ses API'sı

Başlarken

Kütüphaneyi kullanmadan başlayacağız. İlk denememiz üç sinüs dalgası yapmayı içerecek. Bu basit bir örnek olacağı için, merhaba.html adında sadece bir dosya oluşturacağız, az miktarda işaretleme içeren çıplak bir HTML dosyası.

 <!DOCTYPE html> <html> <head> <meta charset="utf‐8"> <title> Hello web audio </title> </head> <body> </body> <script> </script> </html>

Web Ses API'sinin özü, ses bağlamıdır. Ses bağlamı, web sesiyle ilgili her şeyi içerecek bir nesnedir. Tek bir projede birden fazla ses içeriğine sahip olmak iyi bir uygulama olarak kabul edilmez. Mozilla'nın Web Audio API belgelerinde verilen önerileri izleyerek bir ses bağlamı başlatarak başlayacağız.

 var audioCtx = new (window.AudioContext || window.webkitAudioContext);

Osilatör Yapmak

Bir ses bağlamı somutlaştırıldığında, zaten bir ses bileşeniniz var: audioCtx.destination. Bu sizin hoparlörünüz gibidir. Ses çıkarmak için onu audioCtx.destination'a bağlamanız gerekir. Şimdi biraz ses üretmek için bir osilatör oluşturalım:

 var sine = audioCtx.createOscillator();

Harika, ama yeterli değil. Ayrıca başlatılması ve audioCtx.destination'ımıza bağlanması gerekir:

 sine.start(); sine.connect(audioCtx.destination);

Bu dört satırla, sinüs sesi çıkaran oldukça can sıkıcı bir web sayfanız olacak, ancak şimdi modüllerin birbirleriyle nasıl bağlantı kurabileceğini anlıyorsunuz. Aşağıdaki komut dosyasında, her biri farklı bir tona sahip çıkışa bağlı üç sinüs şeklinde ton olacaktır. Kod çok açıklayıcı:

 //create the context for the web audio var audioCtx = new (window.AudioContext || window.webkitAudioContext)(); //create, tune, start and connect each oscillator sinea, sineb and sinec var sinea = audioCtx.createOscillator(); sinea.frequency.value = 440; sinea.type = "sine"; sinea.start(); sinea.connect(audioCtx.destination); var sineb = audioCtx.createOscillator(); sineb.frequency.value = 523.25; sineb.type = "sine"; sineb.start(); sineb.connect(audioCtx.destination); var sinec = audioCtx.createOscillator(); sinec.frequency.value = 698.46; sinec.type = "sine"; sinec.start(); sinec.connect(audioCtx.destination);

Osilatörler sinüs dalgaları ile sınırlı değildir, aynı zamanda MDN'de belirtildiği gibi üçgen, testere dişi, kare ve özel şekilli olabilir.

Web Sesinin Yama Mantığını

Ardından, Web Audio bileşenleri orkestramıza bir kazanç modülü ekleyeceğiz. Bu modül, seslerimizin genliğini değiştirmemizi sağlar. Bir ses düğmesine benzer. Ses çıkışına bir osilatör bağlamak için bağlantı işlevini zaten kullandık. Herhangi bir ses bileşenini bağlamak için aynı bağlantı işlevini kullanabiliriz. Firefox kullanıyorsanız ve web ses konsoluna bakarsanız, aşağıdakileri görürsünüz:

Sesi değiştirmek istiyorsak, yamamız şöyle görünmelidir:

Bu, osilatörlerin artık ses hedefine değil, bunun yerine bir Kazanç modülüne bağlı olduğu ve bu kazanç modülünün hedefe bağlı olduğu anlamına gelir. Bunu her zaman gitar pedalları ve kablolarla yaptığınızı hayal etmek güzel. Kod şöyle görünecek:

 var audioCtx = new (window.AudioContext || window.webkitAudioContext) // we create the gain module, named as volume, and connect it to our var volume = audioCtx.createGain(); volume.connect(audioCtx.destination); //these sines are the same, exept for the last connect statement. //Now they are connected to the volume gain module and not to the au var sinea = audioCtx.createOscillator(); sinea.frequency.value = 440; sinea.type = "sine"; sinea.start(); sinea.connect(volume); var sineb = audioCtx.createOscillator(); sineb.frequency.value = 523.25; sineb.type = "sine"; sineb.start(); sineb.connect(volume); var sinec = audioCtx.createOscillator(); sinec.frequency.value = 698.46; sinec.type = "sine"; sinec.start(); sinec.connect(volume); volume.gain.value=0.2;

Çözümü https://github.com/autotel/simple-webaudioapi/ adresinde bulabilirsiniz.

GainNode en temel efekt birimidir, ancak aynı zamanda bir gecikme, bir konvolver, bir bikuadratik filtre, bir stereo panner, bir dalga şekillendirici ve diğerleri de vardır. Tone.js gibi kitaplıklardan yeni efektler alabilirsiniz.

Bu ses yamalarından birini kendi nesnelerinde saklamak, onları gerektiği gibi yeniden kullanmanıza ve daha az kodla daha karmaşık orkestrasyonlar oluşturmanıza olanak tanır. Bu, gelecekteki bir yazı için bir konu olabilir.

Tone.js ile İşleri Kolaylaştırma

Vanilya Web Audio modüllerinin nasıl çalıştığına kısaca göz attığımıza göre, şimdi harika Web Audio çerçevesine bir göz atalım: Tone.js. Bununla (ve kullanıcı arabirimi bileşenleri için NexusUI), daha ilginç sentezler ve sesler kolayca oluşturabiliriz. Bir şeyleri denemek için, bir örnekleyici yapalım ve ona bazı kullanıcı etkileşimli efektler uygulayalım ve sonra bu örnek için bazı basit kontroller ekleyeceğiz.

Tone.js Örnekleyici

Basit bir proje yapısı oluşturarak başlayabiliriz:

 simpleSampler |-- js |-- nexusUI.js |-- Tone.js |-- noisecollector_hit4.wav |-- sampler.html

JavaScript kitaplıklarımız js dizininde bulunacaktır. Bu demonun amaçları için, NoiseCollector'ın Freesound.org'dan indirilebilen hit4.wav dosyasını kullanabiliriz.

Tone.js, işlevlerini Player nesneleri aracılığıyla sağlar. Nesnenin temel yeteneği, bir sample yüklemek ve onu bir döngüde veya bir kez oynatmak. Buradaki ilk adımımız, sampler.html dosyasının içinde bir "sampler" değişkeninde bir oynatıcı nesnesi oluşturmaktır:

 <!doctype html> <html> <head> <title> Sampler </title> <script type="text/javascript" src="js/nexusUI.js" ></script> <script type="text/javascript" src="js/Tone.js" ></script> <script> var sampler = new Tone.Player("noisecollector_hit4.wav", function() { console.log("samples loaded"); }); </script> </head> <body> </body> </html>

Player yapıcısının ilk parametresinin WAV dosyasının adı olduğunu ve ikincisinin bir geri arama işlevi olduğunu unutmayın. WAV, desteklenen tek dosya türü değildir ve uyumluluk, kitaplıktan çok web tarayıcısına bağlıdır. Geri arama işlevi, oynatıcı numuneyi arabelleğine yüklemeyi bitirdiğinde çalışacaktır.

Ayrıca örnekleyicimizi çıkışa bağlamamız gerekiyor. Bunu yapmanın Tone.js yolu:

 sampler.toMaster();

… burada örnekleyici bir Tone.Player nesnesidir, 10. satırdan sonra. toMaster işlevi connect(Tone.Master) için kısayoldur.

Web tarayıcınızı geliştirici konsolu açıkken açarsanız, oynatıcının doğru şekilde oluşturulduğunu belirten “örnekler yüklendi” mesajını görmelisiniz. Bu noktada örneği dinlemek isteyebilirsiniz. Bunu yapmak için, web sayfasına bir düğme eklememiz ve bir kez basıldığında sample'ı oynatmak için programlamamız gerekiyor. Gövdede bir NexusUI düğmesi kullanacağız:

 <canvas nx="button"></canvas>

Şimdi, belgede işlenen yuvarlak bir düğme görmelisiniz. Örneğimizi oynatmak üzere programlamak için şuna benzeyen bir NexusUI dinleyicisi ekleriz:

 button1.on('*',function(data) { console.log("button pressed!"); })

NexusUI ile ilgili göze çarpan bir şey, her NexusUI öğesi için global bir değişken oluşturmasıdır. NexusUI'yi bunu yapmayacak şekilde ayarlayabilir ve bunun yerine nx.globalWidgets öğesini false olarak ayarlayarak bu değişkenleri yalnızca nx.widgets[] içinde bulundurabilirsiniz. Burada sadece birkaç eleman oluşturacağız, bu yüzden bu davranışa bağlı kalacağız.

Aynı jQuery'deki gibi, bu .on olaylarını koyabiliriz ve ilk argüman olay adı olacaktır. Burada sadece butona yapılan her şeye bir fonksiyon atıyoruz. Bu ne olursa olsun “*” olarak yazılır. NexusUI API'deki her bir öğe için olaylar hakkında daha fazla bilgi edinebilirsiniz. Butona bastığımızda mesajları loglamak yerine sample'ı oynatmak için sampler'ımızın start fonksiyonunu çalıştırmalıyız.

 nx.onload = function() { button1.on('*',function(data) { console.log("button pressed!"); sampler.start(); }); }

Ayrıca dinleyicinin bir onload geri aramasının içine girdiğine dikkat edin. NexusUI öğeleri tuvale çizilir ve nx onload işlevini çağırana kadar bunlara başvuramazsınız. Tıpkı jQuery'deki DOM öğelerinde yaptığınız gibi.

Olay, fare basılı tutulduğunda ve bırakıldığında tetiklenir. Sadece basıldığında tetiklenmesini istiyorsanız, event.press'in bire eşit olup olmadığını değerlendirmelisiniz.

Bununla, her basışta numuneyi çalan bir düğmeniz olmalıdır. sampler.retrigger'ı true olarak ayarlarsanız, sample'ı çalıp çalmadığına bakmaksızın oynatmanıza izin verir. Aksi takdirde, tekrar tetiklemek için numunenin bitmesini beklemeniz gerekir.

Efektleri Uygulamak

Tone.js ile kolayca bir gecikme oluşturabiliriz:

 var delay= new Tone.FeedbackDelay("16n",0.5).toMaster();

İlk argüman, burada gösterildiği gibi müzik notasında yazılabilen gecikme süresidir. İkincisi ise, orijinal ses ile onu etkileyen sesin karışımı anlamına gelen ıslak seviyedir. Gecikmeler için genellikle %100 ıslaklık istemezsiniz, çünkü gecikmeler orijinal sese göre ilginçtir ve ıslak tek başına ikisi birlikte çok çekici değildir.

Bir sonraki adım, örnekleyicimizi ana cihazdan çıkarmak ve gecikme yerine takmak. Örnekleyicinin master'a bağlı olduğu çizgide ince ayar yapın:

 sampler.connect(delay);

Şimdi düğmeyi tekrar deneyin ve farkı görün.

Ardından, belgemizin gövdesine iki kadran ekleyeceğiz:

 <canvas nx="dial"></canvas> <canvas nx="dial"></canvas>

Ve NexusUIlistener'ı kullanarak kadranların değerlerini gecikme efektine uygularız:

 dial1.on('*',function(data) { delay.delayTime.value=data.value; }) dial2.on('*',function(data) { delay.feedback.value=data.value; })

Her olayda ince ayar yapabileceğiniz parametreler Tone.js belgelerinde bulunabilir. Gecikme için, burada. Artık örneği denemeye ve NexusUI kadranlarıyla gecikme parametrelerini değiştirmeye hazırsınız. Bu işlem, yalnızca efektlerle sınırlı kalmayıp, her NexusUI öğesiyle kolayca yapılabilir. Örneğin, başka bir kadran eklemeyi ve dinleyicisini aşağıdaki gibi eklemeyi deneyin:

 dial3.on('*',function(data) { sampler.playbackRate=data.value; })

Bu dosyaları github.com/autotel/simpleSampler adresinde bulabilirsiniz.

Çözüm

Bu API'leri incelediğimde, aklıma gelmeye başlayan tüm olasılıklar ve fikirler karşısında bunalmış hissetmeye başladım. Bu ses uygulaması ile dijital sesin geleneksel uygulamaları arasındaki büyük fark, sesin kendisinde değil, bağlamdadır. Burada sentez yapmanın yeni yöntemleri yok. Daha ziyade yenilik, ses ve müzik yapımının artık web teknolojileriyle buluşmasıdır.

Kişisel olarak elektronik müzik yapımıyla ilgileniyorum ve bu alanda her zaman, gerçekten müzik icra etmek ile kaydedilmiş bir parçaya sadece çalmaya basmak arasındaki belirsizlik paradoksu vardı. Gerçekten canlı elektronik müzik yapmak istiyorsanız, canlı doğaçlama için kendi performatif araçlarınızı veya “müzik yapan robotları” yaratabilmelisiniz. Ancak elektronik müziğin performansı, önceden hazırlanmış müzik yapım algoritmalarında basitçe ince ayar parametreleri haline gelirse, seyirci de bu sürece dahil olabilir. Kitle kaynaklı müzik için bu web ve ses entegrasyonuyla ilgili küçük deneyler üzerinde çalışıyorum ve belki yakında müziğin izleyicilerden akıllı telefonları aracılığıyla geldiği partilere katılacağız. Ne de olsa mağara çağlarında keyifle dinlediğimiz ritmik sıkışmalardan pek de farklı değil.


Toptal Mühendislik Blogunda Daha Fazla Okuma:

  • WebAssembly/Pas Eğitimi: Mükemmel Ses İşleme
  • MIDI Eğitimi: MIDI Donanımı Tarafından Kontrol Edilen Tarayıcı Tabanlı Ses Uygulamaları Oluşturma