Direct Sound в VB
DirectSound является одной из составных частей DirectX и нужен для работы
со звуком. Понять его работу и как он облегчает жизнь программисту можно на примере.
Для начала нужно создать новый проект и добавить к нему библиотеку dx8vb.dll,
затем создать новую форму и модуль. В нём, как обычно, пишем:
Option Explicit
Global DirectX As New DirectX8
Затем объявляем объект DirectSound и массив буферов. Буфер - это место, где храниться звук. Например, в игре используется 3 буфера: один с музыкой, и два других со звуковыми эффектами. Так вот над буферами очень удобно работать: можно менять баланс, громкость и звуковой файл каждого их них.
Global DirectSound As DirectSound8
Global SoundBuffer() As DirectSoundSecondaryBuffer8
Теперь надо создать процедуру, которая инициализирует DirectSound. Назовём её DXCreateSound.
Sub DXCreateSound(HWnd As Integer)
Set DirectSound = DirectX.DirectSoundCreate("")
DirectSound.SetCooperativeLevel HWnd, DSSCL_NORMAL
End Sub
Здесь всё просто. Сначала мы создаём объект DirectSound, а затем устанавливаем кооперативный левел так, что другие программы тоже могут использовать DirectSound. Далее напишем процедуру, которая удаляет DirectSound.
Sub DXDestroySound()
Set DirectSound = Nothing
End Sub
Создавать и удалять DS мы уже можем. Теперь хорошо бы написать процедуры непосредственно для работы со звуком. Сперва мы напишем процедуру для указания и определения количества звуковых буферов.
Sub DXSetSoundBuffers(Buffers As Integer)
ReDim Preserve SoundBuffer(Buffers)
End Sub
Function DXGetSoundBuffers() As Integer
DXGetSoundBuffers = UBound(SoundBuffer)
End Function
Здесь мы просто изменяем или определяем количество элементов в массиве. Теперь можно написать процедуры для загрузки и проигрывания файлов.
Sub DXLoadSound(Buffer As Integer, SoundFile As String, HZ As Integer, Bit As Integer, Channels As Integer)
Dim BufferDesc As DSBUFFERDESC
BufferDesc.lFlags = DSBCAPS_CTRLFREQUENCY Or DSBCAPS_CTRLPAN Or DSBCAPS_CTRLVOLUME Or DSBCAPS_STATIC
BufferDesc.fxFormat.nFormatTag = 1 'WAVE_FORMAT_PCM
BufferDesc.fxFormat.nChannels = Channels
BufferDesc.fxFormat.lSamplesPerSec = HZ
BufferDesc.fxFormat.nBitsPerSample = Bit
BufferDesc.fxFormat.nBlockAlign = BufferDesc.fxFormat.nBitsPerSample / 8 * BufferDesc.fxFormat.nChannels
BufferDesc.fxFormat.lAvgBytesPerSec = BufferDesc.fxFormat.lSamplesPerSec * BufferDesc.fxFormat.nBlockAlign
Set SoundBuffer(Buffer) = DirectSound.CreateSoundBufferFromFile(SoundFile, BufferDesc)
End Sub
Sub DXPlaySound(BufferNum As Integer, PlayMode As Integer)
SoundBuffer(BufferNum).Play PlayMode
End Sub
Sub DXStopSound(BufferNum As Integer)
SoundBuffer(BufferNum).Stop
End Sub
В первой процедуре мы сначала объявляем переменную BufferDesc, которая содержит
всю информацию о текущем звуке. Потом меняем эти параметры в соответствии с указанными и создаём
новый буфер. В DXPlaySound мы вызываем метод Play у указанного буфера для проигрывания звука, при это
указываем ему в качестве параметра номер буфера и способ проигрывания: 0 - проиграть один раз,
1 - проигрывать бесконечно. В последней процедуре тоже самое, но вызывается метод Stop.
Теперь напишем процедуры для изменения баланса и громкости буферов.
Sub DXSetSoundBufferPan(Buffer As Integer, PanVolume As Integer)
Select Case PanVolume
Case 0
SoundBuffer(Buffer).SetPan -10000
Case 100
SoundBuffer(Buffer).SetPan 10000
Case Else
SoundBuffer(Buffer).SetPan (100 * PanVolume) - 5000
End Select
End Sub
Sub DXSetSoundBufferVolume(Buffer As Integer, Volume As Integer)
SoundBuffer(Buffer).SetVolume (60 * Volume) - 6000
End Sub
Здесь кончается написание кода для модуля. Теперь приступим к форме. Создайте и расположите элементы управления примерно как на рисунке.
Поменяйте параметр Name у кнопок на "Play" с индексами от 0 до 3, у полос прокрутки громкости на "Vol", у полос прокрутки баланса на "Pan", у надписей, отображающих их состояние на "VolV" и "PanV" также с индексами 0-3. Теперь напишем код для Form_Load и Form_Unload.
Private Sub Form_Load()
'Инициализируем DirectSound
DXCreateSound Me.HWnd
'Устанавливаем количество буферов
DXSetSoundBuffers 3
'Загружаем 4 звука в 4 буфера
DXLoadSound 0, App.Path & "\Sounds\bigwarning.wav", 11025, 8, 1
DXLoadSound 1, App.Path & "\Sounds\sparks.wav", 11025, 8, 1
DXLoadSound 2, App.Path & "\Sounds\dronemachine3.wav", 11025, 8, 1
DXLoadSound 3, App.Path & "\Sounds\labdrone1.wav", 11025, 8, 1
End Sub
Private Sub Form_Unload(Cancel As Integer)
'Уничтожаем DS
DXDestroySound
End Sub
Теперь код для кнопок.
Private Sub Play_Click(Index As Integer)
If Play(Index).FontBold = False Then
Play(Index).FontBold = True
DXPlaySound Index, 1
Else
Play(Index).FontBold = False
DXStopSound Index
End If
End Sub
Здесь мы определяем параметр FontBold у кнопки: если False, то звук не играет. Тогда параметру FontBold присваивается значение True, и начинает играть звук. Если параметр FontBold True, то всё наоборот.
Private Sub Vol_Change(Index As Integer)
DXSetSoundBufferVolume Index, Vol(Index).Value
VolV(Index).Caption = Vol(Index).Value
End Sub
Private Sub Vol_Scroll(Index As Integer)
Vol_Change Index
End Sub
В процедуре Vol_Change мы меняем громкость буфера и отображаем текущее состояние. Во второй процедуре мы обращаемся к первой, чтобы изменять громкость во время перемещения полосы прокрутки мышкой.
Private Sub Pan_Change(Index As Integer)
DXSetSoundBufferPan Index, Pan(Index).Value
PanV(Index).Caption = Pan(Index).Value - 50
End Sub
Private Sub Pan_Scroll(Index As Integer)
Pan_Change Index
End Sub
Здесь тоже самое, только с балансом.
Теперь программа должна работать. Сохраните её перед запуском на всякий случай (при некоторых ошибках VB вылетает) и посмотрите, что получилось. Во время работы программа должна выглядеть примерно так.
На этом всё. Исходные коды можно скачать с этой страницы.
Автор: Павел Николаевич
E-mail: pasha_nik@mail.ru