Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - VBA

Страница: 1 |

 

  Вопрос: две звуковухи Добавлено: 15.09.08 15:07  

Автор вопроса:  litzter
Привет. Суть проблемы следующая: имеется две звуковушки(одна интегрированная), нужно посредством скрипта отправить на одну 1.wav, на другую 2.wav. Т.е. в реальности это выглядит как две, скажем, кнопки. И две пары наушников. Нажимая на одну, одна мелодия идет на одни наушники. Нажимая на другую - соответственно на вторые и уже другая мелодия. Я как человек незнакомый с VBA в принципе, научился только проигрываться wav'ы посредством winmm.lib и PlaySound'а. Буду рад любому совету.

Ответить

  Ответы Всего ответов: 10  

Номер ответа: 1
Автор ответа:
 mc-black



ICQ: 308-534-060 

Вопросов: 20
Ответов: 1860
 Web-сайт: mc-black.narod.ru/dzp.htm
 Профиль | | #1
Добавлено: 18.09.08 11:27
Ты так уверен, что железячная конфигурация тебе позволит эту причуду? Ответ: в рамках VBA это неразрешимая задача в принципе.

Ответить

Номер ответа: 2
Автор ответа:
 litzter



Вопросов: 1
Ответов: 6
 Профиль | | #2 Добавлено: 18.09.08 11:42
Причем тут железо. Есть АПИ, есть дескрипторы устройств. Значит к ним можно обратиться, используя функции мультимедийных библиотек. Я все еще мучаюсь с VBA, как с языком, но вот например есть функция - waveOutOpen. The waveOutOpen function opens the given waveform-audio output device for playback.

MMRESULT waveOutOpen(
  LPHWAVEOUT phwo,
  UINT_PTR uDeviceID,
  LPWAVEFORMATEX pwfx,
  ;DWORD_PTR dwCallback,
  ;DWORD_PTR dwCallbackInstance,
  ;DWORD fdwOpen
);

uDeviceID

Identifier of the waveform-audio output device to open. It can be either a device identifier or a handle of an open waveform-audio input device. You can use the following flag instead of a device identifier.

Т.е. это же дескриптор устройства, я правильно понял? Так ведь можно тогда не указывать автовыбор WAVE_MAPPER, а явно, какой девайс нужен. Разные кнопки - разные значения аргументов.

Ответить

Номер ответа: 3
Автор ответа:
 litzter



Вопросов: 1
Ответов: 6
 Профиль | | #3 Добавлено: 18.09.08 11:44
По крайней мере на си тоже самое пишется за минуты.

Ответить

Номер ответа: 4
Автор ответа:
 mc-black



ICQ: 308-534-060 

Вопросов: 20
Ответов: 1860
 Web-сайт: mc-black.narod.ru/dzp.htm
 Профиль | | #4
Добавлено: 19.09.08 12:21
winmm.dll, ясно. У меня есть сомнения самой возможности сущесвования в одной системе двух и более АКТИВНЫХ аудиоустройств. есть мнение, что одновременно система не даст работать обоим устройствам. Или нет (докажите)?

Ответить

Номер ответа: 5
Автор ответа:
 litzter



Вопросов: 1
Ответов: 6
 Профиль | | #5 Добавлено: 19.09.08 12:46
Технически - это возможно. Ведь можно же к примеру два модема подключить или монитора? На практике же в настройках звука всегда выбирается один из двух доступных на системе драйверов. Но это про глобальный, системный, вывод. В отдельных же, продвинутых, приложениях можно напрямую указать, какое устройство использовать. Например WinAmp -> настройки -> плагины -> вывод -> directsound. Ставим два проигрывателя, в каждом указываем свое устройство вывода и два человека слушают одновременно разную музыку. Правда с возможными проблемами. Но ведь работает. По аналогии, в задаче - это будут две кнопки с различными файлами(mmioOpen) и устройствами на вывод(waveOutOpen) Разобрался вроде с VBA, но не работает)) Продолжаю ковыряться..

Ответить

Номер ответа: 6
Автор ответа:
 litzter



Вопросов: 1
Ответов: 6
 Профиль | | #6 Добавлено: 19.09.08 13:32
Вывел звук, осталось найти вторые наушники и вынесу вердикт)

Ответить

Номер ответа: 7
Автор ответа:
 litzter



Вопросов: 1
Ответов: 6
 Профиль | | #7 Добавлено: 19.09.08 13:35
Пардон, не знаю как тут редактировать сообщения. В общем все работает.

Ответить

Номер ответа: 8
Автор ответа:
 mc-black



ICQ: 308-534-060 

Вопросов: 20
Ответов: 1860
 Web-сайт: mc-black.narod.ru/dzp.htm
 Профиль | | #8
Добавлено: 19.09.08 14:21
Молодец, что разобрался с нетривиальным вопросом. Код на VBA или на Си здесь возможно вложить? Я про определение аудиоустройств и их идентификаторов.

Ответить

Номер ответа: 9
Автор ответа:
 litzter



Вопросов: 1
Ответов: 6
 Профиль | | #9 Добавлено: 19.09.08 15:34
  1.  
  2. Private Type mmioinfo
  3.     dwFlags     As Long
  4.     fccIOProc   As Long
  5.     pIOProc     As Long
  6.     wErrorRet   As Long
  7.     htask       As Long
  8.     cchBuffer   As Long
  9.     pchBuffer   As String
  10.     pchNext     As String
  11.     pchEndRead  As String
  12.     pchEndWrite As String
  13.     lBufOffset  As Long
  14.     lDiskOffset As Long
  15.     adwInfo(4)  As Long
  16.     dwReserved1 As Long
  17.     dwReserved2 As Long
  18.     hmmio       As Long
  19. End Type
  20.     
  21. Private Type MMCKINFO
  22.     ckid         As Long
  23.     ckSize       As Long
  24.     fccType      As Long
  25.     dwDataOffset As Long
  26.     dwFlags      As Long
  27. End Type
  28.     
  29. Private Type WAVEFORMAT
  30.     wFormatTag      As Integer
  31.     nChannels       As Integer
  32.     nSamplesPerSec  As Long
  33.     nAvgBytesPerSec As Long
  34.     nBlockAlign     As Integer
  35.     wBitsPerSample  As Integer
  36.     cbSize          As Integer
  37. End Type
  38.     
  39. Private Type WAVEHDR
  40.     lpData          As Long
  41.     dwBufferLength  As Long
  42.     dwBytesRecorded As Long
  43.     dwUser          As Long
  44.     dwFlags         As Long
  45.     dwLoops         As Long
  46.     lpNext          As Long
  47.     Reserved        As Long
  48. End Type
  49.  
  50.  
  51. Private Declare Function mmioOpen Lib "winmm.dll" Alias "mmioOpenA" (ByVal szFileName As String, lpmmioinfo As mmioinfo, ByVal dwOpenFlags As Long) As Long
  52. Private Declare Function mmioStringToFOURCC Lib "winmm.dll" Alias "mmioStringToFOURCCA" (ByVal sz As String, ByVal uFlags As Long) As Long
  53. Private Declare Function mmioDescendParent Lib "winmm.dll" Alias "mmioDescend" (ByVal hmmio As Long, lpck As MMCKINFO, ByVal x As Long, ByVal uFlags As Long) As Long
  54. Private Declare Function mmioDescend Lib "winmm.dll" (ByVal hmmio As Long, lpck As MMCKINFO, lpckParent As MMCKINFO, ByVal uFlags As Long) As Long
  55. Private Declare Function mmioAscend Lib "winmm.dll" (ByVal hmmio As Long, lpck As MMCKINFO, ByVal uFlags As Long) As Long
  56. Private Declare Function mmioSeek Lib "winmm.dll" (ByVal hmmio As Long, ByVal lOffset As Long, ByVal iOrigin As Long) As Long
  57. Private Declare Function mmioRead Lib "winmm.dll" (ByVal hmmio As Long, ByVal pch As Long, ByVal cch As Long) As Long
  58. Private Declare Function mmioReadString Lib "winmm.dll" Alias "mmioRead" (ByVal hmmio As Long, ByVal pch As String, ByVal cch As Long) As Long
  59. Private Declare Function waveOutOpen Lib "winmm.dll" (hWaveOut As Long, ByVal uDeviceID As Long, ByVal format As String, ByVal dwCallback As Long, ByRef fPlaying As Boolean, ByVal dwFlags As Long) As Long
  60. Private Declare Function waveOutGetErrorText Lib "winmm.dll" Alias "waveInGetErrorTextA" (ByVal err As Long, ByVal lpText As String, ByVal uSize As Long) As Long
  61. Private Declare Function waveOutPrepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
  62. Private Declare Function waveOutUnprepareHeader Lib "winmm.dll" (ByVal hWaveIn As Long, lpWaveInHdr As WAVEHDR, ByVal uSize As Long) As Long
  63. Private Declare Function waveOutWrite Lib "winmm.dll" (ByVal hWaveOut As Long, lpWaveOutHdr As WAVEHDR, ByVal uSize As Long) As Long
  64. Private Declare Function waveOutClose Lib "winmm.dll" (ByVal hWaveIn As Long) As Long
  65. Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
  66. Private Declare Function GlobalLock Lib "kernel32" (ByVal hmem As Long) As Long
  67. Private Declare Function GlobalFree Lib "kernel32" (ByVal hmem As Long) As Long
  68. Private Declare Sub CopyStructFromString Lib "kernel32" Alias "RtlMoveMemory" (dest As Any, ByVal source As String, ByVal cb As Long)
  69.  
  70.  
  71.  
  72. Const BUFFER_SECONDS = 0.1
  73. Const NUM_BUFFERS = 5
  74. Const MMIO_READ = &H0
  75. Const MMIO_FINDCHUNK = &H10
  76. Const CALLBACK_WINDOW = &H10000
  77. Const MMSYSERR_NOERROR = 0
  78. Const SEEK_CUR = 1
  79. Const SEEK_END = 2
  80. Const SEEK_SET = 0
  81.     
  82. Dim rc                      As Long         ' Êîä âîçâðàòà
  83. Dim hWaveOut                As Long         ' waveout õýíäë
  84. Dim hmmioIn                 As Long         ' õýíäë ôàéëà
  85. Dim mmioinf                 As mmioinfo
  86. Dim mmckinfoParentIn        As MMCKINFO
  87. Dim mmckinfoSubchunkIn      As MMCKINFO
  88. Dim formatBuffer            As String * 50  ' áóôåð õðàíåíèÿ ôîðìàòà
  89. Dim format                  As WAVEFORMAT   ' ôîðìàò
  90. Dim dataOffset              As Long         ' íà÷àëî àóäèî ôàéëà îòíîñèòåëüíî wave ôàéëà
  91. Dim audioLength             As Long         ' ÷èñëî áàéò àóäèî äàòû
  92. Dim bufferSize              As Long         ' ðàçìåð âûõîäíîãî áóôåðà
  93. Dim fPlaying                As Boolean      ' ôëàã, ïðîèãðûâàåòñÿ ëè ñåé÷àñ ôàéë
  94. Dim startPos                As Long         ' ïîçèöèÿ ñ êîòîðîé íà÷èëè ïðîèãðûâàòü ôàéë
  95. Dim msg                     As String * 250 ' áóôåð ñîîáùåíèÿ
  96. Dim hmem(1 To NUM_BUFFERS)  As Long         ' õýíäëû ïàìÿòè
  97. Dim pmem(1 To NUM_BUFFERS)  As Long         ' óêàçàòåëè ïàìÿòè
  98. Dim hdr(1 To NUM_BUFFERS)   As WAVEHDR      ' çàãîëîâêè
  99.  
  100.  
  101. Public Function Play(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByRef wavhdr As WAVEHDR) As Long
  102.     
  103.     Static dataRemaining As Long
  104.     
  105.     If (uMsg = MM_WOM_DONE) Then
  106.         If (fPlaying = True) Then
  107.             'Îïðåäåëÿåì ñêîëüêî îñòàëîñü ÷èòàòü
  108.             dataRemaining = (dataOffset + audioLength - mmioSeek(hmmioIn, 0, SEEK_CUR))
  109.       
  110.             If (bufferSize < dataRemaining) Then
  111.                 rc = mmioRead(hmmioIn, wavhdr.lpData, bufferSize)
  112.             Else
  113.                 rc = mmioRead(hmmioIn, wavhdr.lpData, dataRemaining)
  114.                 fPlaying = False '&#207;&#229;&#240;&#229;&#241;&#242;&#224;&#229;&#236; &#239;&#240;&#238;&#232;&#227;&#240;&#251;&#226;&#224;&#242;&#252;
  115.             End If
  116.             
  117.             wavhdr.dwBufferLength = rc
  118.             rc = waveOutWrite(hWaveOut, wavhdr, Len(wavhdr)) '&#194;&#251;&#226;&#238;&#228;&#232;&#236;
  119.         Else
  120.             For i = 1 To NUM_BUFFERS
  121.                 waveOutUnprepareHeader hWaveOut, hdr(i), Len(hdr(i))
  122.             Next
  123.  
  124.             '&#199;&#224;&#234;&#240;&#251;&#226;&#224;&#229;&#236; &#243;&#241;&#242;&#240;&#238;&#233;&#241;&#242;&#226;&#238; &#232; &#244;&#224;&#233;&#235;
  125.             waveOutClose hWaveOut
  126.         End If
  127.     End If
  128.     
  129. End Function
  130.  
  131. Public Function Init(ByVal deviceID As Long)
  132.  
  133.     fPlaying = False
  134.     startPos = 0
  135.  
  136.     ' &#206;&#242;&#234;&#240;&#251;&#226;&#224;&#229;&#236; &#226;&#245;&#238;&#228;&#237;&#238;&#233; &#244;&#224;&#233;&#235;
  137.     hmmioIn = mmioOpen("D:\Program Files\QIP\Sounds\sndMsgSent.wav", mmioinf, MMIO_READ)
  138.     If (hmmioIn = Null) Then
  139.         Exit Function
  140.     End If
  141.     
  142.     ' &#207;&#240;&#238;&#226;&#229;&#240;&#255;&#229;&#236;, &#247;&#242;&#238; &#253;&#242;&#238; wave &#244;&#238;&#240;&#236;&#224;&#242;
  143.     mmckinfoParentIn.fccType = mmioStringToFOURCC("WAVE", 0)
  144.     rc = mmioDescendParent(hmmioIn, mmckinfoParentIn, 0, MMIO_FINDRIFF)
  145.     If (rc <> MMSYSERR_NOERROR) Then
  146.         Exit Function
  147.     End If
  148.     
  149.     ' &#207;&#238;&#235;&#243;&#247;&#224;&#229;&#236; &#244;&#238;&#240;&#236;&#224;&#242; &#224;&#243;&#228;&#232;&#238;
  150.     mmckinfoSubchunkIn.ckid = mmioStringToFOURCC("fmt", 0)
  151.     rc = mmioDescend(hmmioIn, mmckinfoSubchunkIn, mmckinfoParentIn, MMIO_FINDCHUNK)
  152.     If (rc <> MMSYSERR_NOERROR) Then
  153.         Exit Function
  154.     End If
  155.     
  156.     rc = mmioReadString(hmmioIn, formatBuffer, mmckinfoSubchunkIn.ckSize)
  157.     If (rc = -1) Then
  158.         Exit Function
  159.     End If
  160.     
  161.     rc = mmioAscend(hmmioIn, mmckinfoSubchunkIn, 0)
  162.     CopyStructFromString format, formatBuffer, Len(format)
  163.     
  164.     ' &#200;&#249;&#229;&#236; data
  165.     mmckinfoSubchunkIn.ckid = mmioStringToFOURCC("data", 0)
  166.     rc = mmioDescend(hmmioIn, mmckinfoSubchunkIn, mmckinfoParentIn, MMIO_FINDCHUNK)
  167.     If (rc <> MMSYSERR_NOERROR) Then
  168.         Exit Function
  169.     End If
  170.     
  171.     dataOffset = mmioSeek(hmmioIn, 0, SEEK_SET)
  172.     
  173.     ' &#207;&#238;&#235;&#243;&#247;&#224;&#229;&#236; &#240;&#224;&#231;&#236;&#229;&#240; &#224;&#243;&#228;&#232;&#238;
  174.     audioLength = mmckinfoSubchunkIn.ckSize
  175.     
  176.     ' &#194;&#251;&#228;&#229;&#235;&#255;&#229;&#236; &#224;&#243;&#228;&#232;&#238; &#225;&#243;&#244;&#229;&#240;
  177.     bufferSize = format.nSamplesPerSec * format.nBlockAlign * format.nChannels * BUFFER_SECONDS
  178.     bufferSize = bufferSize - (bufferSize Mod format.nBlockAlign)
  179.  
  180.     For i = 1 To (NUM_BUFFERS)
  181.         GlobalFree hmem(i)
  182.         hmem(i) = GlobalAlloc(0, bufferSize)
  183.         pmem(i) = GlobalLock(hmem(i))
  184.     Next
  185.     
  186.     '&#206;&#242;&#234;&#240;&#251;&#226;&#224;&#229;&#236; &#224;&#243;&#228;&#232;&#238; &#243;&#241;&#242;&#240;&#238;&#233;&#241;&#242;&#226;&#238; &#228;&#235;&#255; &#231;&#224;&#239;&#232;&#241;&#232;
  187.     rc = waveOutOpen(hWaveOut, deviceID, formatBuffer, hwnd, True, CALLBACK_WINDOW)
  188.     If (rc <> MMSYSERR_NOERROR) Then
  189.         waveOutGetErrorText rc, msg, Len(msg)
  190.         Exit Function
  191.     End If
  192.     
  193.     For i = 1 To NUM_BUFFERS
  194.         hdr(i).lpData = pmem(i)
  195.         hdr(i).dwBufferLength = bufferSize
  196.         hdr(i).dwFlags = 0 '&#193;&#243;&#244;&#229;&#240; &#239;&#238;&#228;&#227;&#238;&#242;&#238;&#226;&#235;&#229;&#237;
  197.         hdr(i).dwLoops = 0 '&#194; &#238;&#225;&#251;&#247;&#237;&#238;&#236; &#240;&#229;&#230;&#232;&#236;&#229;, &#225;&#229;&#231; &#246;&#232;&#234;&#235;&#238;&#226;, &#239;&#238;&#235;&#229; &#228;&#238;&#235;&#230;&#237;&#238; &#225;&#251;&#242;&#252; &#237;&#243;&#235;&#229;&#226;&#251;&#236;
  198.         
  199.         rc = waveOutPrepareHeader(hWaveOut, hdr(i), Len(hdr(i)))
  200.         If (rc <> MMSYSERR_NOERROR) Then
  201.             waveOutGetErrorText rc, msg, Len(msg)
  202.         End If
  203.     Next
  204.     
  205.     fPlaying = True
  206.     
  207.     '&#207;&#229;&#240;&#229;&#236;&#229;&#249;&#224;&#229;&#236; &#234;&#243;&#240;&#241;&#238;&#240; &#226; &#237;&#224;&#247;&#224;&#235;&#238; &#244;&#224;&#233;&#235;&#224;
  208.     startPos = mmioSeek(hmmioIn, 0, SEEK_CUR) - dataOffset
  209.         
  210.     '&#207;&#240;&#238;&#232;&#227;&#240;&#251;&#226;&#224;&#229;&#236;
  211.     For i = 1 To NUM_BUFFERS
  212.         Play hwnd, MM_WOM_DONE, 0, hdr(i)
  213.     Next
  214.  
  215. End Function



Вызывать соответственно через Init deviceID. Нумерация с 0. Если звуковухи две штуки, то соответственно диапазон значений 0-1. Комментарии побились, извиняюсь, нет времени поправить, возможно попозже. Как определить, какой идентификатор соответствует какому устройству, незнаю, не стояло такой задачи. Я отловил опытным путем.

Ответить

Номер ответа: 10
Автор ответа:
 mc-black



ICQ: 308-534-060 

Вопросов: 20
Ответов: 1860
 Web-сайт: mc-black.narod.ru/dzp.htm
 Профиль | | #10
Добавлено: 22.09.08 10:35
Спасибо.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам