Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 5 743

/ вопрос решён /

Здравствуйте, уважаемые эксперты!
Пытаюсь написать генератор звуковых волн, но в начале хотел бы вывести кое какую информацию о звуковых адапторах. Нашол функции в MSDN:
waveOutGetNumDevs и waveOutGetDevCaps.
Функция waveOutGetNumDevs работает как часы. Проверял отключая адапторы и службу Win. Audio, вставлял ещё один в PCI слот.
А вот функция waveOutGetDevCaps чудит, или чудит структура которую она заполняет. В частности, элемент структуры .szPname оказывается пустым, и прочие элементы структуры оказываются одинаковыми для двух адапторов, а вызываю я функцию столько раз сколько адапторов.
Так как же получить информацию об адапторах?

Приложение:
  1. procedure TForm1.FormShow(Sender: TObject);
  2. var
  3. Adapters: DWORD;
  4. DevInfo: PWaveOutCaps;
  5. Result, i: byte;
  6. begin
  7. Memo1.Clear;
  8. Label4.Caption:='';
  9. Adapters:= waveOutGetNumDevs;
  10. if Adapters = 0 then
  11. begin
  12.  
  13.  
  14. end;
  15. if Adapters > 0 then
  16. begin
  17. Label3.Caption:= IntToStr(Adapters);
  18. For i:= 1 to Adapters do
  19. begin
  20. waveOutGetDevCaps(i, DevInfo, 0);
  21.  
  22. Memo1.Lines.Add(DevInfo.szPname);
  23. Memo1.Lines.Add('');
  24.  
  25.  
  26. end;
  27. end;
  28.  
  29.  
  30. end;
  31.  


Примечание #1 (13 ноября 2011, 10:35):
Второй день ковыряюсь, сил уже нету.
Я в начале пробовал через DirectSoundEnumerate,
но там не смог справиться с ошибкой. Уже точно не помню текст ошибки, а смысл был в том что есть какая то проблема при подключении к DSound.dll

QWERYTY Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: QWERYTY (статус: Посетитель)
Вопрос отправлен: 13 ноября 2011, 10:21
Состояние вопроса: решён, ответов: 0.


Мини-форум вопроса

Всего сообщений: 19; последнее сообщение — 30 декабря 2011, 22:51; участников в обсуждении: 3.
min@y™

min@y™ (статус: Доктор наук), 13 ноября 2011, 10:46 [#1]:

А где ж выделение памяти под структуру DevInfo? Это ж указатель, ёмоё.
{ waveform output device capabilities structure }
type
  PWaveOutCapsA = ^TWaveOutCapsA;
  PWaveOutCapsW = ^TWaveOutCapsW;
  PWaveOutCaps = PWaveOutCapsA;
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
QWERYTY

QWERYTY (статус: Посетитель), 13 ноября 2011, 11:15 [#2]:

Спасибо вам, Минай.
Вот в функции waveOutGetDevCaps третьим параметром вроде как пишут указать размер структуры, а где его взять не пишут.
Или он стандартный для любого адаптора?
Я ещё не очень понимаю вот эту всю замуту с сылками, указателями, интерфейсами, и прочими сложностями.

Не охото тупить, но видимо придётся. То что вы написали я читал в статьях по созданию проигрывателей, но на С, со всякими звёздочками и скобочками, вобщем ничерта не понял.
Вот это надо добавить в первый же type в проекте?
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
min@y™

min@y™ (статус: Доктор наук), 13 ноября 2011, 11:34 [#3]:

Цитата (QWERYTY):

Вот это надо добавить в первый же type в проекте?

Нет, это я процитировал кусок модуля mmsystem.pas.

Цитата (QWERYTY):

третьим параметром вроде как пишут указать размер структуры, а где его взять не пишут.

Оператор SizeOf() ещё никто не отменял. Однако, нужно оперировать не с указателем (4 байта), а с самой структурой. Можно, конечно, поклянчить под неё память динамически, но проще пользоваться простой статической переменной, а в функцию передавать её адрес. Примерно как-то так:
var
...
  DevInfo: TWaveOutCapsA;
...
begin
...
  // waveOutGetDevCaps(i, &DevInfo, sizeof(DevInfo)); // <--- C++
  waveOutGetDevCaps(i, @DevInfo, SizeOf(DevInfo)); // delphi 
...
end;

Цитата (QWERYTY):

Я ещё не очень понимаю вот эту всю замуту с сылками, указателями, интерфейсами, и прочими сложностями.

Очень рекомендую подучить. В жизни пригодится.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
QWERYTY

QWERYTY (статус: Посетитель), 13 ноября 2011, 12:20 [#4]:

Спасибо вам, Минай. Заработало. Только адаптор находится один, и что меня поразило ещё больше, не тот который активный в данный момент. Но тут уж как нибудь разберусь.

Для тех кто будет читать, дочитает до предыдущего поста, пойдёт делать, а потом вернётся читать дальше:
&DevInfo - вот тут не енд, а собака.
Этот пароль я подобрал методом эвристического подбора ключей. :)
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 13 ноября 2011, 12:24 [#5]:

Плюс вам, Минай. Я думаю это справедливо, вы действительно помогли.
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.

13 ноября 2011, 12:27: Статус вопроса изменён на решённый (изменил автор вопроса — QWERYTY)

min@y™

min@y™ (статус: Доктор наук), 13 ноября 2011, 12:27 [#6]:

Цитата (QWERYTY):

Только адаптор находится один, и что меня поразило ещё больше, не тот который активный в данный момент.

А может они с нуля нумеруются, а не с 1?

Цитата (QWERYTY):

&DevInfo - вот тут не енд, а собака.

Бляхамуха, точно. Это у меня сишник с паскалем в башке перемешались.

Цитата (QWERYTY):

Плюс вам, Минай. Я думаю это справедливо, вы действительно помогли.

От плюса не откажусь. :)
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
QWERYTY

QWERYTY (статус: Посетитель), 13 ноября 2011, 12:44 [#7]:

Мля, как же теперь быть, придётся выкручиваться?
Чё за морока едрён батон. Функция которая возвращает количество передаёт 0 когда ошибка, а дальше по очереди от однёрки и дальше. А функция которая заполняет структуру счёт ведёт с нуля, как я понимаю. Придётся гневное письмо Биллу писать. :)

Видимо так:
.....
.....
For i:= 0 to Adapters-1 do
begin
waveOutGetDevCaps(i, @DevInfo, SizeOf(DevInfo));
Memo1.Lines.Add('Адаптор №'+IntToStr(i+1)+':');
.....
.....
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
min@y™

min@y™ (статус: Доктор наук), 13 ноября 2011, 12:51 [#8]:

Чо, я опять угадал? Было несложно, ибо в цифровой технике ВСЁ считается с нуля!
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
QWERYTY

QWERYTY (статус: Посетитель), 13 ноября 2011, 13:27 [#9]:

Ну всё, вторая функция заработала как часы.
Извлёк:

Адаптор №1:
C-Media Wave Device(Встроенная говняшка, это очень мешало в проверке промежуточных результатов)

Адаптор №2:
Aureal Audio(Цивильный в своё время, полноценный микшер, со всякими феньками и собственными ауреаловскими технологиями)
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 13 ноября 2011, 14:03 [#10]:

Кстати у ауреала подключение странное, слава богу функции на это не купились.

Там в общем получается что к PCI цепляется чип
Multifunction PCI Parent, а к нему звуковой Aureal чип и к нему же игровой порт.
А C-Media сразу цепляется к PCI и уже к нему подключен игровой порт.
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
bugmenot

bugmenot (статус: 3-ий класс), 13 ноября 2011, 18:33 [#11]:

ха, опять
виконання програми розпочинається з того самого мiсця, де призупинилося.

QWERYTY

QWERYTY (статус: Посетитель), 14 ноября 2011, 02:19 [#12]:

Здравствуйте Багменот!
Что значит ха? И что значит опять?

Багменот, не подскажите при помощи mmsystem можно раскачать аудиоадаптер на всю катушку(ну в смысле чтоб я мог закодить и 16гц. и 20000гц и в этом интервале чтоб плавно менять частоты без падения качества).
Скачивал проекты подобных вещей, но там одна прога не позволяет регулировать частоты(там пару положений выбираешь радиобатоном), а вторая даёт ужасные результаты. Там чистый выход не на всей шкале от 200 - 20000гц. И человеческое ухо на этом диапазоне не плохой инструмент. Например там отчётливо слышно что 16800гц грубже звучит чем 11600гц.
Усилитель специально использую 20 - 20000гц, отключил всякую лабуду от компа(типа активных 4-ёх ватных).
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 14 ноября 2011, 04:17 [#13]:

Ну мля, опять пошли траблы. Элемент структуры .wChannels почемуто указывает не 1 или 2 как везде пишут, а 65535 для обоих адаптеров. Теперь придётся покупать новую акустическую систему 65535.1 TwinBass XBass SuperBass.

И я вынужден задать вопрос:
Нормально ли это?
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 14 ноября 2011, 06:25 [#14]:

Ну ахренеть. Я думал функции извлекают данные о адапторах в последовательности как они их находят в шинах PCI. Начал было уже писать код для отображения номера активного адаптора.
Но тут начались чудеса. Активный адаптор всегда отображается первым в списке где я их перечисляю.

Я думал что функции из mmsystem которыми я пользуюсь вызывают(если нужно) другие функции, которые считывают инфу непосредственно из чипов адапторов(класс то известен). Но видимо они берут инфу где угодно, только не с чипов.
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 14 ноября 2011, 08:44 [#15]:

А ёще не получается получить hwo адапторов.
Делаю так:
....
....
var
HWO: DWORD;
Fmt: TWAVEFORMAT;
begin
waveOutOpen(@HWO, 0, @Fmt, 0, 0, CALLBACK_NULL);// для первого
end;

В итоге HWO оказывается 0.
И в MSDN я функций для извлечения HWO не нашол, хотя это странно, он там везде нужен.
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
bugmenot

bugmenot (статус: 3-ий класс), 14 ноября 2011, 11:45 [#16]:

Цитата (QWERYTY):

Что значит ха? И что значит опять?

Сколько раз нужно повторять про проверку результатов чтобы дошло?
виконання програми розпочинається з того самого мiсця, де призупинилося.

QWERYTY

QWERYTY (статус: Посетитель), 16 ноября 2011, 02:24 [#17]:

Вы про ласт еррор, где ошибка подключения длл?
Я посчитал что не буду с этим возиться, там сразу пошло по галимому. Пришлось качать библиотеку с заголовочным файлом DirectSound.pas, в других примерах писали подключаем DirectX, но у меня так вообще не компилировалось. Ну получил бы я информацию об ошибке, а дальше что. Если длл не было то я не собираюсь ради проги устанавливать длл-ки взятые хрен знает откуда. А если траблы в DirectSound.pas то исправлять их я тоже не собираюсь.
Должно быть как-то проще(ну например как с mmsystem, подключаем и пишем).

Вы бы лучше подсказали как добыть HWO. waveOutGetNumDevs и waveOutGetDevCaps его не извлекают, а в остальных он нужен.
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 16 ноября 2011, 04:55 [#18]:

Уродство какое-то, они не могли написать функцию по типу waveOutGetID(только waveOutGetHandle). И выглядело бы это примерно так:
MMRESULT waveOutGetHandle(LPUINT puDeviceID, HWAVEOUT hwo);

Функция waveOutOpen начала извлекать хендл, но он один на 2-а адаптора, и подозрительно короткий. Извлекаю так:
procedure TForm1.FormCreate(Sender: TObject);
var
HWO: HWAVEOUT;
Fmt: TWAVEFORMATEX;
begin
     Fmt.wFormatTag:= 1; // PCM
     Fmt.nChannels:= 2;
     Fmt.nBlockAlign:= 2* Fmt.nChannels;
     Fmt.wBitsPerSample:= 16;
     Fmt.nSamplesPerSec:= 10;
     Fmt.nAvgBytesPerSec:= Fmt.nSamplesPerSec * Fmt.nBlockAlign;
     Fmt.cbSize:= SizeOf(Fmt);
     waveOutOpen(@HWO, 0, @Fmt, 0, 0, WAVE_FORMAT_QUERY);
     Edit1.Text:= IntToStr(HWO);
end;
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.
QWERYTY

QWERYTY (статус: Посетитель), 30 декабря 2011, 22:51 [#19]:

А вот и извлекли HWO всех установленных адапторов.

procedure TForm1.FormCreate(Sender: TObject);
var
HWO: HWAVEOUT;
Fmt: TWAVEFORMATEX;
Adapters, i: Byte;
AdaptersHandle: Array[0..31] of HWAVEOUT;
 
begin
     Adapters:= waveOutGetNumDevs;
     with Fmt do
     begin
          wFormatTag:= WAVE_FORMAT_PCM;
          nChannels:= 1;
          nSamplesPerSec:= 44100;
          wBitsPerSample:= 16;
          nBlockAlign:= nChannels * (wBitsPerSample div 8);
          nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
          cbSize:= 0;
     end;
     For i:= 0 to Adapters-1 do
     begin
          waveOutOpen(addr(HWO), i, @Fmt, Handle, 0, CALLBACK_WINDOW);
          AdaptersHandle[i]:= HWO;
          waveOutClose(HWO);
          HWO:= 0;
     end;
end;
ВЕРИТЬ ВО ВНЕЗЕМНЫЕ ЦИВИЛИЗАЦИИ НЕ ОЗНАЧАЕТ ВЕРИТЬ В ИНОПЛАНЕТЯН.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:49
Выполнено за 0.04 сек.