موضوع : پخش افکتهاي صوتی
در برنامه هاي مالتي مديا
مقدمه : در سلسله مباحث DirectXAudio
شما تکنيکهاي لازم براي اضافه کردن موزيک و افکتهاي صوتي سريع و ديناميک را به
بازيها و برنامه هاي مالتي مديا خواهيد آموخت . DirectXAudio جايگزيني براي بخشهاي
DirectSound ، DirectSound3D و DirectMusic موجود در DirectX 7 مي باشد و داراي
امکانات بهتر و سريعتری بوده و برنامه نويسي آن نيز ساده تر است .
در اولين درس
از DirectXAudio چگونگي پخش افکتهاي صوتي را در برنامه هايتان خواهيد آموخت .
Initial کردن DirectSound :
DirectSound اولين مبحثي است که آنرا
توضيح خواهم داد . گرچه DirectXAudio يک نام عمومي براي امکانات صوتي DirectX8 مي
باشد اما بين Sound و Music تفاوت وجود دارد .
DirectSound با پخش افکتهاي صوتي
ارتباط دارد . DirectSound همانند Direct3D از يکسري device سخت افزاري و نرم
افزاري استفاده مي کند و افکتهاي صوتي در يکسري بافر ذخيره مي شوند .
اولين قدم
براي برپاسازي DirectSound ، اضافه کردن کتابخانه DirectX8 به پروژه تان مي باشد .
قدم بعدي تعريف متغيرها و object هاي موردنياز است . براي استفاده از DirectSound
به متغيرهاي زير نياز داريم :
Private DX As DirectX8
Private DS As
DirectSound8
Private DSBuffer As DirectSoundSecondaryBuffer8
Private
DSEnum As DirectSoundEnum8
Private bLoaded As Boolean
DirectX شي کنترل کننده مرکزي است . DirectSound8 واسط مراقب براي تمام
interface هاي پخش صدا است . DirectSoundSecondaryBuffer8 داده audio واقعي را براي
پخش ذخيره مي کند . DirectSoundEnum8 اجازه مي دهد که اطلاعاتي را در مورد device
هاي سخت افزاري/نرم افزاري استخراج کنيد و متغير bLoaded يک flag وضعيت مي باشد .
حال در برنامه بايد ليست تمام device هاي در دسترس را مشخص کنيم . ( اين امر
کاملاً امکان پذير است که يک کامپيوتر بيش از يک device براي DirectSound داشته
باشد ) :
Private Sub Form_Load()x
bLoaded =
False
Dim I As Long
Set DX = New DirectX8
Set DSEnum =
DX.GetDSEnum
For I = 1 To
DSEnum.GetCount
MsgBox(DSEnum.GetDescription(I))x
Next I
End
Sub
فرض کنيم که يکي از device هاي شناخته شده را
انتخاب کرديم . حال بايستي device را واقعاً برپا کنيم :
If bLoaded Then
Set DSBuffer =
Nothing
Set DS = Nothing
Set DX = Nothing
End If
Dim DSBDesc As
DSBUFFERDESC
Set DX = New DirectX8
Set DS =
DX.DirectSoundCreate(DSEnum.GetGuid(devicenumber))x
DS.SetCooperativeLevel
frmMain.hWnd, DSSCL_NORMAL
متغير devicenumber شماره device اي است که شما مي خواهيد با
آن کار کنيد . DSBDesc فايل صوتي شما را توصيف مي کند .
--------------------------------
موضوع : پخش افکتهاي صوتی در برنامه هاي مالتي مديا
ساخت بافر و play کردن آن : تاکنون ما توانستيم DirectSound را
initial کنيم . همانطور که می دانيد در تمام component های DirectX داده ها در
يکسری بافر ذخيره می شوند . در مورد DirectSound نيز ما يک بافر با نام
DirectSoundSecondaryBuffer8 می سازيم و داده های صوتی را در آن قرار می دهيم .
برخی پارامتر ها هستند که بايد برای بافر تنظيم شوند مثل : stereo يا mono بودن
بافر ، ۸ بيتی يا ۱۶ بيتی بودن بافر ، فرکانس صوتی ( 22khz ، 44khz و غيره ) . اگر
اين پارامترها را مشخص نکنيم DirectSound از اطلاعات فايل صوتی استفاده می کند .
در يک کاربرد ساده ، ما تنها يک بافر صوتی از يک فايل ايجاد می کنيم اما امکان
ايجاد چندين بافر بطور همزمان و نيز پخش چندين صدا بطور همزمان نيز وجود دارد
:
DSBDesc.lFlags = DSBCAPS_CTRLFREQUENCY
Or DSBCAPS_CTRLPAN Or DSBCAPS_CTRLVOLUME
Set DSBuffer =
DS.CreateSoundBufferFromFile(App.Path & "\Sample.wav", DSBDesc)x
MsgBox
"SOUND BUFFER CREATED:"x
MsgBox "Buffer Size: " & DSBDesc.lBufferBytes
& "bytes (" & Round(DSBDesc.lBufferBytes / 1024, 3) &
"kb)"x
MsgBox "Buffer Channel Count:" &
DSBDesc.fxFormat.nChannelsIIf(DSBDesc.fxFormat.nChannels = 1, " (Mono)", "
(Stereo)")x
MsgBox "Buffer Bits per channel: " &
DSBDesc.fxFormat.nBitsPerSample & " bits"x
در بالا يک بافر صوتی ايجاد شده و اطلاعات صدا از فايل به بافر
load شده است .
حال بايستی داده صوتی موجود در بافر را play کنيم :
دستور
لازم برای Play کردن بافر بصورت loop :
DSBuffer.Play
DSBPLAY_LOOPING
دستور لازم برای Play کردن بافر بدون loop :
DSBuffer.Play
DSBPLAY_DEFAULT
دستورات لازم برای Stop کردن بافر :
DSBuffer.Stop
DSBuffer.SetCurrentPosition 0
دستور لازم برای Pause کردن بافر :
DSBuffer.Stop
تنظيم خصوصيات بافر : سه خصوصيت وجود دارد که در مورد
بافر تنظيم می شود pannig ، volume و frequency
محدوده مقادير pannig بين اعداد
زير است :
DSBPAN_LEFT = -10,000
DSBPAN_CENTER = 0
DSBPAN_RIGHT = 10,000
توسط متد SetPan می توان pannig بافر را تنظيم کرد :
DSBuffer.SetPan yourValue
DirectSound صدا را تقويت نمی کند بلکه آنرا تضعيف می نمايد
بنابراين ماکزيمم volume عبارت است از volume ای که فايل صوتی با آن ضبط شده است .
بعبارت ديگر محدود مقادير volume بين اعداد زير است :
DSBVOLUME_MAX =
0
DSBVOLUME_MIN = -10000
توسط متد SetVolume می توان volume بافر را تنظيم
کرد :
DSBuffer.SetVolume yourValue
محدود فرکانسی DirectSound عبارت است از :
DSBFREQUENCY_MIN
= 100 (hz)x
DSBFREQUENCY_MAX = 100000 (hz) = 100khz x
توسط متد
SetFrequency می توان فرکانس بافر را تنظيم کرد :
DSBuffer.SetFrequency
yourValue
---------------------------------------
موضوع : پخش موزيک توسط DirectMusic
مقدمه
:
در اولين درس از آموزش DirectXAudio با چگونگي پخش افکتهاي صوتي
آشنا شديد . اکنون اين توانايي را داريد که يک engine ساده صوتي بنويسيد . در اين
بخش مباني پخش موزيک را فرا خواهيد گرفت . پس از اين درس شما مي توانيد يک ماژوال
براي پخش موزيکهاي پس زمينه و افکتهاي صوتي براي برنامه هايتان ايجاد کنيد
.
Initil کردن DirectMusic8 :
قبل از هر کار بايستي ماژول
DirectMusic8 را مقداردهي اوليه کنيد . اينکار بصورت زير انجام مي شود
:
Option ExplicitImplements DirectXEvent8
Private oDX As DirectX8
Private oDMPerf As DirectMusicPerformance8
Private oDMLoader As DirectMusicLoader8
Private oDMSeg As
DirectMusicSegment8
Dim dmParams As DMUS_AUDIOPARAMS
Set oDX = New
DirectX8
Set oDMPerf = oDX.DirectMusicPerformanceCreate
Set oDMLoader =
oDX.DirectMusicLoaderCreate
oDMPerf.InitAudio frmMain.hWnd, DMUS_AUDIOF_ALL,
dmParams, Nothing, DMUS_APATH_DYNAMIC_STEREO,
128
oDMPerf.SetMasterAutoDownload True
شي DirectMusicLoader8 کمک مي کند تا موزيک درون بافر load شود
.
شي DirectMusicSegment8 مموزيکي را که بايد پخش شود ذخيره مي کند .
کد فوق
کافي است يکبار زمانيکه برنامه آغاز مي شود ، اجرا گردد .
اکنون ما يک واسط
مقدار دهي شده از DirectMusic داريم اما قبل از اينکه موزيک را Load کرده و پخش
کنيم چگونگي terminate کردن DirectMusic را در زير مي بينيد :
If ObjPtr(oDMSeg)Then Set oDMSeg =
Nothing
If ObjPtr(oDMLoader)Then Set oDMLoader = Nothing
If Not (oDMPerf
Is Nothing) Then
oDMPerf.CloseDown
Set oDMPerf = Nothing
End If
If
ObjPtr(oDX) Then Set oDX = Nothing
پيغامها :
در برخي از component هاي
DirectX8 مثل Input , Sound , Music و Play برنامه شما بايستي يک سيستم messaging
را برپا کند تا DirectX زمان وقوع برخي رخدادهاي خاص را بشما گزارش دهد . اين مطلب
بخصوص زمانيکه يک موزيک را پخش مي کنيد مفيد است براي مثال مي تواند زمان خاتمه
يافتن موزيک را به شما اطلاع دهد و آنگاه شما مي توانيد قطعه موزيک بعدي را پخش
کنيد .
پيغامها توسط يک سيستم callback انجام مي شوند . کد زير را در تابع
InitDMusic تان پس از initial کردن DirectMusic8 قرار دهيد :
oDMPerf.AddNotificationType
DMUS_NOTIFY_ON_SEGMENT
hEvent =
oDX.CreateEvent(Me)x
oDMPerf.SetNotificationHandle hEvent
اولين سطر به DirectMusic مي گويد چه نوع پيغامهايي را مي
خواهيد به برنامه تان بفرستد . چندين نوع پيغام وجود دارد
:
DMUS_NOTIFY_ON_SEGMENT = اطلاعات موزيک فعلي ( شروع پخش ، پايان پخش و غيره
)
DMUS_NOTIFY_ON_CHORD = اطلاعات تغيير chord موزيک
DMUS_NOTIFY_ON_COMMAND
= زمانيکه يک event فرماني صدا زده شود .
DMUS_NOTIFY_ON_MEASUREANDBEAT =
اطلاعات beat/measure مربوط به موزيک فعلي
DMUS_NOTIFY_ON_PERFORMANCE = که
event مربوط به سطح performance می باشد .
DMUS_NOTIFY_ON_RECOMPOSE = که
recomposition event می باشد .
آخرين بخش از پيغام دهي ، تابع اصلي آن مي باشد .
همانطور که در بخش Initial کردن DirectMusic ديديد يک توصيف بصورت Implements
DirectXEvent8 داشتيم . بخش اصلي تابع callback مربوط به DirectXEvent8 ، شامل يک
select case است که بين پيغامهاي مختلف سوئيچ می کند :
Private Sub
DirectXEvent8_DXCallback(ByVal eventid As Long)x
If eventid = hEvent Then
Dim dmMSG As DMUS_NOTIFICATION_PMSG
If Not
oDMPerf.GetNotificationPMSG(dmMSG) Then
Else
Select Case
dmMSG.lNotificationOption
Case DMUS_NOTIFICATION_SEGABORT
Case
DMUS_NOTIFICATION_SEGALMOSTEND
Case DMUS_NOTIFICATION_SEGEND
Case
DMUS_NOTIFICATION_SEGLOOP
Case DMUS_NOTIFICATION_SEGSTART
Case Else
End Select
End If
End If
End Sub
پخش موزيک / متوقف کردن موزيک :
براي پخش يک
موزيک ابتدا بايستي آنرا load کنيد . اينکار توسط کد زير انجام مي شود
:
oDMLoader.SetSearchDirectory App.Path
& "\"x
Set oDMSeg = oDMLoader.LoadSegment(App.Path &
FILENAME)oDMSeg.SetStandardMidiFile
DirectMusic تنها چهار نوع فرمت صوتي را مي پذيرد : WAV ، MID
، RMI و SEG .
براي پخش فايلهاي MP3 بايستي از DirectXShow استفاده کنيد که
آنرا در درسهاي بعدي خواهيد ديد .
اکنون که داده هاي فايل صوتي درون بافر load
شد مي توانيد آنرا پخش کنيد :
oDMSeg.SetRepeats 0
oDMPerf.PlaySegmentEx oDMSeg, DMUS_SEGF_DEFAULT, 0
تعداد پخش شدن فايل را با متد SetRepets تنظيم کنيد . اگر اين
مقدار صفر باشد ، آهنگ تنها يکبار پخش مي شود و اگر 1- باشد بطور ممتد پخش خواهد شد
.
براي متوقف کردن موزيک از کد زير استفاده کنيد :
oDMPerf.StopEx oDMSeg, 0,
DMUS_SEGF_DEFAULT
براي تنظيم ميزان صدا از متد SetMasterVolume استقاده کنيد
:
oDMPerf.SetMasterVolume
yourvalue
رنج صدا بين 20+ دسی بل تا 200- دسي بل است .
براي تنظيم
Tempo از متد SetMasterTempo استفاده کنيد :
oDMPerf.SetMasterTempo yourvalue/
100
بطور نرمال tempo برابر 1 مي باشد . عدد 2 سرعت را دو برابر مي
کند و عدد 0 موزيک را قطع مي کند .
-------------------------------
موضوع : ايجاد صدای سه بعدی توسط
DirectSound3D
مقدمه
تاکنون با چگونگي پخش افکتهاي صوتي و
موسيقي پس زمينه توسط DirectXAudiuo آشنا شديد . اين مطالب براي کاربردهاي ساده
مناسبند اما اينکه فقط ما صداي استريو داشته باشيم کافي نيست و در کاربردهاب حرفه
اي بايستي از صداهاي کاملاً سه بعدي استفاده کنيم .
با استفاده از افکتهاي صوتي
سه بعدي مي توانيم صدا را در تمام جهتها براي کاربر شبيه سازي کنيم اما با همه
مزاياي صداي سه بعدي ، دو اشکال براي آن وجود دارد : اول اينکه پخش صداي سه بعدي
پيچيده تر از پخش صداي عادي است و تنها کارت هاي سخت افزاري جديد بطور کاملاً واقعي
از آن پشتيباني مي کنند و دوم اينکه صداي سه بعدي با 4 بلندگو يا بيشتر حاصل مي شود
– کيفيت حالت 2 بلندگو بد نيست اما در مقايسه با حالت 4 بلندگو ، بسيار کيفيت صداي
سه بعدي پايين است .
برپاسازي DirectSound3D
برپاسازي صداي سه
بعدي چندان پيچيده نيست اما هر بافر صوتي که براي يک صداي سه بعدي مي سازيد ، يک
overhead را به سيستم تان اضافه مي کند . همچنين برخي درايورها هستند که تنها اجازه
ايجاد تعداد محدودي بافر سه بعدي را در يک لحظه مي دهند و نيز اغلب درايورها تعداد
بافرهاي سه بعدي که مي توان در يک لحظه پخش کرد را محدود مي کنند ( معمولاً 8 تا 16
بافر ) .
اولين قدم در استفاده از صداي سه بعدي تعريف متغيرها و اشيا زير است
:
Dim DSBuffer As
DirectSoundSecondaryBuffer8
Dim DSBuffer3D As DirectSound3DBuffer8
Dim
DSBListener As DirectSound3DListener8
تنها دو شي آخر براي شما جديد هستند . شي DirectSound3dBuffer8
يک ارائه سه بعدي از بافرهاي عادي است . ما همچنان از DirectSoundSecondaryBuffer8
براي نگهداري داده صوتي استفاده مي کنيم و از DirectSound3Dbuffer8 براي نگهداري
پارامترهاي سه بعدي و تنظيمات سه بعدي استفاده مي کنيم . شي DirectSound3Dlistener8
نيز يک listener است و براي تنظيم کردن سرعت و جهت صدا و برخي پارامترهاي ديگر
استفاده مي شود .
مرحله دوم ، ساخت بافر صوتي است . اين کار در دو بخش انجام مي
شود . اول ما يک بافر صوتي نرمال مي سازيم و سپس يک واسط بافر صوتي سه بعدي را از
آن بدست مي آوريم :
If Not (DSBuffer Is Nothing) Then
DSBuffer.Stop
Set DSBuffer = Nothing
DSBDesc.lFlags = DSBCAPS_CTRL3D Or
DSBCAPS_CTRLVOLUME
Set DSBuffer = DS.CreateSoundBufferFromFile(App.Path &
"\blip.wav", DSBDesc)x
If DSBDesc.fxFormat.nChannels > 1 Then
MsgBox
"You can only use mono (1 channel) sounds with DirectSound3D"x
End If
If
optLow.Value Then DSBDesc.guid3DAlgorithm = GUID_DS3DALG_NO_VIRTUALIZATION
If
optMedium.Value Then DSBDesc.guid3DAlgorithm = GUID_DS3DALG_HRTF_LIGHT
If
optHigh.Value Then DSBDesc.guid3DAlgorithm = GUID_DS3DALG_HRTF_FULL
Set
DSBuffer = DS.CreateSoundBufferFromFile(App.Path & "\blip.wav",
DSBDesc)x
Set DSBuffer3D = DSBuffer.GetDirectSound3DBuffer()x
سه نکته است که بايد به آن دقت شود :
1 – اضافه کردن
DSBCAPS_CTRL3D بسيار مهم است . شما اگر اين پارامتر را بکار نبريد ، قادر نخواهيد
بود که واسط سه بعدي را بدست آوريد .
2 – ما بايستي تنها از افکتهاي صوتي Mono (
تک کاناله ) استفاده کنيم زيرا افکت صوتي استريو در صداي سه بعدي معنا ندارد زيرا
صدا از يک نقطه در فضاي سه بعدي مي آيد .
3 – سطح الگوريتم سه بعدي – که در
پارامتر DSBDesc.guid3Dalgorhthm آمده . حالت NO VIRTULIZATION تنها از CPU استفاده
مي کند و روي تمام سيستم ها کار مي کند اما افکتها مينيمم هستند . حالت HRTF LIGHT
هم از CPU و هم سخت افزار کارت صوتي استفاده مي کند و کيفيت بهتري را نسبت به خالت
اول ارائه مي دهد . حالت HRTF FULL بهترين حالت است اما در صورتي درست کار مي کند
که يک سخت افزار سه بعدي داشته باشيد .
آخرين پارامتري که بايد تنظيم کنيم شي
listener است :
DSBDesc_2.lFlags = DSBCAPS_CTRL3D Or
DSBCAPS_PRIMARYBUFFER
Set DSBPrimary = DS.CreatePrimarySoundBuffer(DSBDesc_2)
x
Set DSBListener =
DSBPrimary.GetDirectSound3Dlistener
DSBListener.SetOrientation 0#, 0#, 1#,
0#, 1#, 0#, DS3D_IMMEDIATE
تا اينجا صداي سه بعدي ما آماده است و مي توانيم برخي پخش بافر
را مشابه درسهاي قبلي شروع کنيد .
پارامترهاي اختياري :
چند
پارامتر وجود دارد که مي توان آنها را تغيير داد :
1 – Volume : عدد 0 بيشترين
ميزان صدا و عدد 3000 - کمترين ميزان صدا را دارد :
If DSBuffer Is Nothing Then Exit
Sub
DSBuffer.SetVolume scrlVolume.Value
2 – Position : تنظيم محل listener :
DSBuffer3D.SetPosition Src_X, 0, Src_Y,
DS3D_IMMEDIATE
DSBListener.SetPosition Src_X, 0, Src_Y, DS3D_IMMEDIATE
3 – Velocity : تنظيم سرعت و جهت منبع صدا :
DSBuffer3D.SetVelocity X, Y, Z,
DS3D_IMMEDIATE
DSBListener.SetVelocity X, Y, Z, DS3D_IMMEDIATE
4 – Dppler Effect : انحراف صدا از مسيري که مي پيمايد انحراف
سرعت حرکت صدا :
DSBListener.SetDopplerFactor
CSng(scrlDoppler.Value), DS3D_IMMEDIATE
5 – Rolloff Effect : rolloff چگونگي تضعيف صدا با تغيير فاصله
است .
DSBListener.SetRolloffFactor
CSng(scrlRolloff.Value), DS3D_IMMEDIATE
6 – Distance : ماکزيمم فاصله اي که يک صدا مي تواند شنيده شود
:
DSBuffer3D.SetMaxDistance 250,
DS3D_IMMEDIATE
DSBuffer3D.SetMinDistance 0.01, DS3D_IMMEDIATE
--------------------------