LOGO Lazarus
AIMP 3.6 Пример визуализации, Lazarus

Визуализация для AIMP 3.6 с использованием нового API

Описание базового класса визуализации

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
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);

procedure vis_Draw(
	DC_AIMP, DC_Buffer: HDC; 
	Data: PAIMPVisualData; 
	const Width,Height:integer
); virtual;
Главная функция отрисовки визуализации

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

DC_AIMP - контекст устройства непосредственно самого AIMP
DC_Buffer - Буфер-контекст рисования, вся отрисовка происходит на нем.
Data : PAIMPVisualData указатель на структуру данных визуализации
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 - текущая ширина и высота соотвественно.

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

Исходный код
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;
Задаем имя автора и название визуализации
function TSimpleWave.vis_GetAutor: string;
begin
  Result:='Lazarus Visual';
end;

function TSimpleWave.vis_GetName: string;
begin
  Result:='SimpleWave Lazarus';
  showTextTime:=0;
end;
Указываем какой массив данных будет использовать визуализация для отрисовки
function TSimpleWave.vis_GetType: TAIMP_VISUAL_TYPE;
begin
  Result:=AIMP_VISUAL_FLAGS_RQD_DATA_WAVE; // запрашиваем волновую
end;
Функция отрисовки
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;
Инициализация:
function TSimpleWave.vis_Init(Width, Height: Integer): HRESULT;
begin
  showTextTime:=0;
  Result:=inherited vis_Init(Width, Height);
end;
В случае получения сообщения AIMP_MSG_EVENT_STREAM_START обновляем таймер showTextTime для отображения текста на экране визуализации
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;
Пример обработки события нажания на визуализацию
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 ;
  // Lazarus использует UTF8 кодировку
  // MessageBoxW испольует Unicode
  // проводим преобразование кодировки через функцию UTF8Decode
  Windows.MessageBoxW(0, PWideChar(UTF8Decode(s)) , 'AIMP Click Event', 0);
end; ;

Общий вид:



Скачать AIMP SDK

 Скачать SimpleAIMPVisual.zip