3D Game Programming Audio Ming-Te Chi Department of Computer Science, National Chengchi University 2017
Goal Sound and music in game OpenAL programming Unity3D Audio 首先,介紹在遊戲中音效和音樂扮演的角色 再來介紹音效儲存的格式 最後以OpenAL函式庫為主,介紹如何把音效加入到遊戲中
Music and Sound Game music Sound FX Transition animation Exploding Wind blowing Raining Walking 遊戲中常利用背景音樂(長而不斷循環的音樂)強化對場景風格的效果 Mario brother的主題音樂一出現,大家自然能與遊戲的場景和遊玩的回憶串聯起來 另外,像敲磚塊、吃到香菇長大等音效(相對短的效果音),也是玩家耳熟能詳的 良好的視覺效果加上適當的音效,更能帶領玩家進入遊戲的世界
Sound wave Sound waves are often simplified to a description in terms of sinusoidal plane waves 聲音的結構可被理解由不同的波型藉由空氣從音源處傳播出去 最簡單的結構之一是單一波長和振幅的正弦波 藉由不同波長和振幅可重現出許多不同的聲音效果
Sound
Properties of sound wave Frequency, or its inverse, the period Wavelength Wavenumber Amplitude Sound pressure Sound intensity Speed of sound source Direction 聲波的特性有以下數種 -頻率、波長、 -震幅、音壓、聲音的強度、 音源移動的速度和發出的方向
Audio Format An audio format is a medium for storing sound and music. Wav and mp3 are common format Store 44,100 samples per second, 16 bits per sample. 如同影像可以bmp或jpg的圖檔格式儲存 常用的聲音格式有wav和mp3 儲存的原理是在單位時間內對聲音的強度進行取樣, CD音源的取樣頻率就是每秒切隔成44100的小區間取樣,每一個取樣以16bit記錄,也就是2的16次方(65535)的強度變化 這些沿著時間軸的取樣,便可還原成聲波的變化
Windows api Simply use windows api to play wav BOOL WINAPI PlaySound( LPCSTR pszSound, HMODULE hmod, DWORD fdwSound ); Simply use windows api to play wav Ex: play a wav file in“music/ding.wav” PlaySound("music/ding.wav", NULL,SND_ASYNC | SND_FILENAME); 可利用windows api播放wav格式的聲音 SND_ASYNC 非同步播放聲音(一發出聲音,程式就繼續執行下去) 若換成SND_SYNC 則要等聲音檔播完程式才會繼續執行下去 SND_FILENAME 表示pszSound所描述的是檔案名稱 其缺點同時只能播放一個聲音,如需播放背景音樂,可利用mciSendString( “play music/back.wma”, 0, 0, 0 ); 播放音樂
OpenAL OpenAL (Open Audio Library) is a free software cross-platform audio API. It is designed for efficient rendering of multichannel three dimensional positional audio. 若需要同時發出多個音效,並建立3D的音場效果 可使用OpenAL
OpenAL Basic Elements Source Buffer Listener A source of a sound in the world Link to buffer for actual data to play Buffer Hold physical sound data in the memory Cannot play buffer directly Need to use source Listener The ears of the world OpenAL主要有三個基本元件 Source (音源),定義在3D世界中音源的位置和相關資訊。必須和buffer進行連接以發出聲音 Buffer 存放聲音資料,無法直接控制buffer元件播放聲音 Listener,在3D世界中聆聽者的位置和相關資訊
OpenAL Architecture Source0 Buffer0 Buffer1 Source1 Listener Buffer2 整體的架構圖 將會使用到的音樂和音效透過buffer載入到記憶體中 先在3D世界對應出source和listener的位置, 經由buffer和source的對應,控制source播放聲音 OpenAL會據此計算3D音效 Buffer3 Source2 memory 3D world
Listener For every context, there is automatically one Listener object. alListenerfv(AL_POSITION, listenerPos); alListenerfv(AL_VELOCITY, listenerVel); alListenerfv(AL_ORIENTATION, listenerOri); Listener 可以對應到3D繪圖的相機,是接收聲音的位置 所以需設定位置、移動的速度和方向 之所以要記載移動的向量,主要是可以藉由音源和聆聽者間的相對移動速度, 以都卜勒效應(Doppler effect)計算出接受到波的頻率與波源發出的頻率的變化
Buffer Each buffer generated by alGenBuffers has properties which can be retrieved. Buffer用來存放聲音資料 需利用alut或其它函式,將聲音格式(ex: wav, mp3)轉成OpenAL能裡解的格式 其行為很類似在OpenGL處理texture image的部份
const int NUM_BUFFERS = 3; ALuint buffer[NUM_BUFFERS]; ALboolean al_bool; ALsizei size,freq; ALenum format; ALvoid *data = NULL; int ch; // Generate buffers, or no sound will be produced alGenBuffers(NUM_BUFFERS, buffer); if(alGetError() != AL_NO_ERROR) { printf("- Error creating buffers !!\n"); exit(1); } else { // printf("Created buffers\n"); } alutLoadWAVFile("c.wav", &format ,&data, &size, &freq, &al_bool); alBufferData(buffer[0], format, data, size, freq); alutUnloadWAV(format, data, size, freq);
Source A source in OpenAL is exactly what it sounds like, a source of a sound in the world. 這張表詳列音源的參數設定
const int NUM_SOURCES = 3; ALuint source[NUM_SOURCES]; alGetError(); /* clear error */ alGenSources(NUM_SOURCES, source); if(alGetError() != AL_NO_ERROR) { printf("- Error creating sources !!\n"); exit(2); } alSourcef(source[0], AL_PITCH, 1.0f); alSourcef(source[0], AL_GAIN, 1.0f); alSourcefv(source[0], AL_POSITION, source0Pos); alSourcefv(source[0], AL_VELOCITY, source0Vel); alSourcei(source[0], AL_BUFFER, buffer[0]); //attach buffer alSourcei(source[0], AL_LOOPING, AL_TRUE); 對音源初始化時需先建立音源,並設定音高、音量、音源位置、音源移動速度等資訊 有了音源位置和速度加上聆聽者的位置資訊,OpenAL會自動根據這些資訊計算出立體的音場 最重要的是將buffer (聲音資料)連接到source(音源)
Play and Stop Combine with keyboardfunc(), or some other way Ex: alSourcePlay(source[0]); alSourceStop(source[0]); alSourcePause(source[0]); 可以利用這三個函式讓某個音源開始播放、停止或暫停 通常可以和GLUT的keyboardFunc做結合 譬如是按下 j 鍵時會驅動角色的位置改變做出跳躍的動作,並同時設定音效的播放 或是更進一步整合各種會發出音效的狀況,播放適當的音效
Audio in Unity3D Audio Sources attached to objects, Audio Listener attached to another object, most often the main camera
Audio Listener Each scene can only have 1 Audio Listener to work properly.
Audio Source Plays back an Audio Clip in the scene. Volume Pitch
Audio Clip AIFF, WAV, MP3 and Ogg formats
Play()/Stop() Pause()/UnPause() void Start() { AudioSource audio = GetComponent<AudioSource>(); audio.Play(); audio.Play(44100); } Pause()/UnPause()
Play, wait, switch clip [RequireComponent(typeof(AudioSource))] public class ExampleClass : MonoBehaviour { public AudioClip otherClip; IEnumerator Start() { AudioSource audio = GetComponent<AudioSource>(); audio.Play(); yield return new WaitForSeconds(audio.clip.length); audio.clip = otherClip; }
AudioSource.unity 嘗試各種不同的AudioSource效果。
AudioSource 有時候,某些事件發生後會需要播放一段短暫的音效。 UI按鈕音效。 爆炸聲。 角色被攻擊的慘叫。 AudioSource.playOneShot(適合參數一樣的音效,如UI音效,或主角發出的所有聲音) AudioSource.playClipAtPoint(適合即時產生在場景某處的3D音效,如爆炸聲)
AudioSource.PlayOneShot 需要一個AudioSource Component。 使用該Audio Source,播放一段Audio Clip。 不會更改該Audio Source目前的clip。 Audio Source任何的參數變化/狀態變化都會影響播放中的OneShot。 可以同時呼叫PlayOneShot多次,彼此之間不互相影響。 播放以後沒辦法獨立暫停/取消。
AudioSource.PlayClipAtPoint AudioSource class的靜態成員函式,不需要AudioSource實體。 在世界座標指定的位址播放一段Audio Clip。必定為3D Sound。 場景中會產生一個One shot audio物件,播放完會自我刪除。
Audio Effects 本身不發出聲音,但可以影響Audio Source發出的聲音或Audio Listener聽到的聲音。 音效元件: Audio Mixer + Audio Effect Audio Filter Reverb Zone
Audio Mixer + Audio Effect 控制Audio Source混合的順序,每一次混和都可以加入不同的Audio Effect。 請參閱文件: http://docs.unity3d.com/Manual/AudioMixer.html
Audio Filter 直接對物件發出/聽到的音效做出filter效果。 對Audio Source使用: 影響發出的聲音。 對Audio Listener使用: 影響聽到的所有聲音。 Component的順序會影響filter套用的順序。 圖: 對Audio Listener聽到的所有聲音,先 做low pass(過濾掉頻率高於5000hz的聲音) ,再做chorus(合唱) filter。
Reverb Zone Reverb,殘響,用來模擬聲音在具有障礙物的環境中的反射/折射/繞射綜合產生的複雜效果。 使用時機如: 玩家走進山洞中時,腳步聲會產生回音。此時只要將山洞整個包在Reverb Zone中,所有位於其中的Audio Source和Audio Listener都會自動受到影響。 有各項環境參數可調整,與一般電腦中的混音軟體相似。
ReverbZone.unity 當角色進入Reverb Zone時,腳步聲會變化,模擬洞穴的回音。