Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Создание плагинов к Winamp


Автор: Иван Ширко
Источник: docs.com.ru
Оформил: @lex



Windows все свое рабочее время (в промежутках между зависаниями) занимается тем, что рассылает и принимает сообщения. Например, изменил пользователь разрешение экрана, Windows тут же сообщает эту новость всем окнам (извините за тавтологию), мол, пора бы и перерисоваться. Разумеется, каждая программа может реагировать на любое сообщение по-своему. Многие приложения определяют для себя некоторые специфичные команды, которые зачастую бывают просто необходимы.

Возьмем, к примеру, Microsoft Word. У него есть главное внешнее окно, внутри которого располагаются дочерние окна, в которых открываются документы. Предположим, пользователь запустил Word и редактирует какой-нибудь документ. И вдруг он где-то в "Проводнике" увидел еще один файл, который ему срочно нужно редактировать в том же Word. Юзер два раза кликает по файлу, и опять запускается Word. Word-копия проверяет, единственный ли он и неповторимый, или уже есть его запущенный собрат. Если есть, то он посылает некое сообщение оригиналу и благополучно закрывается. Word-оригинал ловит это сообщение и из него узнает, что нужно открыть такой-то файл, и открывает его, а пользователь даже и не заметил, что Word запускался второй раз. Winamp поддерживает ряд нестандартных сообщений. Благодаря этим сообщениям существует огромное количество плагинов к нему и программ, которые умеют управлять Winamp'ом.

Чтобы послать Winamp'у какое-либо сообщение, нужно прежде всего определить идентификатор его окна. Делается это при помощи WinApi-функции:

    FindWindow(lpClassName, lpWindowName: PChar): HWND;

(здесь и далее используется синтаксис Object Pascal);

  • lpClassName - название класса искомого окна;
  • lpWindowName - заголовок искомого окна.

Для посылки сообщения используется еще одна WinApi-функция:

    SendMessage(hWnd:HWND;Msg:UINT;wParam:WPARAM;lParam:LPARAM):LRESULT;
  • hWnd - идентификатор окна, которому посылается сообщение;
  • Msg - посылаемое сообщение;
  • wParam - первый параметр сообщения;
  • lParam - второй параметр сообщения.

Winamp поддерживает два основных типа сообщения (параметр Msg):

  • WM_COMMAND: служит только для подачи определенных команд Winamp'у (Play, Stop, Next, Close и т.д.);
  • WM_USER: используется не только для выполнения действий, но и для определения различной информации (версия, текущая композиция, количество композиций и т.д.).

В таблице 1 приведены основные константы для первого параметра сообщения WM_COMMAND.

Команда Описание команды
40044 Кнопка «Prev»
40048 Кнопка «Next»
40045 Кнопка «Play»
40046 Кнопка «Pause»
40047 Кнопка «Stop»
40157 Остановиться после текущей композиции
40148 На 5 секунд вперед
40144 На 5 секунд назад
40154 Перейти на первую песню Playlist’а (режим «Suffle» — случайное проигрывание - должен быть отключен)
40158 Перейти на последнюю песню Playlist’а (режим «Suffle» должен быть отключен)
40192 Запустить плагин визуализации
40036 Показать/Спрятать эквалайзер
40040 Показать/Спрятать редактор Playlist’ов
40258 Показать/Спрятать главное окно
40298 Показать/Спрятать мини-браузер
40022 Кнопка «Repeat»
40023 Кнопка «Suffle»
40188 Показать информацию о файле
40058 Увеличить громкость на один процент
40059 Уменьшить громкость на один процент
40001 Закрыть Winamp

Для их использования можно применять процедуру:

    Procedure WinampCommand(Command:Integer);
     var
      WinampHWND:HWND;
    begin
     //поиск окна Winamp'a
     WinampHWND:=findwindow('Winamp v1.x',nil);
     //если поиск успешен, то посылаем сообщение
     if WinampHWND<>0 then
      SendMessage(WinampHWND, WM_Сommand, Command, 0);
    end;

Теперь для подачи сообщения типа WM_COMMAND нужно выбрать из таблицы понравившуюся константу и передать ее в качестве параметра процедуре WinampCommand. Пример:

    WinampCommand(40044); - переход к предыдущей композиции.

В таблице 2 перечислены основные константы для сообщений WM_USER.

Id Data Пояснения
0 0 Возвращает версию Winamp’а
102 0 Начать проигрывать выбранную в playlist’е композицию
104 0 Возвращает статус проигрывания: 1 — играет, 3 — пауза, иначе остановлен
105 0 Возвращает в миллисекундах позицию проигрывания
105 1 Возвращает в секундах длину композиции
121 n Выбирает в playlist’e композицию под номером n
122 n Устанавливает громкость в значение n (от 0 до 255)
123 n Устанавливает баланс в значение n (от 0 до 255)
125 0 Возвращает позицию текущей песни в playlist’е
126 0 Возвращает samplerate (частоту дискретизации)
126 1 Возвращает bitrate (скорость передачи информации)
126 2 Возвращает количество каналов (1 — моно, 2 — стерео)
135 0 Перезагружает Winamp (например, для подключения нового плагина)

Для их использования запишите следующую функцию:

    Function WinampUser(data:Integer, id:Integer):integer;
     var
      WinampHWND:HWND;
    begin
     WinampHWND:=findwindow ('Winamp v1.x', nil);
     if WinampHWND<>0 then
      result:=SendMessage (WinampHWND,WM_USER,data, id)
     else result:=-1;
    end;

Пример:

    WinampUser(1, 105); - возвращает длину текущей композиции в секундах.

Управлять Winamp'ом мы уже научились, это умение пригодится для написания плагинов к нему.

Плагины к Winamp'у бывают пяти видов:

  1. Input - плагины для проигрывания различных форматов;
  2. Output - для записи музыки в различных форматах;
  3. General Purpose - плагины общего назначения, в них наиболее часто используются сообщения, которые мы рассмотрели выше;
  4. DSP/Effect - для обработки звука;
  5. Visualization - плагины, которые делают что-нибудь в такт музыке.

На сайте http://www.winamp.com/ можно скачать шаблоны всех типов плагинов. Для примера рассмотрим маленький визуализационный плагин, который заставит мигать лампочки Num Lock, Caps Lock и Scroll Lock в такт музыке. Для этого воспользуемся соответствующим шаблоном (vis_minisdk). В нем присутствует функция Render, которая через заданный промежуток времени получает от Winamp'a информацию о текущих уровнях частот проигрываемой музыки. Остается только написать обработчик этих данных:

{Если плагин пишется не на C, то не следует забывать, что параметры процедур должны передаваться так же, как в этом языке. Поэтому в данном случае нужно использовать служебное слово cdecl (c-declaration)}

    function Render(this_mod: PwinampVisModule): integer;cdecl;

    //внутренняя процедура, которая будет гаситьзажигать нужные лампочки
     Procedure SetLock(n, state:byte);
      var
       KS: TKeyboardState;
       c: byte;
     begin
      //смотрим, с какой лампочкой будем работать
      case n of
       0: c:=VK_NUMLOCK;
       1: c:=VK_CAPITAL;
       2: c:=VK_SCROLL;
      end;
      //в зависимости от параметра state, зажигаем либо гасим лампочку
      GetKeyboardState(KS);
      KS[c]:=state;
      SetKeyboardstate(KS);
     end;

     var
      i:byte;
    begin
     //в зависимости от уровня звука, гасимзажигаем
     //соответствующие лампочки
     for i:=0 to 2 do
     if this_mod.spectrumData [0,i]>40 then SetLock(i, 1)
      else SetLock(i, 0);
     result:=0;
    end;

Весь исходный код и готовый плагин можно найти на странице www.IvanFDC.narod.ru/download.html. Хочу отметить, что данный плагин управляет только состоянием лампочек, а сами клавиши не трогает. Поэтому при использовании плагина можно набирать текст безо всяких проблем.

Как видим, всю работу по обработке звука Winamp берет на себя, поэтому создавать плагины к этому популярнейшему плееру может даже человек, весьма далекий от музыки.


P.S. (from @lex): Если надо заюзать готовый плагин у себя в программе, то скачайте TBASSPlayer - !!! :))) !!!

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay