AIMP Forum

AIMP for Windows => Дополнения / Addons => Разработка / Development => Topic started by: alexpac26 on December 11, 2014, 01:08:00

Title: Пример визуализации 3.6 (Класс TAIMP_SimpleVisual)
Post by: alexpac26 on December 11, 2014, 01:08:00
Представляю класс обертку  TAIMP_SimpleVisual которая позволяет легко от нее наследоваться и писать визуализации под AIMP

При этом не нужно проводить иницализацию промежуточных интерфейсов. Достаточно только унаследоваться от этого класса и отписать несколько методов

Code: [Select]
TAIMP_SimpleVisual = class (TAIMPCustomPlugin)
{ ... }
public
    // Методы для наследования
    // - Необязательные методы
    function vis_Init(Width, Height: Integer): HRESULT; virtual;
    procedure vis_Finalize; virtual;
    procedure vis_Click(X, Y: Integer; Button: Integer); virtual;
    procedure vis_Resize(NewWidth, NewHeight: Integer); virtual;
    procedure vis_AIMP_Message(Message: DWORD; Param1: Integer; Param2: Pointer; var Result: HRESULT); virtual;
    // - Обязательные методы, требуют реализации
    function vis_GetAutor: string; virtual;
    function vis_GetName: string; virtual;
    function vis_GetType: TAIMP_VISUAL_TYPE; virtual; // AIMP_VISUAL_FLAGS_RQD_DATA_SPECTRUM
    // Отрисовка
    procedure vis_Draw(DC_AIMP, DC_Buffer: HDC;
        Data: PAIMPVisualData; const Width,Height:integer); virtual;
end;

TAIMP_SimpleVisual берет на себя большинство операций связанных с инициализацией визуализации, таким образом, не нужно больше дублировать код при написании визуализаций под AIMP.

Описание наследуемых методов из базового объекта TAIMP_SimpleVisual:

.vis_Init(Width, Height: Integer): HRESULT;

Вызывается когда визуализация инициализируется.
В случае успеха нужно вернуть S_OK;

.vis_Finalize;

Вызывается когда работа визуализации завершена.

.vis_Click(X, Y: Integer; Button: Integer);

Вызывается когда произошло нажатие на визуализацию.

.vis_Resize(NewWidth, NewHeight: Integer)

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

.vis_AIMP_Message(Message: DWORD; ... );

Вызывается всякий раз когда AIMP посылает сообщение.
Смотрите документацию на AIMP 3.6 API для подробностей какие типы сообщений могут быть.

.vis_GetAutor: string; .vis_GetName: string;

Имя Автора и Название визуализации соотвественно

.vis_GetType: TAIMP_VISUAL_TYPE;

Тип данных которые будет использовать визуализация.
Принимает один или комбинацию флагов из apiVisuals.pas

Code: [Select]
AIMP_VISUAL_FLAGS_RQD_DATA_WAVE       = 1;
AIMP_VISUAL_FLAGS_RQD_DATA_SPECTRUM   = 2;
AIMP_VISUAL_FLAGS_NOT_SUSPEND         = 4;

.vis_Draw(DC_AIMP, DC_Buffer, Data, Width, Height);

Code: [Select]
procedure vis_Draw(
DC_AIMP, DC_Buffer: HDC;
Data: PAIMPVisualData;
const Width,Height:integer
); virtual;

Главная функция отрисовки визуализации

Описание параметров:

DC_AIMP - контекст устройства непосредственно самого AIMP
DC_Buffer - Буфер-контекст рисования, вся отрисовка происходит на нем.
Data : PAIMPVisualData указатель на структуру данных визуализации

Code: [Select]
type
  TAIMPVisualDataSpectrum = array[0..AIMP_VISUAL_SPECTRUM_MAX - 1] of Single;
  TAIMPVisualDataWaveform = array[0..AIMP_VISUAL_WAVEFORM_MAX - 1] of Single;

  PAIMPVisualData = ^TAIMPVisualData;
  TAIMPVisualData = packed record
    Peaks: array[0..1] of Single;
    Spectrum: array[0..2] of TAIMPVisualDataSpectrum;
    Waveform: array[0..1] of TAIMPVisualDataWaveform;
  end;

Width,Height - текущая ширина и высота соотвественно.

Пример визуализации:

Визуализация осциллограф двухканальный

(http://jqbook.net.ru/up_images/5488afbc0af67.png)

Исходный код

Code: [Select]
TSimpleWave = class (TAIMP_SimpleVisual)
public
  function vis_GetAutor: string; override;
  function vis_GetName: string; override;
  function vis_GetType: TAIMP_VISUAL_TYPE; override;
  // Отрисовка
  procedure vis_Draw(DC_AIMP, DC_Buffer: HDC; Data: PAIMPVisualData; const Width,Height:integer); override;
  // Init
  function vis_Init(Width, Height: Integer): HRESULT; override;
  // Обработка сообщений
  procedure vis_AIMP_Message(Message: DWORD; Param1: Integer; Param2: Pointer; var Result: HRESULT); override;
  // Клик по визуализации
  procedure vis_Click(X, Y: Integer; Button: Integer); override;
public
  showTextTime: Integer;
end;

Задаем имя автора и название визуализации

Code: [Select]
function TSimpleWave.vis_GetAutor: string;
begin
  Result:='SimpleWave Autor';
end;

function TSimpleWave.vis_GetName: string;
begin
  Result:='SimpleWave Visual';
  showTextTime:=0;
end;

Указываем какой массив данных будет использовать визуализация для отрисовки
Code: [Select]
function TSimpleWave.vis_GetType: TAIMP_VISUAL_TYPE;
begin
  Result:=AIMP_VISUAL_FLAGS_RQD_DATA_WAVE; // запрашиваем волновую
end;

Функция отрисовки

Code: [Select]
procedure TSimpleWave.vis_Draw(DC_AIMP, DC_Buffer: HDC; Data: PAIMPVisualData; const Width, Height: integer);
var ci,x,z,y, offset: integer;
  br: HBRUSH; s: AnsiString;
begin
   // отрисовка
   // Все рисование идет на DC_Buffer, и в самом конце переносится на DC_AIMP через функцию BitBlt

  // Очистка экрана
  br:=windows.CreateSolidBrush($3C3C3C);
  windows.FillRect(DC_Buffer, Bounds(0,0, Width, Height), br);
  windows.DeleteObject(br);

  offset:=trunc( Height / 2 );

  // << CSS совместимый цвет
  y:=0;
  for ci:=0 to High(Data^.Waveform) do begin
     for x:=0 to Width-1 do begin
        z:= Trunc((1 - Data^.Waveform[ci][x]) * offset / 2);
        if z < 0 then z := 0;
        if z > Height then z:= Height -1;
        if x = 0 then y := z;
        repeat  // draw line from previous sample...
          if y < z then begin
             inc(y);
          end else if y > z then begin
             dec(y);
          end;
          if (ci = 0) then begin
             windows.SetPixel(DC_Buffer, x, y + round(offset / 2), $FFFAFA);
          end;
          if (ci = 1) then begin
             windows.SetPixel(DC_Buffer, x, y + round(offset / 2), $00FA9A);
          end;
        until y = z;
     end; // end for
  end; // end for

  if (showTextTime>0) then begin
// показываем текст в случае если таймер showTextTime не истек
     dec(showTextTime);
     s:= 'AIMP new track';
     Windows.SetBkColor(DC_Buffer, $3C3C3C); // фон
     Windows.SetTextColor(DC_Buffer, $00FA9A); // текст

     Windows.TextOutA(DC_Buffer, 2, Height-15, PAnsiChar(s), Length(s));
  end;

  // Копируем буфер на DC_AIMP
  BitBlt(
    DC_AIMP,
    0, 0,
    Width, Height,
    DC_Buffer,
    0, 0,
    SRCCOPY
  );
end;

Инициализация:

Code: [Select]
function TSimpleWave.vis_Init(Width, Height: Integer): HRESULT;
begin
  showTextTime:=0;
  Result:=inherited vis_Init(Width, Height);
end;

В случае получения сообщения AIMP_MSG_EVENT_STREAM_START обновляем таймер showTextTime для отображения текста на экране визуализации

Code: [Select]
procedure TSimpleWave.vis_AIMP_Message(Message: DWORD; Param1: Integer;
  Param2: Pointer; var Result: HRESULT);
begin
  if Message = AIMP_MSG_EVENT_STREAM_START then begin
     showTextTime:=60;
  end;
end;

Пример обработки события нажания на визуализацию

Code: [Select]
procedure TSimpleWave.vis_Click(X, Y: Integer; Button: Integer);
var s: string;
begin
  s:= 'WIN_DLL_Path: ' + AIMP_SimpleVisual.GET_WIN_DLL_Path + #13#10 +
  'APPDATA PATH: ' + self.visAPPDataPath ;
  Windows.MessageBoxW(0, PWideChar(s) , 'AIMP Click Event', 0);
end; ;

http://jqbook.net.ru/up_files/simpleaimpvisual.zip << исходники с проектом Delphi + Lazarus

документация (http://jqbook.net.ru/lazarus/vis_example) на класс TAIMP_SimpleVisual
Title: Re: Пример визуализации 3.6 (Класс TAIMP_SimpleVisual)
Post by: Artem on December 26, 2014, 09:22:14
https://www.aimp.ru/forum/index.php?topic=46745.msg287212#msg287212