home *** CD-ROM | disk | FTP | other *** search
/ Microsoft DirectX SDK 7.0 / Dx7.bin / DXF / samples / multimedia / vbsamples / dsound / src / streamfrom / form1.frm (.txt) next >
Encoding:
Visual Basic Form  |  1999-08-06  |  15.5 KB  |  323 lines

  1. VERSION 5.00
  2. Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "comdlg32.ocx"
  3. Begin VB.Form Form1 
  4.    BorderStyle     =   3  'Fixed Dialog
  5.    Caption         =   "Stream From File"
  6.    ClientHeight    =   2430
  7.    ClientLeft      =   45
  8.    ClientTop       =   330
  9.    ClientWidth     =   2430
  10.    Icon            =   "form1.frx":0000
  11.    LinkTopic       =   "Form1"
  12.    MaxButton       =   0   'False
  13.    MinButton       =   0   'False
  14.    ScaleHeight     =   2430
  15.    ScaleWidth      =   2430
  16.    StartUpPosition =   2  'CenterScreen
  17.    Begin VB.CommandButton cmdStop 
  18.       Caption         =   "Stop"
  19.       Enabled         =   0   'False
  20.       Height          =   420
  21.       Left            =   600
  22.       TabIndex        =   2
  23.       Top             =   1740
  24.       Width           =   1185
  25.    End
  26.    Begin MSComDlg.CommonDialog cdlgLoad 
  27.       Left            =   1920
  28.       Top             =   1200
  29.       _ExtentX        =   847
  30.       _ExtentY        =   847
  31.       _Version        =   393216
  32.    End
  33.    Begin VB.CommandButton cmdPlay 
  34.       Caption         =   "Play File"
  35.       Enabled         =   0   'False
  36.       Height          =   420
  37.       Left            =   600
  38.       TabIndex        =   1
  39.       Top             =   1200
  40.       Width           =   1185
  41.    End
  42.    Begin VB.CommandButton cmdLoad 
  43.       Caption         =   "Load File"
  44.       Height          =   420
  45.       Left            =   600
  46.       TabIndex        =   0
  47.       Top             =   660
  48.       Width           =   1185
  49.    End
  50.    Begin VB.Label lblTitle 
  51.       Alignment       =   2  'Center
  52.       BackColor       =   &H00FFFFC0&
  53.       BorderStyle     =   1  'Fixed Single
  54.       Caption         =   "None"
  55.       ForeColor       =   &H00800000&
  56.       Height          =   255
  57.       Left            =   120
  58.       TabIndex        =   3
  59.       Top             =   240
  60.       Width           =   2175
  61.    End
  62. Attribute VB_Name = "Form1"
  63. Attribute VB_GlobalNameSpace = False
  64. Attribute VB_Creatable = False
  65. Attribute VB_PredeclaredId = True
  66. Attribute VB_Exposed = False
  67. Option Explicit
  68. '''''''''''''''''''''''''''''''''''''''''''''
  69. 'This sample shows how to stream from a file.
  70. '''''''''''''''''''''''''''''''''''''''''''''
  71. 'Initialize variables, constants, and user-defined types.
  72. Implements DirectXEvent                         'This enables the form to receive events from DirectX.
  73. Const NUM_POSITIONS = 16                        'Used for making 16 (0 based) notification positions.
  74. Private Declare Sub RtlZeroMemory Lib "kernel32" (dest As Any, ByVal cbSize As Long)
  75. Private Type FileHeader                         'File header structure for wave files.
  76.     dwRiff As Long
  77.     dwFileSize As Long
  78.     dwWave As Long
  79.     dwFormat As Long
  80.     dwFormatLength As Long
  81. End Type
  82. Private Type FileFormat                         'File format structure for wave files
  83.         wFormatTag As Integer
  84.         nChannels As Integer
  85.         nSamplesPerSec As Long
  86.         nAvgBytesPerSec As Long
  87.         nBlockAlign As Integer
  88.         wBitsPerSample As Integer
  89. End Type
  90.      
  91. Private Type HeaderChunk                        'Header chunk format for wave files
  92.     dwType As Long
  93.     dwLen As Long
  94. End Type
  95. Dim dx As New DirectX7                          'DirectX object.
  96. Dim ds As DirectSound                           'Direct Sound object.
  97. Dim dsb As DirectSoundBuffer                    'Direct sound buffer object.
  98. Dim dsbPrimary As DirectSoundBuffer             'Primary direct sound buffer object.
  99. Dim dsbd As DSBUFFERDESC                        'Direct sound buffer description.
  100. Dim Format As WAVEFORMATEX                      'Wave format EX structure.
  101. Dim Header As FileHeader                        'Wave file header variable.
  102. Dim HdrFormat  As FileFormat
  103. Dim hEvent(1) As Long                           'Array to hold the event handle.
  104. Dim psa(1) As DSBPOSITIONNOTIFY                 'Notify position array.
  105. Dim FileFree As Long                            'Holds the handle to the file.
  106. Dim Buffer() As Byte                            'Dynamic byte array for the wave data buffer.
  107. Dim lngNotificationSize As Long
  108. Dim lngLastBit As Long
  109. Dim fEnd As Long
  110. Dim dwDataLength As Long
  111. Dim m_bLoop As Boolean
  112. Private Sub cmdPlay_Click()
  113.     'This is where the buffers are initialized for playback.
  114.     If CreateStreamingBuffer Then               'Call the function that creates the streaming buffer. If it succeeds, continue.
  115.         fEnd = 0
  116.         dsb.SetCurrentPosition 0
  117.         If m_bLoop Then
  118.             dsb.Play DSBPLAY_LOOPING                'Start the secondary buffer, and keep it looping as well.
  119.             cmdLoad.Enabled = False                 'Disable the load button during playback.
  120.             cmdPlay.Enabled = False                 'Disable the play button during playback.
  121.             cmdStop.Enabled = True                  'Enable the stop button.
  122.         Else
  123.             dsb.Play DSBPLAY_DEFAULT                'Start the secondary buffer
  124.         End If
  125.     End If
  126. End Sub
  127. Private Sub cmdStop_Click()
  128.         
  129.     dsb.Stop                                    'Stop the direct sound buffer.
  130.     cmdLoad.Enabled = True                      'Enable the load button.
  131.     cmdStop.Enabled = False                     'Disable the stop button.
  132.     cmdPlay.Enabled = True                      'Enable the play button.
  133. End Sub
  134. Private Sub Form_Load()
  135.     'Sets up the primary buffer & DX events.
  136.     On Local Error GoTo ErrOut
  137.     Dim dsbdPrimary As DSBUFFERDESC             'Used to initialize the primary buffer.
  138.     Dim WavFormat As WAVEFORMATEX               'Also used to init the primary buffer.
  139.         
  140.     Me.Show                                     'Make sure that the loading of the form is complete.
  141.     cmdLoad.Enabled = True                      'Enable the load button.
  142.     cmdPlay.Enabled = False                     'Disable the play button.
  143.     cmdStop.Enabled = False                     'Disable the stop button.
  144.     hEvent(0) = dx.CreateEvent(Me)              'Create an event handle, and attach it to this form.
  145.     hEvent(1) = dx.CreateEvent(Me)              'Create an event handle, and attach it to this form.
  146.     Set ds = dx.DirectSoundCreate(vbNullString) 'Create the direct sound object using the default driver.
  147.     ds.SetCooperativeLevel Me.hWnd, DSSCL_PRIORITY
  148.                                                 'Set the cooperative level to the forms window handle.
  149.                                                 'Create the primary buffer.
  150.     Exit Sub
  151. ErrOut:
  152.     MsgBox "Cannot create the primary sound device.  Exiting this application.", vbOKOnly Or vbCritical, "Cannot create"
  153.     End
  154. End Sub
  155. Private Sub cmdLoad_Click()
  156.     'This begins the loading process for the wave file to be played back.
  157.     On Local Error GoTo ErrorHandler            'Make sure to handle if cancel is pressed.
  158.     With cdlgLoad                               'Set the flags for the common dialog box.
  159.         .CancelError = True                     'Make sure canel will be detected if it is clicked.
  160.         .Filter = "(*.WAV)|*.WAV"               'Set the filters for the dialog box.
  161.         .flags = cdlOFNHideReadOnly Or cdlOFNFileMustExist
  162.                                                 'Hide the read only checkbox, and the user has to enter a file that already exists.
  163.         .ShowOpen                               'Show the common dialog box.
  164.     End With
  165.     cmdPlay.Enabled = True                      'Enable the play button.
  166.                                                 'Display the selected wave file.
  167.         
  168.     Dim l_d As Long
  169.     l_d = 1
  170.     Do While InStr(l_d, cdlgLoad.FileName, "\", vbBinaryCompare) <> 0
  171.         l_d = l_d + 1                           'Loop until the last \ is found
  172.     Loop
  173.         
  174.     lblTitle = Right(cdlgLoad.FileName, Len(cdlgLoad.FileName) - (l_d - 1))
  175.         
  176.     Exit Sub                                    'Exit the subroutine.
  177. ErrorHandler:                                   'Set up error handling for a cancel error.
  178.     If Err.Number = cdlCancel Then              'If cancel was selected,
  179.         Exit Sub                                'Exit the sub.
  180.     End If
  181. End Sub
  182. Private Function CreateStreamingBuffer() As Boolean
  183.     'This sub sets up the streaming buffer.
  184.     Dim lngCount As Long                        'Standard count variable.
  185.     Close #FileFree                             'Close the file in case it is open.
  186.     Set dsb = Nothing                           'Set the secondary buffer to nothing.
  187.     Format = FillFormat()                       'Fill the format structure by calling the FillFormat function.
  188.     If Format.nFormatTag <> WAVE_FORMAT_PCM Then
  189.                                                 'If an unsupported format is attempting to load,
  190.         MsgBox "Unsupported format"             'display this message.
  191.         Close #FileFree                         'Close the open file.
  192.         Exit Function                           'Exit the sub.
  193.     End If
  194.     lngNotificationSize = (Format.lSamplesPerSec * 2) \ 2
  195.     dsbd.lBufferBytes = lngNotificationSize * 2
  196.     lngLastBit = (dwDataLength \ dsbd.lBufferBytes) * dsbd.lBufferBytes
  197.                                                 'Create a half second buffer.
  198.     dsbd.lFlags = DSBCAPS_GETCURRENTPOSITION2 Or DSBCAPS_CTRLPOSITIONNOTIFY
  199.                                                 'Set the flags for the buffer. Flags needed are DSBCAPS_GLOBALFOCUS,
  200.                                                 'DSBCAPS_GETCURRENTPOSITION2 for accurate notification position tracking,
  201.                                                 'and DSBCAPS_CTRLPOSITIONNOTIFY to let Direct Sound know we are keeping
  202.                                                 'track of the position during playback.
  203.     Set dsb = ds.CreateSoundBuffer(dsbd, Format)
  204.                                                 'Create the buffer with the above structures.
  205.     If dwDataLength >= dsbd.lBufferBytes Then
  206.         psa(0).lOffset = (dsbd.lBufferBytes) \ 2
  207.         psa(0).hEventNotify = hEvent(0)
  208.         psa(1).lOffset = (dsbd.lBufferBytes - 1)
  209.         psa(1).hEventNotify = hEvent(1)
  210.             
  211.         dsb.SetNotificationPositions 2, psa()       'Set the notification positions for the buffer.
  212.                                                     'Set the playback position to the middle of the buffer to trigger the first event.
  213.     End If
  214.     ReDim Buffer(dsbd.lBufferBytes - 1)         'Resize the wave data buffer to the size of the direct sound buffer
  215.     cmdPlay.Enabled = True                      'Enable the play button.
  216.     CreateStreamingBuffer = True                'The function succeeded.
  217.     m_bLoop = True
  218.     If dwDataLength < dsbd.lBufferBytes Then
  219.         ReDim Buffer(dwDataLength - 1)
  220.         m_bLoop = False
  221.     End If
  222.     'get our first chunk of data
  223.     Get #FileFree, , Buffer             'Read the wave data into the buffer array.
  224.     dsb.WriteBuffer 0, UBound(Buffer), Buffer(0), DSBLOCK_DEFAULT
  225. End Function
  226. Private Function FillFormat() As WAVEFORMATEX
  227.         
  228.     Dim chunk As HeaderChunk
  229.     Dim by As Byte
  230.     Dim i As Long
  231.     'This reads the header info from a wave file, and returns a filled WAVEFORMATEX structure from this info.
  232.     Close #FileFree
  233.     FileFree = FreeFile                         'Get a free file handle.
  234.     Open cdlgLoad.FileName For Binary Access Read As #FileFree
  235.                                                 'Open the selected wave file for binary input.
  236.     Get #FileFree, , Header                     'Get the wave header data, and fill the header structure with the info.
  237.     If Header.dwRiff <> &H46464952 Then         'This is not a valid Riff
  238.         Exit Function
  239.     End If
  240.     If Header.dwWave <> &H45564157 Then         'This is not a valid Wave
  241.         Exit Function
  242.     End If
  243.     Dim lCount As Long
  244.     If Header.dwFormatLength < 16 Then          'We will only handle formats that are 16 bytes or greater
  245.         Exit Function
  246.     End If
  247.     Get #FileFree, , HdrFormat                  'Get the wave format data
  248.                     
  249.     'get rid of extra format bytes
  250.     For i = 1 To Header.dwFormatLength - 16
  251.         Get #FileFree, , by
  252.     Next
  253.     Get #FileFree, , chunk
  254.     Do While chunk.dwType <> &H61746164 'DATA chunck
  255.         For i = 1 To chunk.dwLen
  256.             Get #FileFree, , by
  257.         Next
  258.         Get #FileFree, , chunk
  259.     Loop
  260.     dwDataLength = chunk.dwLen
  261.     With FillFormat                             'Fill the WAVEFORMATEX structure with the info from the file header.
  262.         .lAvgBytesPerSec = HdrFormat.nAvgBytesPerSec
  263.         .lExtra = 0
  264.         .lSamplesPerSec = HdrFormat.nSamplesPerSec
  265.         .nBitsPerSample = HdrFormat.wBitsPerSample
  266.         .nBlockAlign = HdrFormat.nBlockAlign
  267.         .nChannels = HdrFormat.nChannels
  268.         .nFormatTag = HdrFormat.wFormatTag
  269.     End With
  270.     'The file is left open to keep the file read position at the start of the wave file data.
  271. End Function
  272. Private Sub DirectXEvent_DXCallback(ByVal eventid As Long)
  273.           
  274.     'This is the callback sub for the DirectX event. The buffer data is written to the direct sound buffer here.
  275.     Select Case eventid
  276.         Case hEvent(0)                          'Event 0 has fired.
  277.         
  278.             If Loc(FileFree) > lngLastBit Then 'This is the last section of the buffer
  279.                 fEnd = fEnd + 1
  280.                 Get #FileFree, , Buffer 'Read in the buffer
  281.                 Dim dwStartSilence As Long
  282.                 Dim dwLenSilence As Long
  283.                 dwStartSilence = dwDataLength - lngLastBit
  284.                 dwLenSilence = dsbd.lBufferBytes - dwStartSilence
  285.                 Call RtlZeroMemory(Buffer(dwStartSilence), dwLenSilence) 'Zero the buffer out
  286.             Else
  287.                 Get #FileFree, , Buffer             'Read the wave data into the buffer array.
  288.             End If
  289.             Dim j As Long
  290.             j = ((UBound(Buffer) + 1) \ 2)
  291.             j = j + j Mod 2
  292.             dsb.WriteBuffer 0, j, Buffer(0), DSBLOCK_DEFAULT
  293.             'Write to the buffer, using half of the data contained
  294.             'in the wave data buffer, give it the starting element of the buffer,
  295.             'and use the default flag for the buffer.
  296.             
  297.         Case hEvent(1)
  298.             'Event 1 has fired.
  299.                 Dim h As Long
  300.                 h = ((UBound(Buffer) + 1) \ 2)
  301.                 dsb.WriteBuffer h, h, Buffer(0), DSBLOCK_DEFAULT
  302.                 If fEnd = 2 Then
  303.                     cmdPlay.Enabled = True
  304.                     cmdLoad.Enabled = True
  305.                     cmdStop.Enabled = False
  306.                     dsb.Stop
  307.                 End If
  308.             
  309.     End Select
  310. End Sub
  311. Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  312.     'Make sure that everything is stopped and reset before exiting.
  313.     Set dsb = Nothing                           'Set the secondary buffer to nothing.
  314.     Set dsbPrimary = Nothing                    'Set the primary buffer object to nothing.
  315.     If hEvent(0) <> 0 Then                      'If event handle zero exists,
  316.         dx.DestroyEvent hEvent(0)               'destroy it.
  317.     End If
  318.     If hEvent(1) <> 0 Then                      'If event handle one exists,
  319.         dx.DestroyEvent hEvent(1)               'destroy it.
  320.     End If
  321.     Set dx = Nothing                            'Set the DirectX object to nothing.
  322. End Sub
  323.