summaryrefslogtreecommitdiff
path: root/plugins/Watrack/players/pl_aimp.pas
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Watrack/players/pl_aimp.pas')
-rw-r--r--plugins/Watrack/players/pl_aimp.pas376
1 files changed, 376 insertions, 0 deletions
diff --git a/plugins/Watrack/players/pl_aimp.pas b/plugins/Watrack/players/pl_aimp.pas
new file mode 100644
index 0000000000..17c52bc5b6
--- /dev/null
+++ b/plugins/Watrack/players/pl_aimp.pas
@@ -0,0 +1,376 @@
+{AIMP player}
+unit pl_AIMP;
+{$include compilers.inc}
+
+interface
+
+implementation
+uses windows,messages,common,srv_player,wat_api,winampapi;
+
+const
+ WM_AIMP_COMMAND = WM_USER + $75;
+ WM_AIMP_GET_VERSION = 4;
+ WM_AIMP_STATUS_GET = 1;
+ WM_AIMP_STATUS_SET = 2;
+ WM_AIMP_CALLFUNC = 3;
+const
+ AIMP_STS_Player = 4;
+ AIMP_STS_VOLUME = 1;
+ AIMP_STS_POS = 31;
+const
+ AIMP_PLAY = 15;
+ AIMP_PAUSE = 16;
+ AIMP_STOP = 17;
+ AIMP_NEXT = 18;
+ AIMP_PREV = 19;
+
+const
+ AIMP2_RemoteClass:PAnsiChar = 'AIMP2_RemoteInfo';
+const
+ AIMP2_RemoteFileSize = 2048;
+
+type
+ PAIMP2FileInfo = ^TAIMP2FileInfo;
+ TAIMP2FileInfo = packed record
+ cbSizeOF :dword;
+ //
+ nActive :LONGBOOL;
+ nBitRate :dword;
+ nChannels :dword;
+ nDuration :dword;
+ nFileSize :Int64;
+ nRating :dword;
+ nSampleRate :dword;
+ nTrackID :dword;
+ //
+ nAlbumLen :dword;
+ nArtistLen :dword;
+ nDateLen :dword;
+ nFileNameLen:dword;
+ nGenreLen :dword;
+ nTitleLen :dword;
+ //
+ sAlbum :dword; // size of pointer for 32 bit system
+ sArtist :dword;
+ sDate :dword;
+ sFileName :dword;
+ sGenre :dword;
+ sTitle :dword;
+ end;
+
+function Check(wnd:HWND;flags:integer):HWND;cdecl;
+begin
+ if wnd<>0 then
+ begin
+ result:=0;
+ exit;
+ end;
+ result:=FindWindowA(AIMP2_RemoteClass,AIMP2_RemoteClass);
+end;
+
+function GetVersionText(ver:integer):pWideChar;
+begin
+ if (ver and $F00)<>0 then
+ begin
+ mGetMem(result,8*SizeOf(WideChar));
+ result[0]:=WideChar((ver div 1000)+ORD('0'));
+ ver:=ver mod 1000;
+ result[1]:='.';
+ result[2]:=WideChar((ver div 100)+ORD('0'));
+ ver:=ver mod 100;
+ result[3]:='.';
+ result[4]:=WideChar((ver div 10)+ORD('0'));
+ result[5]:='.';
+ result[6]:=WideChar((ver mod 10)+ORD('0'));
+ result[7]:=#0;
+ end
+ else
+ result:=nil;
+end;
+
+function GetVersion(wnd:HWND):integer;
+begin
+ result:=SendMessage(wnd,WM_AIMP_COMMAND,WM_AIMP_GET_VERSION,0);
+end;
+
+function GetStatus(wnd:HWND):integer; cdecl;
+begin
+ result:=SendMessage(wnd,WM_AIMP_COMMAND,WM_AIMP_STATUS_GET,AIMP_STS_Player);
+end;
+
+function GetVolume(wnd:HWND):cardinal;
+begin
+ result:=SendMessage(wnd,WM_AIMP_COMMAND,WM_AIMP_STATUS_GET,AIMP_STS_VOLUME);
+ result:=(result shl 16)+round((result shl 4)/100);
+end;
+
+procedure SetVolume(wnd:HWND;value:cardinal);
+begin
+ SendMessage(wnd,WM_AIMP_COMMAND,WM_AIMP_STATUS_SET,
+ (AIMP_STS_VOLUME shl 16)+((value*100) shr 4));
+end;
+
+function VolDn(wnd:HWND):integer;
+var
+ val:dword;
+begin
+ result:=GetVolume(wnd);
+ val:=loword(result);
+ if val>0 then
+ SetVolume(wnd,val-1);
+end;
+
+function VolUp(wnd:HWND):integer;
+var
+ val:dword;
+begin
+ result:=GetVolume(wnd);
+ val:=loword(result);
+ if val<16 then
+ SetVolume(wnd,val+1);
+end;
+
+function GetFileName(wnd:HWND;flags:integer):pWideChar;cdecl;
+var
+ FFile:THANDLE;
+ pStr:pointer;
+ s:integer;
+ p:PAnsiChar;
+ pw,pw1:pWideChar;
+begin
+ result:=nil;
+ s:=AIMP2_RemoteFileSize;
+ p:=AIMP2_RemoteClass;
+ FFile:=OpenFileMappingA(FILE_MAP_READ,True,p);
+ pStr:=MapViewOfFile(FFile,FILE_MAP_READ,0,0,s);
+ try
+ if pStr<>nil then
+ begin
+ with PAIMP2FileInfo(pStr)^ do
+ begin
+ StrDupW(result,
+ pWideChar(PAnsiChar(pStr)+SizeOf(TAIMP2FileInfo)+
+ (nAlbumLen+nArtistLen+nDateLen)*SizeOf(WideChar)),
+ nFileNameLen);
+ // Delete rest index (like "filename.cue:3")
+ pw :=StrRScanW(result,':');
+ if pw<>nil then
+ begin
+ pw1:=StrScanW (result,':');
+ if pw<>pw1 then
+ pw^:=#0;
+ end;
+ end;
+ end;
+ finally
+ UnmapViewOfFile(pStr);
+ CloseHandle(FFile);
+ end;
+end;
+
+procedure TranslateRadio(var SongInfo:tSongInfo);
+var
+ pc,pc1:pWideChar;
+begin
+{
+ artist - album - title (radio)
+}
+ with SongInfo do
+ begin
+ if (artist=nil) and (title<>nil) then
+ begin
+ // Radio title
+ if (StrEndW(title)-1)^=')' then
+ begin
+ pc:=StrRScanW(title,'(');
+ if (pc<>nil) and (pc>title) and ((pc-1)^=' ') then
+ begin
+ if comment=nil then
+ begin
+ StrDupW(comment,pc+1);
+ (StrEndW(comment)-1)^:=#0;
+ end;
+ (pc-1)^:=#0;
+ end;
+ end;
+ // artist - title
+ pc:=StrPosW(title,' - ');
+ if pc<>nil then
+ begin
+ if artist=nil then
+ begin
+ pc^:=#0;
+ inc(pc,3);
+ StrDupW(artist,title);
+ end;
+ // artist - album - title
+ pc1:=StrPosW(pc,' - ');
+ if pc1<>nil then
+ begin
+ if album=nil then
+ begin
+ pc1^:=#0;
+ StrDupW(album,pc);
+ pc:=pc1+3;
+ end;
+ end;
+ pc1:=title;
+ StrDupW(title,pc);
+ mFreeMem(pc1);
+ end;
+ end;
+ end;
+end;
+
+function GetInfo(var SongInfo:tSongInfo;flags:integer):integer;cdecl;
+var
+ FFile:THANDLE;
+ s:integer;
+ p:PAnsiChar;
+ pStr:PAIMP2FileInfo;
+begin
+ result:=0;
+ if (flags and WAT_OPT_PLAYERDATA)<>0 then
+ begin
+ if SongInfo.plyver=0 then
+ begin
+ SongInfo.plyver:=GetVersion (SongInfo.plwnd);
+ SongInfo.txtver:=GetVersionText(SongInfo.plyver);
+ end;
+ if SongInfo.winampwnd=0 then
+ SongInfo.winampwnd:=WinampFindWindow(SongInfo.plwnd);
+ exit;
+ end;
+
+ if SongInfo.winampwnd<>0 then
+ WinampGetInfo(int_ptr(@SongInfo),flags);
+
+ if (flags and WAT_OPT_CHANGES)=0 then
+ begin
+ s:=AIMP2_RemoteFileSize;
+ p:=AIMP2_RemoteClass;
+ FFile:=OpenFileMappingA(FILE_MAP_READ,True,p);
+ pStr:=MapViewOfFile(FFile,FILE_MAP_READ,0,0,s);
+ try
+ if pStr<>nil then
+ begin
+ with SongInfo do
+ begin
+ with pStr^ do
+ begin
+ if channels=0 then channels:=nChannels;
+ if kbps =0 then kbps :=nBitRate div 1000;
+ if khz =0 then khz :=nSampleRate div 1000;
+ if total =0 then total :=nduration;
+ if fsize =0 then fsize :=nFileSize;
+ if track =0 then track :=nTrackID;
+
+ with PAIMP2FileInfo(pStr)^ do
+ begin
+ if (artist=nil) and (nArtistLen>0) then
+ begin
+ StrDupW(artist,
+ pWideChar(PAnsiChar(pStr)+SizeOf(TAIMP2FileInfo))+
+ nAlbumLen,nArtistLen);
+ end;
+ if (album=nil) and (nAlbumLen>0) then
+ begin
+ StrDupW(album,
+ pWideChar(PAnsiChar(pStr)+SizeOf(TAIMP2FileInfo)),
+ nAlbumLen);
+ end;
+ if (title=nil) and (nTitleLen>0) then
+ begin
+ StrDupW(title,
+ pWideChar(PAnsiChar(pStr)+SizeOf(TAIMP2FileInfo))+
+ nAlbumLen+nArtistLen+nDateLen+nFileNameLen+nGenreLen,
+ nTitleLen);
+ end;
+ if (year=nil) and (nDateLen>0) then
+ begin
+ StrDupW(year,
+ pWideChar(PAnsiChar(pStr)+SizeOf(TAIMP2FileInfo))+
+ nAlbumLen+nArtistLen,
+ nDateLen);
+ end;
+ if (genre=nil) and (nGenreLen>0) then
+ begin
+ StrDupW(genre,
+ pWideChar(PAnsiChar(pStr)+SizeOf(TAIMP2FileInfo))+
+ nAlbumLen+nArtistLen+nDateLen+nFileNameLen,
+ nGenreLen);
+ end;
+
+ if StrPosW(mfile,'://')<>nil then
+ TranslateRadio(SongInfo);
+ end;
+ end;
+ end;
+ end;
+ finally
+ UnmapViewOfFile(pStr);
+ CloseHandle(FFile);
+ end;
+ end
+ else // request AIMP changed data: volume
+ begin
+ SongInfo.time:=SendMessage(SongInfo.plwnd,WM_AIMP_COMMAND,WM_AIMP_STATUS_GET,AIMP_STS_POS);
+ SongInfo.volume:=GetVolume(SongInfo.plwnd);
+ end;
+end;
+
+function Command(wnd:HWND;cmd:integer;value:integer):integer;cdecl;
+var
+ WinampWindow:HWND;
+begin
+ WinampWindow:=WinampFindWindow(wnd);
+ if WinampWindow<>0 then
+ result:=WinampCommand(WinampWindow,cmd+(value shl 16))
+ else
+ begin
+ result:=0;
+ case cmd of
+ WAT_CTRL_PREV : SendMessage(wnd,WM_AIMP_COMMAND,WM_AIMP_CALLFUNC,AIMP_PREV);
+ WAT_CTRL_PLAY : SendMessage(wnd,WM_AIMP_COMMAND,WM_AIMP_CALLFUNC,AIMP_PLAY);
+ WAT_CTRL_PAUSE: SendMessage(wnd,WM_AIMP_COMMAND,WM_AIMP_CALLFUNC,AIMP_PAUSE);
+ WAT_CTRL_STOP : SendMessage(wnd,WM_AIMP_COMMAND,WM_AIMP_CALLFUNC,AIMP_STOP);
+ WAT_CTRL_NEXT : SendMessage(wnd,WM_AIMP_COMMAND,WM_AIMP_CALLFUNC,AIMP_NEXT);
+ WAT_CTRL_VOLDN: result:=VolDn(wnd);
+ WAT_CTRL_VOLUP: result:=VolUp(wnd);
+ WAT_CTRL_SEEK : begin
+ SendMessage(wnd,WM_AIMP_COMMAND,WM_AIMP_STATUS_SET,
+ (AIMP_STS_POS shl 16)+value);
+ end;
+ end;
+ end;
+end;
+
+const
+ plRec:tPlayerCell=(
+ Desc :'AIMP';
+ flags :WAT_OPT_APPCOMMAND or WAT_OPT_HASURL;
+ Icon :0;
+ Init :nil;
+ DeInit :nil;
+ Check :@Check;
+ GetStatus:@GetStatus;
+ GetName :@GetFileName;
+ GetInfo :@GetInfo;
+ Command :@Command;
+ URL :'http://www.aimp.ru/';
+ Notes :nil);
+
+var
+ LocalPlayerLink:twPlayer;
+
+procedure InitLink;
+begin
+ LocalPlayerLink.Next:=PlayerLink;
+ LocalPlayerLink.This:=@plRec;
+ PlayerLink :=@LocalPlayerLink;
+end;
+
+initialization
+// ServicePlayer(WAT_ACT_REGISTER,dword(@plRec));
+ InitLink;
+end.