Имя аудио устройства

Тема в разделе "WASM.AUDIO", создана пользователем _qwe8013, 12 июл 2017.

  1. _qwe8013

    _qwe8013 Member

    Публикаций:
    2
    Регистрация:
    30 ноя 2016
    Сообщения:
    112
    Пишу программу, работающую со звуком. Понадобилось мне имя устройства, юзаю waveOutGetDevCaps, в эту функцию передаю хендл полученный от waveOutOpen. Если в waveOutOpen использовать индекс устройства, то получаю правильно заполненное короткое имя и GUID имени. Но мне нужно указать WAVE_MAPPER в waveOutOpen, но в таком случае все GUID-ы нулевые, и короткое имя тоже не заполнено, как быть?

    PS
    Вызываемая копия функции - юникодная.
    Код (ASM):
    1.  
    2.     struct GUID
    3.  
    4.    Data1 dd ?
    5.    Data2 dw ?
    6.    Data3 dw ?
    7.    Data4 dq ?
    8.  
    9. ends
    10.  
    11. struct WAVEOUTCAPS2
    12.  
    13.    wMid dw ?
    14.    wPid dw ?
    15.    vDriverVersion dd ?
    16.    szPname du 32 dup (?)
    17.    dwFormats dd ?
    18.    wChannels dw ?
    19.    wReserved1 dw ?
    20.    dwSupport dd ?
    21.    ManufacturerGuid GUID
    22.    ProductGuid GUID
    23.    NameGuid GUID
    24.  
    25. ends
    26.  
    27. struct WAVEFORMATEX
    28.  
    29.    wFormatTag dw ?
    30.    nChannels dw ?
    31.    nSamplesPerSec dd ?
    32.    nAvgBytesPerSec dd ?
    33.    nBlockAlign dw ?
    34.    wBitsPerSample dw ?
    35.    cbSize dw ?
    36.  
    37. ends
    38.  
    39. ...
    40.  
    41.     mov [WaveFormat+WAVEFORMATEX.wFormatTag],WAVE_FORMAT_PCM
    42.     mov [WaveFormat+WAVEFORMATEX.nChannels],1
    43.     mov [WaveFormat+WAVEFORMATEX.nSamplesPerSec],44100
    44.     mov [WaveFormat+WAVEFORMATEX.nAvgBytesPerSec],44100*2
    45.     mov [WaveFormat+WAVEFORMATEX.nBlockAlign],2
    46.     mov [WaveFormat+WAVEFORMATEX.wBitsPerSample],16
    47.     and [WaveFormat+WAVEFORMATEX.cbSize],0
    48.  
    49.     lea rcx,[hWaveOut]
    50.     or rdx,WAVE_MAPPER
    51.     lea r8,[WaveFormat]
    52.     invoke waveOutOpen,rcx,rdx,r8,[Event],0,CALLBACK_EVENT
    53.     test rax,rax
    54.     je .Opened
    55.  
    56.    
    57.         invoke CloseHandle,[Event]
    58.    
    59.         lea rcx,[OpenError]
    60.         invoke wprintf,rcx,rdx
    61.    
    62.  
    63.     jmp .err
    64.     .Opened:
    65.  
    66.     lea rdx,[WaveOutCaps]
    67.     invoke waveOutGetDevCaps,[hWaveOut],rdx,sizeof.WAVEOUTCAPS2
    68.     test rax,rax
    69.     je .CapsGot
    70.  
    71.    
    72.         lea rcx,[CapsErr]
    73.         invoke wprintf,rcx
    74.    
    75.  
    76.     jmp .EndCaps
    77.     .CapsGot:
    78.  
    79.         int3
     
  2. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    1.922
    _qwe8013,

    waveOutGetDevCaps(WAVE_MAPPER) ?
     
  3. _qwe8013

    _qwe8013 Member

    Публикаций:
    2
    Регистрация:
    30 ноя 2016
    Сообщения:
    112
    Я передаю хендл, полученный при открытии WAVE_MAPPER функцией waveOutOpen в функцию waveOutGetDevCaps.
     
  4. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    1.922
    Туда можно WAVE_MAPPER передать.
     
  5. _qwe8013

    _qwe8013 Member

    Публикаций:
    2
    Регистрация:
    30 ноя 2016
    Сообщения:
    112
    Всё то же самое, правда ManufacturerGuid он выставляет не нулевым.
     
  6. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    422
    Вызывай waveOutGetID и ID уже передавай в waveOutGetDevCaps.
     
  7. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    422
    Проверил, это не будет работать. Можно попробовать отправить сообщение DRVM_MAPPER_PREFERRED_GET чтобы получить ID.
     
  8. _qwe8013

    _qwe8013 Member

    Публикаций:
    2
    Регистрация:
    30 ноя 2016
    Сообщения:
    112
    Решил вместо WAVE_MAPPER перечислить все устройства и вывести их имена, но для первого и единственного устройства у меня на компьютере waveOutGetDevCaps корректно заполняет ManufacturerGuid и ProductGuid, но NameGuid - нулевой.
     
  9. _qwe8013

    _qwe8013 Member

    Публикаций:
    2
    Регистрация:
    30 ноя 2016
    Сообщения:
    112
    Да, и как вообще искать имена по этим GUID-ам, в реестре таких GUID-ов нет.
     
  10. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    422
    _qwe8013, может быть проще задействовать DirectSound?
    Кажется это опциональное поле:
    Там же:
     
  11. _qwe8013

    _qwe8013 Member

    Публикаций:
    2
    Регистрация:
    30 ноя 2016
    Сообщения:
    112
    Там же COM, если не ошибаюсь, на асме будет не очень удобно.
     
  12. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    422
    Удобно. Если никто не скинет, сделаю примерчик позже. Если же просто перечисление, то COM даже не используется в явном виде.
    А прием с DRVM_MAPPER_PREFERRED_GET работает?
     
  13. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    422
    Код (ASM):
    1. format PE64
    2. entry start
    3.  
    4. include 'WIN64WX.inc'
    5.  
    6. struct GUID
    7.    Data1 dd ?
    8.    Data2 dw ?
    9.    Data3 dw ?
    10.    Data4 db 8 dup(?)
    11. ends
    12.  
    13. section '.idata' import data readable writeable
    14.  
    15. library kernel, 'kernel32.dll', \
    16.         dsound, 'dsound.dll', \
    17.         ole32, 'ole32.dll', \
    18.         msvcrt, 'msvcrt.dll'
    19.  
    20. import kernel,\
    21.        memcpy, 'RtlMoveMemory', \
    22.        ExitProcess, 'ExitProcess', \
    23.        WriteConsole, 'WriteConsoleW', \
    24.        GetStdHandle, 'GetStdHandle', \
    25.        lstrlen, 'lstrlenW'
    26.  
    27. import dsound, \
    28.        DirectSoundEnumerate, 3
    29.  
    30. import msvcrt, \
    31.        swprintf_s, 'swprintf_s'
    32.  
    33. import ole32, \
    34.        StringFromGUID2, 'StringFromGUID2'
    35.  
    36. section '.data' data readable writeable
    37.  
    38. hOut      dq ?;
    39. pszFormat du "%s: %s", 13, 10, 0  ; Формат [Имя: GUID]
    40.  
    41. section '.text' code readable executable
    42.  
    43. proc start
    44.  
    45.     invoke GetStdHandle, STD_OUTPUT_HANDLE
    46.     mov [hOut], rax
    47.  
    48.     invoke DirectSoundEnumerate, DSEnumCallback ; Запуск перечисления
    49.  
    50.     invoke ExitProcess, 0;
    51.  
    52.     ret
    53.  
    54. endp
    55.  
    56. ; Функция перечисления
    57. proc DSEnumCallback, lpGuid, lpcstrDescription, lpcstrModule, lpContext
    58.     locals
    59.         cBuffer   du 128 dup(?)            ; Буфер для выходной строки
    60.         cGUID     du 41 dup(?)             ; Буфер для строкового представления GUID
    61.         tGuid     GUID 0, 0, 0, 8 dup (0)
    62.         dwWritten dw ?
    63.     endl
    64.  
    65.     mov [lpGuid], rcx;
    66.     mov [lpcstrDescription], rdx;
    67.  
    68.     .if ([lpGuid])
    69.         invoke memcpy, addr tGuid, [lpGuid], sizeof.GUID
    70.     .endif
    71.  
    72.     invoke StringFromGUID2, addr tGuid, addr cGUID, 41  ; Переводим GUID в строку
    73.     cinvoke swprintf_s, addr cBuffer, 128, pszFormat, [lpcstrDescription], addr cGUID
    74.  
    75.     invoke WriteConsole, [hOut], addr cBuffer, <invoke lstrlen, addr cBuffer>, addr dwWritten, NULL  ; Выводим в консоль
    76.  
    77.     ret
    78.  
    79. endp
    [​IMG]
     
  14. _qwe8013

    _qwe8013 Member

    Публикаций:
    2
    Регистрация:
    30 ноя 2016
    Сообщения:
    112
    Посмотрел DirectSound, как я понял, для работы нужно вызывать метод SetCooperativeLevel, он принимает на вход хендл окна моей программы. Но проблема в том, что у моей программы нет окна (только консоль). Можно ли как-то обойтись без окна, или надо юзать WINMM?

    Хотя вроде-бы GetDesktopWindow принимает, так вообще можно делать?
     
  15. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    422
    _qwe8013, лучше создать окно или получить хендл консольного окна, т.к. в документации требуется окно верхнего уровня принадлежащее текущему процессу. Вообще использовать или не использовать DirectSound для проигрывания звука - зависит от задачи. Я скинул пример получения полных имен через DirectSound, а для проигрывания также можно использовать WINMM. Если ты не используешь возможности DirectSound то лучше наверное использовать WINMM.
     
  16. _qwe8013

    _qwe8013 Member

    Публикаций:
    2
    Регистрация:
    30 ноя 2016
    Сообщения:
    112
    Ещё такой вопрос: вызываю функцию waveOutGetDevCaps с заведомо невалидным индексом устройства:
    Код (ASM):
    1. lea rdx,[WaveCaps]
    2.     invoke waveOutGetDevCaps,10,rdx,sizeof.WAVEOUTCAPS2
    она возвращает ошибку. Но когда я передаю её в waveOutGetErrorText, в строке оказывается мусор:
    Код (ASM):
    1. ErrText du 512 dup (?)
    2. ...
    3. lea rdx,[ErrText]
    4.     invoke waveOutGetErrorText,rax,rdx,512
    Как получить строку ошибки?
     
  17. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    422
    Версия функции правильная? Что возвращает сама waveOutGetErrorText?
    Проверил у себя - все корректно.
    Безымянный.png
     
  18. _qwe8013

    _qwe8013 Member

    Публикаций:
    2
    Регистрация:
    30 ноя 2016
    Сообщения:
    112
    Да, у меня тоже всё верно, просто кодировку дампа не правильно настроил, а как это вывести на консоль?
    CharToOEM не помогает.
     
    Последнее редактирование: 14 июл 2017
  19. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    422
    WriteConsoleW
     
  20. _qwe8013

    _qwe8013 Member

    Публикаций:
    2
    Регистрация:
    30 ноя 2016
    Сообщения:
    112
    Я знаю какими функциями выводить текст в консоль, вопрос в том, как вывести русские буквы.