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

Hosted by uCoz