Arama Motoru

OpenAL İle 3D Ses Programlama

Platformdan bağımsız ses çevresinin yaratılması

08/06/2003
02/05/2010

Giriş

Ses kart ve API'lerinin kabiliyetlerinin yılar geçtikçe artmasıyla 3D ses oyunlarda gittikçe önemli bir rol oynar hale geldi. Oyunculara 3Boyut tecrübesini yaşatmak, güzel görünen grafiklerinin ötesine geçti. Doğru şekilde yapılan ortam ses ve müziği oyunları tamamen yeni bir seviyeye götürür. Bu etkiyi başarmak için,  Microsoft tarafından DirectSound ve DirectSound3D, Aureal tarafından A3D ve Creative Labs tarafından EAX gibi farklı ses programlama API'leri geliştirildi. Daha yakın zamanda, Loki ve Creative Labs OpenAL'i geliştirdi. Hangi isim cisimde olursa olsun geliştiricilere platformdan bağımsız API ile sesi kullanmaya imkan verecek bir standart oluşturma gayretiyle bu yapıldı. Bu makale, OpenAL'in temellerini ve projenize 3D sesi nasıl dahil edeceğinizi açıklayacak.
OpenAL, basitçe bir oyun ortamında ses ve müziği çalacak fonksiyonlar içeren bir ses kütüphanesidir. O programcıya sesleri diledikleri gibi yüklemesine Ve ses gelişimini belirleyen pozisyon, güç, yön,koni açısı gibi belirli karakteristikleri kontrol etmesine imkan verir. Bütün sesler, kullanıcının olduğu oyun evreninde geçerli yeri temsil eden listener'a(dinleyiciye) göreli olarak yerleştirilir. Yakındaki dinleyicinin(listener) bir sesi alması daha yüksek şiddette olur. OpenAL, müzik çalmak içinde kullanılabilir. OpenAL, arkada müziği aralıksız devamlı çalmak için streamlemeyi kullanabilir. OpenAL, DirectSound3D ve EAX'in kullanımını destekler. Herhangi ekstra programlama olmadan , kütüphanede bunların API'lerini kullanıma imkan veren fonksiyonlar vardır .
OpenAL'in DirectSound ve EAX ‘e göre  ana avantajı, OpenAL'in, platformdan bağımsız API olarak tasarlanmasıdır. Windows, Mac ve Linux binarylerini yüklemek mümkün olup, birçok işletim sisteminde kullanılabilir. DirectSound ve DirectSound3D, sadece Windows için tasarlandı ve EAX temelde DirectSound3D'un bir uzantısıdır. Birçok işletim sistemi için bir uygulama yaratmayı arzulayanlar için OpenAL uygun olabilir. Bu ders, size windows'da OpenAL'in  temel işlevlerini göstermek üzere tasarlandı. Burada gösterilen kod, yükleyebileceğiniz örnekte tümü bulunan demo uygulamasındandır. Demoda, OpenGL ve OpenAL'in arasında benzerliği göstermek için OpenGL kullanıldı.

Başlarken

Yapılacak ilk şey OpenAL SDK'i elde etmektir . Bu, geliştirici Creative Labs'ın http://developer.creative.com sitesinden elde edilebilir. SDK kurulduğu andan itibaren fonksiyonları kullanılmaya başlanabilir. İlkin oyun veya uygulamanızın başında OpenAL'i ilklemeye ihtiyaç duyarsınız. Uygulamamda ben DirectSound3D'u kullanmayı seçtim tabi aynı şekilde EAX'dan yararlanmakta mümkündür. İlkleme kodu şuna benzer:

ALCcontext *Context;
ALCdevice *Device;
Device = alcOpenDevice((ALubyte*)"DirectSound3D");
 
if (Device == NULL)
    exit(-1);
 
//Context’i(‘leri) yarat
Context=alcCreateContext(Device, NULL);
//aktif geçerli context olarak set et
alcMakeContextCurrent(Context);
// hata kodunu aydınlat
alGetError();

Seslerin Yüklenmesi

OpenAL'in ilklenmesiyle, bufferlar seslerle doldurulmaya başlanabilir. Birinci adım, alutLoadWAVFile fonksiyonunu kullanarak ses ile bir buffer'ı doldurmaktır. Buffer'ı doldurduktan sonra, bir source'ü ona bağlamaya ihtiyaç duyarsın. Bu source sonra sesi çalmak üzere kullanılacak. Bir sesi yükleyen kodlar şuna benzer:

char* alBuffer;            //buffer
ALenum alFormatBuffer;     //buffer formatı için
ALsizei alFreqBuffer;      //buffer’ın frekansı için
long alBufferLen;          //derinlik biti 
ALboolean alLoop;          //döngüleme
unsigned int alSource;     //source
unsigned int alSampleSet; 
//wave dosyasını yükle
alutLoadWAVFile("test.wav",&alFormatBuffer, (void**) &alBuffer, (unsigned int *)&alBufferLen, &alFreqBuffer, &loop);
 
//1 source yarat
alGenSources(1, &alSource);
 
//1 buffer yarat
alGenBuffers(1, &alSampleSet);
 
//örnek setini alBuffer’dan buffer datasıyla doldur
alBufferData(alSampleSet, alFormatBuffer, alBuffer, alBufferLen, alFreqBuffer);
 
//bu source’ü buffer’a bağla
alSourcei(alSource, AL_BUFFER, alSampleSet);
 
//datayı serbest bırak
alutUnloadWAV(alFormatBuffer, alBuffer, alBufferLen, alFreqBuffer);

Burada İlk yapılan  "Test. Wav" dosyasını yüklemektir. Data okunup alBuffer'da depolanır . Sonra bir buffer ve source yaratılır. Ondan sonra buffer ,alBuffer’dan datayla doldurulur. Sonrada buffer source 'e tahsis edilip wave datası serbest bırakılır.

Source Özelliklerinin Ayarlanması

Sesin source olarak kurgulanmışına sahip olunmasıyla onun bazı özelliklerini set etmeye ihtiyaç duyarsınız. Bunu yapmak için alSource komutunu kullanırsınız. alSourcei, alSourcef, alSource3f vb gibi farklı uyarlamaları olan fonksiyon, OpenGL'deki mevcut fonksiyonlara benzer çalışır. Set edeceğiniz özellikler, hangi fonksiyonu kullanacağınızı belirler. Örneğin sadece bir kayan noktalı parametreyse bu o zaman alSource3f kullanılır. Fonksiyonun ilk parametresi, modifelemeyi istediğini source’i belirtir. İkinci parametre,  ne özelliği getirileceğine karşılık gelir. Kalan parametreler bu özellik için aktüel değerlerdir. Buradaki bir source için pozisyon ve gücünü ayarlamanın bir örneğidir:

//source pozisyonunu set et
alSource3f(alSource,AL_POSITION, xposition, yposition, zposition);
 
//source gücünü set et
alSource3f(alSource,AL_VELOCITY, xvelocity, yvelocity, zvelocity);

Buradaki alSource bizim ses source'imiz ve AL_POSITION ve AL_VELOCITY, bizim, pozisyon ve güç özelliklerini değiştirmek istediğimizi gösterir. Kalan, kayan noktalı sayılar bu özellikler için ilk değerlerine karşılık gelir.

Listener’ın Kullanımı

3D sesde bir listener'ının kullanımı önemlidir bununla seslerin duyulacağı bir referans noktasına sahip olursunuz. Bir listener'ın bir ses source pozisyonuna yakınlığı daha yüksek sesin alınmasına mani değildir. OpenAL listener nesnesini ayarlar Böylece tümünü sizin yapmanız gerekirken ihtiyaç duyulduğu gibi özellikleri değiştirilir. Listener'ın en önemli özellikleri listener'ın pozisyon ve yönüdür. Bu özellikler,  bir oyunda her döngü için birer kez genellikle güncelleştirilir. Pozisyon, listener'ın hali hazırda yüzünün dönük olduğu yerin yönü gösterir. Örneğin, eğer bir listener batıya yüzü dönük  ve ses kuzeyden geliyorsa, Ses, sağdan geliyormuş gibi olacak. Bununla birlikte eğer kullanıcı yönünü değiştirip yüzünü kuzeye dönerse, Ses düz ilerden geliyormuş gibi olacak.
Bir listener'ın özelliklerini değiştirmek , ses source'nin özelliklerini değiştirme şeklinize benzer şekilde çalışır. alListener fonksiyonu kullanıp değiştireceğin özelliğe bağlı çeşitlenir. Örneğin,listener(dinleyici) pozisyonunu set etmek için alListener3f'i çağırıp 3 ayrı kayan noktalı sayı belirtebilirsiniz veya alListenerfv'i çağırıp kayan noktalı sayılarının bir dizisini geçebilirdiniz. Pozisyon parametreleri,  oyun dünyası içinde listener'ın x, y ve z değerleridir. Yön özelliği bununla birlikte 6 parametre alır. İlk 3ü listener'ın kullanıcıya mevcut bakışına karşılık gelen vektör için. Sonraki 3 vektör listener'ın yüzünü döndüğü yön içindir. Aşağıdaki, listener'ın pozisyon ve yönünü set etme örneğidir:

float listenerx, listenery, listenerz;
float vec[6];
 
listenerx=10.0f;
listenery=0.0f;
listenerz=5.0f;
 
vec[0] = fvecx; //forward vector x değeri
vec[1] = fvecy; //forward vector y değeri
vec[2] = fvecz; //forward vector z değeri
vec[3] = uvecx; //up vector x değeri
vec[4] = uvecy; //up vector y değeri
vec[5] = uvecz; //up vector z değeri
//mevcut listener pozisyonunu set et
alListener3f(AL_POSITION, listenerx, listenery, listenerz);
 
//mevcut listener yönünü set et
alListenerfv(AL_ORIENTATION, vec);

İlk fonksiyon çağrısında, 3 ayrı kayan noktalı sayı listener'ın x,y,z pozisyonuna geçilir. İkinci çağrı, vec isimli bir diziyi geçer. Bu dizi, listener'ın yönüyle ilgili olan altı değerden oluşan iki vektör içindir.

Seslerin Çalınması

Sesleriniz yüklenip listener özelliklerini set ettikten sonra seslerinizi çaldırabilirsiniz. alSourcePlay fonksiyonunu çağırmanız bunu sağlar. Bu fonksiyon,  çalmayı istediğiniz source olan tek bir parametre alır. Bir sesi durdurmak için yine durdurmayı istediğiniz source ismiyle alSourceStop fonksiyonunu çağırırsınız. Eğer sesin döngülenme etkisini istiyorsan Mesela su akış sesi gibisine sahipsen, Sesi çaldırmadan önce sesin döngülenme özelliğini true’e getirmelisin. örnek kod bölümü bu:

//sesin sürekli döngüleneceğini söyle
alSourcei(alSource,AL_LOOPING,AL_TRUE);
 
//sesi çal
alSourcePlay(alSource);
 
// sesi durdur
alSourceStop(alSource);

Bitiş

Programınızla işiniz bitince, source'lerinizi ve bufferlarınızı serbest bırakıp OpenAL'ı sonlamaya ihtiyaç duyarsınız. Komutlar göreli basittir. source'lerinizi ve buffer'larınız nasıl silineceği burada:

//source’umuzu sil
alDeleteSources(1,&alSource);
//buffer’ımızı sil
alDeleteBuffers(1,&alSampleSet);

Burada her birinin ilk parametresi silinecek buffer veya sourcelerin sayısıdır  Ve ikincisi silinicek buffer veya source'dir. Son adım,  OpenAL'i n kendisini sonlamaktır. Bu, takip eden gibi yapılır:

//aktif gaçerli context’i elde et
Context=alcGetCurrentContext();
//aktif context aygıtını elde et
Device=alcGetContextsDevice(Context);
//aktif geçerli context’i etkisizleştir
alcMakeContextCurrent(NULL);
//context’i(‘leri) serbest bırak
alcDestroyContext(Context);
//aygıtı kapa
alcCloseDevice(Device);

OpenAL'de sesleri çalma hakkındaki temeller bunlar. Temel adımlardan, ilki OpenAL'i ilklemek, sonra, ihtiyaç duyduğun sesleri yükleyip, Seslerin ve listener'ın özelliklerini set etmek ve sonra sesleri çalmaktır. OpenAL'le yapabileceğin daha çoğu var Ama bu sadece bir kısım temelleri tanımlamak için yazıldı. Bununla beraber gelen kaynak kodu, bir OpenGL demosunda bunların tümünün kullanımı göstermekte. Demoda, listener'ı kontrol ediyorsunuz, bir döngüde pozisyona sizin mevcut konumunuz set ediliyor. Eğer herhangi bir soru veya düşünceye sahipseniz, ricart3@tcnj.edu ‘e bana mail atın.

Bu dersin kaynak kodlarını yükle.
Dersin Orjinali : http://www.devmaster.net/articles/openal/