Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;************************************************************************************************
- ;* AmpMasterLibrary DLL (x86) v1.18.8 - 19.08.2018 10:58 - PB 5.44 LTS - Peace^TST
- ;* ----------------------------------------------------------------------------------------------
- ;* Unit for WinAmp In/Out Dlls x86 - no unicode!
- ;* ----------------------------------------------------------------------------------------------
- ;* https://testaware.wordpress.com
- ;************************************************************************************************
- EnableExplicit
- #AMP_VER = #PB_Compiler_Date
- #IsAPI = 0 ;* Windows API -> 1 = on / 0 = off (always off -> coz buggy API)
- XIncludeFile "Includes\i_amp_enumeration.pbi"
- XIncludeFile "Includes\i_amp_structures.pbi"
- XIncludeFile "Includes\i_amp_macros.pbi"
- XIncludeFile "Includes\i_amp_player.pbi"
- XIncludeFile "Includes\i_amp_table.pbi"
- ; *** IDs for Subsongs: *.sid;*.mdat;*.tfm;*.tfx;*.nsf;*.gbs;*.fred
- #ID_FR10 = ID_MAGIC($4E,$FA,$00,$10) ; FRED10
- #ID_FR12 = ID_MAGIC($4E,$FA,$00,$12) ; FRED12
- #ID_FR4E = ID_MAGIC($4E,$FA,$00,$4E) ; FRED4E
- #ID_FR78 = ID_MAGIC($4E,$FA,$00,$78) ; FRED78
- #ID_FRSS = $F1D4 ; FRED SubSong (*.fred Word $6000 = 6 Songs $SN = always 0..6=7)
- #MAX_FRED= %1111 ; Max. Subsongs ($F/15) (random-crap)
- #ID_GBS1 = ID_MAGIC('G','B','S', 1 ) ; GBS1 = *.gbs
- #ID_NESM = ID_MAGIC('N','E','S','M') ; NESM = *.nsf
- #ID_PSID = ID_MAGIC('P','S','I','D') ; PSID = *.sid
- #ID_TFMX = ID_MAGIC('T','F','M','X') ; TFMX = mdat.*, *.tfm
- #ID_SONG = ID_MAGIC('-','S','O','N') ; TFMX-SON(G)
- #ID_TMOD = ID_MAGIC('-','M','O','D') ; TFMX-MERGED *.tfm
- #ID_2001 = ID_MAGIC(' ', 0, 0, 1 ) ; TFMX-CUSTOM
- #ID_AMP0 = ID_MAGIC('A','M','P', 0 ) ; TFMX-AMP0 = Private Tag (ReSet-SubSong) V1
- DeclareCDLL Amp_Free()
- ProcedureDLL AttachProcess(Instance)
- Global RS_WINAMP.RS_WINAMP ; Winamp structure
- Global RS_AMPMASTER.RS_AMPMASTER ; AmpMaster structure
- Global RS_AMPTIME.RS_AMPTIME ; Intern timehandling structure
- Global *i_n = ?i_n ; s. include i_amp_table.pbi
- RS_AMPMASTER\ProgramName$ = ProgramFilename()
- EndProcedure
- ProcedureDLL DetachProcess(Instance)
- Amp_Free()
- EndProcedure
- ProcedureC Amp_Dummy(*pointer=#Null, numsamples=#Null, bps=#Null, nch=#Null);, srate=#Null, temp=#Null)
- ProcedureReturn numsamples
- EndProcedure
- ProcedureC Amp_IsFile(*File)
- ;*************************************************************
- ; Let's check for avail file to avoid loosy request by plugins
- ; ------------------------------------------------------------
- ; Return: 1 = file exist / 0 = file not found
- ;*************************************************************
- If *File = #Null : ProcedureReturn #False : EndIf
- Protected iStatus
- iStatus = FileSize(PeekS(*File))
- ProcedureReturn Bool(iStatus > #Null)
- EndProcedure
- ProcedureCDLL Amp_VersionStr(Flags.i)
- With RS_AMPMASTER
- Protected t$
- t$ = StrU(Year(#AMP_VER)%1000) + "." +
- StrU(Month(#AMP_VER)) + "." +
- StrU(Day(#AMP_VER))
- If Flags
- t$ + RSet(StrU(Hour(#AMP_VER)), 3) + ":" +
- RSet(StrU(Minute(#AMP_VER)), 2, "0") + ":" +
- RSet(StrU(Second(#AMP_VER)), 2, "0")
- EndIf
- \Version$ = #AMP_NAME$ + " v1." + t$ + " (x86)"
- ProcedureReturn @\Version$
- EndWith
- EndProcedure
- ProcedureCDLL Amp_Close()
- With RS_WINAMP
- If \In2_DLL
- If RS_AMPMASTER\IsPause
- If \In2_Head\UnPause : CallCFunctionFast(\In2_Head\UnPause) : EndIf
- EndIf
- If RS_AMPMASTER\IsPlay
- If \In2_Head\Stop : CallCFunctionFast(\In2_Head\Stop) : EndIf
- EndIf
- If \In2_Head\Quit : CallCFunctionFast(\In2_Head\Quit) : EndIf
- EndIf
- If \Out_DLL
- If \Out_Head\Quit : CallCFunctionFast(\Out_Head\Quit) : EndIf
- EndIf
- If \In2_DLL : MA_LibClose(\In2_DLL) : EndIf
- If \Out_DLL : MA_LibClose(\Out_DLL) : EndIf
- EndWith
- With RS_AMPMASTER
- \IsOpen = #False
- \IsPause = #False
- \IsPlay = #False
- EndWith
- ClearStructure(@RS_WINAMP, RS_WINAMP)
- ClearStructure(@RS_AMPTIME,RS_AMPTIME)
- EndProcedure
- ProcedureCDLL Amp_Free()
- Amp_Close()
- ClearStructure(@RS_AMPMASTER, RS_AMPMASTER)
- EndProcedure
- ProcedureCDLL Amp_Init()
- Amp_Free()
- With RS_AMPMASTER
- \ProgramName$ = ProgramFilename()
- \Path$ = GetPathPart(\ProgramName$) + #DAMP_PATH$
- \OutPath$ = #DAMP_PATH$
- \InPath$ = #DAMP_PATH$
- \InDll$ = #DAMP_InDll$
- \OutDll$ = #DAMP_OUTDLL$
- \Volume = #DAMP_VOLUME
- \DefaultLength = #DAMP_LENGTH
- EndWith
- EndProcedure
- ProcedureCDLL Amp_Open()
- Protected In_Ptr
- Amp_Close() ; Already open -> close all and clear RS_WINAMP structure
- With RS_AMPMASTER
- ; Is path of AmpLibs -> or default -> "AmpLibs\"
- If Len(\Path$) = #Null : \Path$ = GetPathPart(\ProgramName$) + #DAMP_PATH$ : EndIf
- If Right(\Path$, 1) <> "\": \Path$ + "\" : EndIf
- ; Set in_dll -> or use default one one -> "in_xmp.dll"
- If Len(\InDll$) = #Null : \InDll$ = #DAMP_INDLL$ : EndIf
- If Len(\InPath$) < 2 : \InPath$ = \Path$ : EndIf
- ; Set out_dll -> or use default one -> "out_wave.dll"
- If Len(\OutDll$) = #Null : \OutDll$ = #DAMP_OUTDLL$ : EndIf
- If Len(\OutPath$) < 2 : \OutPath$= \Path$ : EndIf
- \InDll$ = \InPath$ + GetFilePart(\InDll$)
- \OutDll$ = \OutPath$ + GetFilePart(\OutDll$)
- ; Check if in/out avail
- If Amp_IsFile(@\InDll$) = #False : RETURN_ERR(#EAMP_OPEN_INDLL) : EndIf
- ;If Amp_IsFile(@\OutDll$)= #False : RETURN_ERR(#EAMP_OPEN_OUTDLL) : EndIf
- If \WindowID = #Null : \WindowID = GetForegroundWindow_() : EndIf
- EndWith
- ;************************************************
- ; Initialize WinAmp In/Out - Libraries
- ;************************************************
- With RS_WINAMP
- ; Set windowhandle -> or use foreground
- \WindowID = RS_AMPMASTER\WindowID
- SetCurrentDirectory(RS_AMPMASTER\InPath$) ; Must set for sublibs & ini
- ; IN_DLL
- ; -------------------------------------------------
- MA_LibOpen(\In2_DLL, RS_AMPMASTER\InDll$)
- If \In2_DLL > #Null
- MA_LibPtr(\In2_DLL, \In2_GeInModule2, "winampGetInModule2")
- If \In2_GeInModule2
- \In2_Head = CallCFunctionFast(\In2_GeInModule2)
- If \In2_Head > #Null
- \In2_Head\Version = #IN_VER
- \In2_Head\hMainWindow = \WindowID
- \In2_Head\hDllInstance = \In2_DLL
- CallCFunctionFast(\In2_Head\Init)
- ;dummy-routines (not used but needed)
- \In2_Head\SAVSAInit = @Amp_Dummy()
- \In2_Head\SAVSADeInit = @Amp_Dummy()
- \In2_Head\SAAddPCMData = @Amp_Dummy()
- \In2_Head\SAGetMode = @Amp_Dummy()
- \In2_Head\SAAdd = @Amp_Dummy()
- \In2_Head\VSAAddPCMData = @Amp_Dummy()
- \In2_Head\VSAGetMode = @Amp_Dummy()
- \In2_Head\VSAAdd = @Amp_Dummy()
- \In2_Head\VSASetInfo = @Amp_Dummy()
- \In2_Head\dsp_isactive = @Amp_Dummy()
- \In2_Head\dsp_dosamples = @Amp_Dummy()
- \In2_Head\EQSet = @Amp_Dummy()
- \In2_Head\SetInfo = @Amp_Dummy()
- RS_AMPMASTER\InInfo$ = PeekS(\In2_Head\description)
- EndIf
- EndIf
- EndIf
- If \In2_DLL <= #Null Or \In2_Head <= #Null ; In-Error?
- Amp_Close() : RETURN_ERR(#EAMP_OPEN_INDLL)
- EndIf
- ; OUT_DLL
- ; -------------------------------------------------
- If \In2_Head\UsesOutputPlug ; does this plug-in use the output plug-ins?
- If Amp_IsFile(@RS_AMPMASTER\OutDll$)= #False : RETURN_ERR(#EAMP_OPEN_OUTDLL) : EndIf
- MA_LibOpen(\Out_DLL, RS_AMPMASTER\OutDll$)
- If \Out_DLL > #Null
- MA_LibPtr(\Out_DLL, \Out_GetOutModule, "winampGetOutModule")
- \Out_Head = CallCFunctionFast(\Out_GetOutModule)
- If \Out_Head > #Null
- \Out_Head\Version = #OUT_VER
- \Out_Head\hMainWindow = \WindowID
- \Out_Head\hDllInstance = \Out_DLL
- CallCFunctionFast(\Out_Head\Init)
- EndIf
- EndIf
- If \Out_DLL <= #Null Or \Out_Head <= #Null ; Out-Error?
- Amp_Close() : RETURN_ERR(#EAMP_OPEN_OUTDLL)
- EndIf
- \In2_Head\outMod = \Out_Head
- RS_AMPMASTER\OutInfo$ = PeekS(\Out_Head\description)
- Else
- RS_AMPMASTER\OutInfo$ = "No use of output plug-ins"
- EndIf
- EndWith
- RS_AMPMASTER\IsOpen = #True
- RETURN_ERR(#EAMP_OK)
- EndProcedure
- ProcedureCDLL Amp_GetInFlags(*InLib)
- With RS_AMPMASTER
- \InFlags = #FAMP_DEFAULT
- If *InLib
- Protected File$ = GetFilePart(PeekS(*InLib))
- Protected *i_x.RS_INTABLE = *i_n
- While *i_x\iFLG
- If StrCmpNI_(@*i_x\iLIB\s, @File$, Len(File$)) = #Null
- \InFlags = PeekI(*i_x\iFLG)
- Break
- EndIf
- *i_x + SizeOf(RS_INTABLE)
- Wend
- If \IsPlay
- If RS_WINAMP\In2_Head\is_seekable = #Null ; is this stream not seekable?
- \InFlags|#FAMP_NO_SEEK
- EndIf
- If RS_WINAMP\In2_Head\UsesOutputPlug= #Null ; doesn't this plug-in use output plug-ins?
- \InFlags|#FAMP_NO_OUTPUT|#FAMP_NO_RECORD
- EndIf
- EndIf
- EndIf
- ProcedureReturn \InFlags
- EndWith
- EndProcedure
- ProcedureCDLL Amp_GetAmpInFormatStr(*InLib)
- ; Returns all supported formats by given *InLib only as string
- With RS_AMPMASTER
- Protected File$ = GetFilePart(PeekS(*InLib))
- Protected *i_x.RS_INTABLE = *i_n
- \InFormats$ = #Empty$
- While *i_x\iFLG
- If StrCmpNI_(@*i_x\iLIB\s, @File$, Len(File$)) = #Null
- \InFormats$ = *i_x\iEXT\s
- Break
- EndIf
- *i_x + SizeOf(RS_INTABLE) ; Next in Table-Ptr
- Wend
- CharLower_(@\InFormats$)
- ProcedureReturn @\InFormats$
- EndWith
- EndProcedure
- ;-
- ;- *** Play-Stuff ***
- ProcedureCDLL Amp_MusicPlay(*File)
- ; Play musicfile, returns 0 if all ok
- With RS_AMPMASTER
- If \IsOpen = #False : RETURN_ERR(#EAMP_INITIALIZE) : EndIf
- If Amp_IsFile(*File) = #False : RETURN_ERR(#EAMP_OPEN_FILE) : EndIf
- \MusicFile$ = PeekS(*File)
- Amp_GetInFlags(@\InDll$) ; get flags of in_dll
- If \InFlags&#FAMP_EX_SFX
- If GetPathPart(\MusicFile$)
- SetCurrentDirectory(GetPathPart(\MusicFile$)) ; Must set for miniusf, minipsf...
- EndIf
- Else
- If GetCurrentDirectory() <> \InPath$
- SetCurrentDirectory(\InPath$) ; Must set for sublibs & ini
- EndIf
- EndIf
- ; Try to get Tag-Title and real length in ms by played file (*File=0 doesn't work for wma)
- CallCFunctionFast(RS_WINAMP\In2_Head\GetFileInfo, *File, @\Buffer, @\MusicTime)
- ; Title of musicfile (eg. *.Mod)
- If \Buffer
- \MusicTitle$ = \Buffer ; get title
- Else
- \MusicTitle$ = GetFilePart(\MusicFile$) ; use filename
- EndIf
- \MusicLength = \MusicTime ; length in ms
- If CallCFunctionFast(RS_WINAMP\In2_Head\Play, *File) <> #EAMP_OK ; Error?
- RETURN_ERR(#EAMP_UNKOWN_FORMAT)
- EndIf
- CallCFunctionFast(RS_WINAMP\In2_Head\SetVolume, \Volume) ; s. Amp_Init()
- CallCFunctionFast(RS_WINAMP\In2_Head\SetPan, \Pan) ; s. Amp_Init()
- If RS_WINAMP\In2_Head\is_seekable = #Null
- \InFlags|#FAMP_NO_SEEK
- EndIf
- If RS_WINAMP\In2_Head\UsesOutputPlug= #Null
- \InFlags|#FAMP_NO_OUTPUT|#FAMP_NO_RECORD
- EndIf
- \IsPlay = #True
- ; No real playlength -> use getlength or length as default in ms (#DAMP_LENGTH)
- If \MusicLength <= 1000 ; length must > 1000ms
- \MusicLength = CallCFunctionFast(RS_WINAMP\In2_Head\GetLength) ; get playlength
- If \MusicLength <= 1000 ; use default length?
- \MusicLength = \DefaultLength ; s. Amp_SetDefaultLength(ms)
- EndIf
- EndIf
- EndWith
- ; set starttime (EleapsedMilliseconds() equ 0)
- With RS_AMPTIME
- \msStart = MA_GetTime()
- ;\msStop = \msStart + RS_AMPMASTER\MusicLength
- EndWith
- RETURN_ERR(#EAMP_OK)
- EndProcedure
- ProcedureCDLL Amp_MusicPause(Pause.i)
- ; set/return status of pause (1=pause/0=unpause)
- With RS_AMPMASTER
- Pause = Bool(Pause)
- If \IsPause <> Pause
- \IsPause = Pause
- If \IsPlay
- If \IsPause
- CallCFunctionFast(RS_WINAMP\In2_Head\Pause)
- RS_AMPTIME\msSleep = MA_GetTime() ; ms until unpause
- Else
- CallCFunctionFast(RS_WINAMP\In2_Head\UnPause)
- RS_AMPTIME\msStart + (MA_GetTime() - RS_AMPTIME\msSleep) ; refresh startime
- ;RS_AMPTIME\msStart = MA_GetTime() - (RS_AMPTIME\msSleep - RS_AMPTIME\msStart)
- ;RS_AMPTIME\msStop = RS_AMPTIME\msStart + RS_AMPMASTER\MusicLength ; refresh finish
- EndIf
- EndIf
- EndIf
- ProcedureReturn \IsPause
- EndWith
- EndProcedure
- ProcedureCDLL Amp_MusicStop()
- With RS_AMPMASTER
- If \IsPlay
- \IsPlay = #False
- CallCFunctionFast(RS_WINAMP\In2_Head\Stop)
- EndIf
- EndWith
- EndProcedure
- ProcedureCDLL Amp_MusicSetVolume(Volume.i)
- With RS_AMPMASTER
- If \Volume <> Volume
- If Volume < #Null
- Volume = 0
- ElseIf Volume > 255
- Volume = 255
- EndIf
- \Volume = Volume
- If \IsOpen
- CallCFunctionFast(RS_WINAMP\In2_Head\SetVolume, \Volume)
- EndIf
- EndIf
- ProcedureReturn \Volume
- EndWith
- EndProcedure
- ProcedureCDLL Amp_MusicSetPan(Pan.i)
- With RS_AMPMASTER
- If \Pan <> Pan
- If Pan < -127
- Pan = -127
- ElseIf Pan > 127
- Pan = 127
- EndIf
- \Pan = Pan
- If \IsOpen
- CallCFunctionFast(RS_WINAMP\In2_Head\SetPan, \Pan)
- EndIf
- EndIf
- ProcedureReturn \Pan
- EndWith
- EndProcedure
- ProcedureCDLL Amp_MusicIsPlaying()
- With RS_AMPMASTER
- If \IsOpen = #Null
- ProcedureReturn #Null
- ElseIf RS_WINAMP\In2_Head\UsesOutputPlug
- \IsPlay = CallCFunctionFast(RS_WINAMP\Out_Head\IsPlaying)
- EndIf
- ProcedureReturn \IsPlay
- EndWith
- EndProcedure
- ProcedureCDLL Amp_MusicGetLength(Flags.i)
- ;**************************************************************************************
- ; Flags: 0=MusicLength (eg. DefaultLength)
- ; 1=MusicTime (original length by in_dll)
- ; -------------------------------------------------------------------------------------
- ; Return: total length of music in ms
- ;**************************************************************************************
- If Flags
- ProcedureReturn RS_AMPMASTER\MusicTime
- EndIf
- ProcedureReturn RS_AMPMASTER\MusicLength ; Fast & full musiclength in ms -> s. Amp_MusicPlay (real length)
- EndProcedure
- ProcedureCDLL Amp_MusicGetPosition()
- ;**************************************
- ; Return: current playposition in ms
- ;**************************************
- With RS_WINAMP
- If RS_AMPMASTER\IsPlay
- If \In2_Head\is_seekable And RS_AMPMASTER\MusicLength <> RS_AMPMASTER\DefaultLength
- ProcedureReturn CallCFunctionFast(\In2_Head\GetOutputTime)
- ElseIf \In2_Head\UsesOutputPlug
- ProcedureReturn CallCFunctionFast(\Out_Head\GetOutputTime)
- EndIf
- EndIf
- EndWith
- ProcedureReturn #Null
- EndProcedure
- ProcedureCDLL Amp_MusicGetOutPosition()
- ;****************************************************
- ; Important: use this if in_player is a diskwriter!
- ; Return: written/saved size in ms
- ;****************************************************
- With RS_AMPMASTER
- If \IsPlay And RS_WINAMP\In2_Head\UsesOutputPlug
- ProcedureReturn CallCFunctionFast(RS_WINAMP\Out_Head\GetOutputTime)
- EndIf
- EndWith
- ProcedureReturn #Null
- EndProcedure
- ProcedureCDLL Amp_MusicSetPosition(Milliseconds.i)
- ;****************************************
- ; Milliseconds: position in ms
- ; Return: real playposition in ms
- ;****************************************
- With RS_WINAMP
- If RS_AMPMASTER\IsOpen
- If \In2_Head\is_seekable
- If Milliseconds < #Null
- Milliseconds = 0
- ElseIf Milliseconds > RS_AMPMASTER\MusicLength
- Milliseconds = RS_AMPMASTER\MusicLength
- EndIf
- If RS_AMPMASTER\IsPlay
- CallCFunctionFast(\In2_Head\SetOutputTime, Milliseconds)
- If \In2_Head\UsesOutputPlug
- CallCFunctionFast(\Out_Head\Flush, Milliseconds)
- EndIf
- EndIf
- Else
- Milliseconds = Amp_MusicGetPosition() ;CallCFunctionFast(\Out_Head\GetOutputTime) ; current position in ms
- EndIf
- ; Refresh starttime
- RS_AMPTIME\msStart = MA_GetTime() - Milliseconds
- ProcedureReturn Milliseconds
- EndIf
- EndWith
- EndProcedure
- ProcedureCDLL Amp_MusicGetTitleStr()
- ProcedureReturn @RS_AMPMASTER\MusicTitle$
- EndProcedure
- ProcedureCDLL Amp_InAbout()
- If RS_AMPMASTER\IsOpen = #False : RETURN_ERR(#EAMP_NO_INDLL) : EndIf
- With RS_WINAMP
- If \In2_DLL And \In2_Head\About : CallCFunctionFast(\In2_Head\About, \WindowID) : EndIf
- EndWith
- EndProcedure
- ProcedureCDLL Amp_InConfig()
- If RS_AMPMASTER\IsOpen = #False : RETURN_ERR(#EAMP_NO_INDLL) : EndIf
- With RS_WINAMP
- If \In2_DLL And \In2_Head\Config : CallCFunctionFast(\In2_Head\Config, \WindowID) : EndIf
- EndWith
- EndProcedure
- ProcedureCDLL Amp_OutAbout()
- If RS_AMPMASTER\IsOpen = #False : RETURN_ERR(#EAMP_NO_OUTDLL) : EndIf
- With RS_WINAMP
- If \Out_DLL And \Out_Head\About : CallCFunctionFast(\Out_Head\About, \WindowID) : EndIf
- EndWith
- EndProcedure
- ProcedureCDLL Amp_OutConfig()
- If RS_AMPMASTER\IsOpen = #False : RETURN_ERR(#EAMP_NO_OUTDLL) : EndIf
- With RS_WINAMP
- If \Out_DLL And \Out_Head\Config : CallCFunctionFast(\Out_Head\Config, \WindowID) : EndIf
- EndWith
- EndProcedure
- ProcedureCDLL Amp_InfoBox(*File)
- ; Shows in_dll depended informations
- If RS_AMPMASTER\IsOpen = #False : RETURN_ERR(#EAMP_NO_INDLL) : EndIf
- If Amp_IsFile(*File) = #False : RETURN_ERR(#EAMP_OPEN_FILE) : EndIf
- With RS_WINAMP
- If \In2_DLL And \In2_Head\InfoBox
- ProcedureReturn CallCFunctionFast(\In2_Head\InfoBox, *File, \WindowID)
- EndIf
- EndWith
- ProcedureReturn #Null
- EndProcedure
- ProcedureCDLL Amp_GetFileInfo(*File, *Title, *Length)
- ;************************************************
- ; File = 0 -> current played file
- ; Title = Buffer{2048} for real title of module
- ; Length = Integer for time in ms
- ;************************************************
- If RS_AMPMASTER\IsOpen = #False : RETURN_ERR(#EAMP_NO_INDLL) : EndIf
- If Amp_IsFile(*File) = #False : RETURN_ERR(#EAMP_OPEN_FILE) : EndIf
- With RS_WINAMP
- If \In2_DLL And \In2_Head\GetFileInfo
- CallCFunctionFast(\In2_Head\GetFileInfo, *File, *Title, *Length)
- EndIf
- EndWith
- EndProcedure
- ProcedureCDLL Amp_SetDefaultLength(Milliseconds.i)
- ;**************************************************************
- ; Set default playlength if no calculated musiclength by in_dll
- ; -------------------------------------------------------------
- ; Milliseconds = length in ms or default length (300000)
- ;**************************************************************
- With RS_AMPMASTER
- If Milliseconds <= #Null
- Milliseconds = #DAMP_LENGTH
- EndIf
- \DefaultLength = Milliseconds
- EndWith
- EndProcedure
- ProcedureCDLL Amp_GetInFormatStr()
- ; Return supported tracker + (*.formats;..) by in_dll only (winamp)
- If RS_AMPMASTER\IsOpen = #False : RETURN_ERR(#EAMP_NO_INDLL) : EndIf
- With RS_AMPMASTER
- Protected NewList Srt.s()
- Protected i, e$, i$
- Protected *Ptr.Character = RS_WINAMP\In2_Head\FileExtensions
- If *Ptr
- \Formats$ = #Null$ ; clear string
- While *Ptr\c
- e$ = PeekS(*Ptr) : *Ptr + Len(e$) + SizeOf(Character)
- i$ = PeekS(*Ptr) : *Ptr + Len(i$) + SizeOf(Character)
- i = StrStrI_(i$, "(")
- AddElement(Srt())
- If i
- CharLower_(i) : Srt() = i$
- Else
- CharLower_(@e$): Srt() = i$ + " (" + e$ + ")" ; eg. in_tfmx.dll
- EndIf
- Wend
- SortList(Srt(), #PB_Sort_Ascending)
- ForEach Srt()
- \Formats$ + Srt() + #LF$
- Next
- \Formats$ = Trim(\Formats$, #LF$)
- Else
- \Formats$ = #Empty$ ; must set empty$ coz error if null$
- EndIf
- FreeList(Srt())
- ProcedureReturn @\Formats$
- EndWith
- EndProcedure
- ProcedureCDLL Amp_SetAmpPath(*Path)
- ; Set path for in_/out_dll
- With RS_AMPMASTER
- If *Path
- \Path$ = PeekS(*Path)
- Else
- \Path$ = GetPathPart(\ProgramName$) + #DAMP_PATH$
- EndIf
- If Right(\Path$, 1) <> "\" : \Path$ + "\" : EndIf
- \InPath$ = \Path$
- \OutPath$ = \Path$
- EndWith
- EndProcedure
- ProcedureCDLL Amp_SetInPath(*Path)
- ; Set path for in_dll only
- With RS_AMPMASTER
- If *Path
- \InPath$ = PeekS(*Path)
- Else
- \InPath$ = GetPathPart(\ProgramName$) + #DAMP_PATH$
- EndIf
- If Right(\InPath$, 1) <> "\" : \InPath$ + "\" : EndIf
- EndWith
- EndProcedure
- ProcedureCDLL Amp_SetInDll(*InLib)
- ; Set in_dll for musicfile
- With RS_AMPMASTER
- If *InLib
- \InDll$ = PeekS(*InLib) : If GetPathPart(\InDll$) : \InPath$ = GetPathPart(\InDll$) : EndIf
- EndIf
- EndWith
- EndProcedure
- ProcedureCDLL Amp_SetOutPath(*Path)
- ; Set path to out_dll only
- With RS_AMPMASTER
- If *Path
- \OutPath$ = PeekS(*Path)
- Else
- \OutPath$ = GetPathPart(\ProgramName$) + #DAMP_PATH$
- EndIf
- If Right(\OutPath$, 1) <> "\" : \OutPath$ + "\" : EndIf
- EndWith
- EndProcedure
- ProcedureCDLL Amp_SetOutDll(*OutLib)
- ; Set out_dll for musicplay
- With RS_AMPMASTER
- If *OutLib
- \OutDll$ = PeekS(*OutLib) : If GetPathPart(\OutDll$) : \OutPath$ = GetPathPart(\InDll$) : EndIf
- EndIf
- EndWith
- EndProcedure
- ProcedureCDLL Amp_SetWindow(*Window)
- ; Set Window for callback
- With RS_AMPMASTER
- If *Window
- \WindowID = *Window
- Else
- \WindowID = GetForegroundWindow_()
- EndIf
- RS_WINAMP\WindowID = \WindowID
- ;SetActiveWindow_(\WindowID)
- EndWith
- EndProcedure
- ProcedureCDLL Amp_GetAmpInDllStr(*File)
- ;**************************************************************************************
- ; If no in_dll is given, Amp searchs for predefined in_dll by extension (*.MOD & MOD.*)
- ; -------------------------------------------------------------------------------------
- ; Return: ptr to string of in_dll
- ;**************************************************************************************
- With RS_AMPMASTER
- \InDll$ = #Empty$
- If *File
- Protected File$ = GetFilePart(PeekS(*File)) ; No spaces allowed (extension can't use it)
- Protected i = CountString(File$, ".") + 1
- If i > 1
- Protected *i_x.RS_INTABLE = *i_n
- Protected a$ = ";" + Trim(StringField(File$, i, ".")) + ";" ; 1. try -> *.MOD (standard PC)
- Protected b$ = ";" + Trim(StringField(File$, 1, ".")) + ";" ; 2. try -> MOD.* (classic Amiga)
- While *i_x\iFLG
- If StrStrI_(@*i_x\iEXT\s, @a$) Or StrStrI_(@*i_x\iEXT\s, @b$)
- \InDll$ = *i_x\iLIB\s : Break
- EndIf
- *i_x + SizeOf(RS_INTABLE)
- Wend
- EndIf
- EndIf
- ProcedureReturn @\InDll$
- EndWith
- EndProcedure
- ProcedureCDLL Amp_CountAmpFormatsAll()
- ;*************************************************************
- ; Calculates number of all supported formats (*.MOD) by AmpLib
- ; ------------------------------------------------------------
- ; Return: Number of all supported formats
- ;*************************************************************
- With RS_AMPMASTER
- If \nAmpFormatsAll : ProcedureReturn \nAmpFormatsAll : EndIf
- Protected i, t$, e$
- Protected *i_x.RS_INTABLE = *i_n
- Protected NewMap Extensions.s()
- While *i_x\iFLG
- i = #Null
- t$ = Trim(*i_x\iEXT\s, ";")
- Repeat
- i + 1 : e$ = StringField(t$, i, ";") : Extensions(e$) + 1
- Until Len(e$) = 0
- *i_x + SizeOf(RS_INTABLE) ; Next in Table-Ptr
- Wend
- \nAmpFormatsAll = MapSize(Extensions()) - 1 ; No/empty extension (-1)
- FreeMap(Extensions())
- ProcedureReturn \nAmpFormatsAll
- EndWith
- EndProcedure
- ProcedureCDLL Amp_CountAmpPlayersAll()
- ;****************************************************************
- ; Calculates number of all supported players (in_*.dll) by AmpLib
- ; ---------------------------------------------------------------
- ; Return: Number of all supported players (in_dlls)
- ;****************************************************************
- With RS_AMPMASTER
- If \nAmpPlayersAll : ProcedureReturn \nAmpPlayersAll : EndIf
- Protected *i_x.RS_INTABLE = *i_n
- While *i_x\iLIB\s
- \nAmpPlayersAll + 1
- *i_x + SizeOf(RS_INTABLE) ; Next in Table-Ptr
- Wend
- ProcedureReturn \nAmpPlayersAll
- EndWith
- EndProcedure
- ProcedureCDLL Amp_GetAmpFormatsStrAll()
- ;***********************************************************
- ; Generates sorted string of all supported formats by AmpLib
- ; ----------------------------------------------------------
- ; Return: ptr to (very long) formatstring (*.A;*.B;*.C;...)
- ;***********************************************************
- With RS_AMPMASTER
- If Len(\sAmpFormatsAll$) : ProcedureReturn @\sAmpFormatsAll$ : EndIf
- Protected i, t$, e$
- Protected *i_x.RS_INTABLE = *i_n
- Protected NewMap Extensions.s()
- Protected NewList Srt.s()
- While *i_x\iFLG
- i = #Null
- t$ = Trim(*i_x\iEXT\s, ";")
- Repeat
- i + 1 : e$ = StringField(t$, i, ";") : Extensions(e$) + 1
- Until Len(e$) = 0
- *i_x + SizeOf(RS_INTABLE) ; Next in Table-Ptr
- Wend
- ForEach Extensions()
- If MapKey(Extensions())
- AddElement(Srt()) : Srt() = MapKey(Extensions())
- EndIf
- Next
- SortList(Srt(), #PB_Sort_Ascending)
- ForEach Srt()
- \sAmpFormatsAll$ + ";*." + Srt()
- Next
- CharLower_(@\sAmpFormatsAll$)
- FreeMap(Extensions())
- FreeList(Srt())
- ProcedureReturn @\sAmpFormatsAll$
- EndWith
- EndProcedure
- ProcedureCDLL Amp_GetAmpInDllsStrAll(*File)
- ;**************************************************************************************
- ; Generates sorted string of all predefined in_dlls used by extension
- ; -------------------------------------------------------------------------------------
- ; Return: ptr to multi-string of in_dlls (in_xamp.dll;in_oldsk00l.dll;in_bass.dll...)
- ;**************************************************************************************
- With RS_AMPMASTER
- \InDllsAll$ = #Empty$
- If *File
- Protected File$ = GetFilePart(PeekS(*File)) ; No spaces allowed in PB (extensions can't use it)
- Protected i = CountString(File$, ".") + 1
- If i > 1
- Protected *i_x.RS_INTABLE = *i_n
- Protected a$ = ";" + Trim(StringField(File$, i, ".")) + ";" ; 1. try -> *.MOD (standard PC)
- Protected b$ = ";" + Trim(StringField(File$, 1, ".")) + ";" ; 2. try -> MOD.* (classic Amiga)
- While *i_x\iFLG
- If StrStrI_(@*i_x\iEXT\s, @a$) Or StrStrI_(@*i_x\iEXT\s, @b$)
- \InDllsAll$ + *i_x\iLIB\s + ";"
- EndIf
- *i_x + SizeOf(RS_INTABLE)
- Wend
- EndIf
- EndIf
- ProcedureReturn @\InDllsAll$
- EndWith
- EndProcedure
- ProcedureCDLL Amp_GetErrorStr(Error.i)
- With RS_AMPMASTER
- Select Error
- Case #EAMP_OK : \ErrorStr$ = #SAMP_OK$
- Case #EAMP_NO_INDLL : \ErrorStr$ = #SAMP_NO_INDLL$
- Case #EAMP_NO_OUTDLL : \ErrorStr$ = #SAMP_NO_OUTDLL$
- Case #EAMP_OPEN_FILE : \ErrorStr$ = #SAMP_OPEN_FILE$
- Case #EAMP_OPEN_INDLL : \ErrorStr$ = #SAMP_OPEN_INDLL$
- Case #EAMP_OPEN_OUTDLL : \ErrorStr$ = #SAMP_OPEN_OUTDLL$
- Case #EAMP_UNKOWN_FORMAT : \ErrorStr$ = #SAMP_UNKOWN_FORMAT$
- Case #EAMP_INITIALIZE : \ErrorStr$ = #SAMP_INITIALIZE$
- Default
- \ErrorStr$ = #SAMP_UNKNOWN$
- EndSelect
- ProcedureReturn @\ErrorStr$
- EndWith
- EndProcedure
- ProcedureCDLL Amp_GetError()
- ProcedureReturn RS_AMPMASTER\ErrorN
- EndProcedure
- ProcedureCDLL Amp_GetInInfoStr()
- ProcedureReturn @RS_AMPMASTER\InInfo$
- EndProcedure
- ProcedureCDLL Amp_GetOutInfoStr()
- ProcedureReturn @RS_AMPMASTER\OutInfo$
- EndProcedure
- ;-
- ;- *** Sub-Songs ***
- ProcedureCDLL Amp_SetSubSong(*File, SubSong.i)
- ;***************************************
- ; Set number of subsong to replay
- ; --------------------------------------
- ; *File: @Ptr to full Path + Filename
- ; SubSong: Number of subsong
- ; --------------------------------------
- ; Return: #EAMP_OK if all ok
- ;***************************************
- With RS_AMPMASTER
- If Amp_IsFile(*File) = #False : RETURN_ERR(#EAMP_OPEN_FILE) : EndIf
- If SubSong <= #Null : SubSong = 1 : EndIf
- Protected hF, i, TFM_OFFSET
- Protected RS_PSID.RS_PSID
- Protected RS_TFMX.RS_TFMX, *TFMX.RS_TFMX_AMP
- \SubSong = SubSong
- hF = OpenFile(#PB_Any, PeekS(*File))
- If hF
- \ID = ReadLong(hF)
- Select \ID
- ; *** PSID
- Case #ID_PSID
- FileSeek(hF, #Null)
- If ReadData(hF, @RS_PSID, SizeOf(RS_PSID)) = SizeOf(RS_PSID)
- \NumSongs = UINT16(RS_PSID\songs)
- If \SubSong <= \NumSongs And \SubSong <> UINT16(RS_PSID\startSong)
- FileSeek(hF, OffsetOf(RS_PSID\startSong))
- WriteWord(hF, UINT16(\SubSong))
- FlushFileBuffers(hF)
- EndIf
- EndIf
- ; *** TFMX Hardcoded! Creates a not official TAG -> would be glad if another way to play subsongs in WinAMP!?
- Case #ID_TFMX
- i = ReadLong(hF)
- Select i
- Case #ID_SONG, #ID_2001, #ID_TMOD ; Really TFMX-Song?
- If i = #ID_TMOD : TFM_OFFSET = $14 : EndIf ; TFM -> Merged MDAT + SMPL?
- FileSeek(hF, TFM_OFFSET)
- If ReadData(hF, @RS_TFMX, SizeOf(RS_TFMX)) = SizeOf(RS_TFMX)
- *TFMX = @RS_TFMX\StartPos - SizeOf(RS_TFMX_AMP)
- If *TFMX\ID = #ID_AMP0 And *TFMX\NumSongs >= \SubSong
- \NumSongs = *TFMX\NumSongs
- RS_TFMX\StartPos [0] = *TFMX\StartPos ; Get/Restore SubSong[0] Start
- RS_TFMX\EndPos [0] = *TFMX\EndPos ; Get/Restore SubSong[0] End
- RS_TFMX\Tempo [0] = *TFMX\Tempo ; Get/Restore SubSong[0] Tempo
- *TFMX\SubSong = \SubSong - 1 ; Set SubSong[n] as SubSong[0]
- FileSeek(hF, #TFMX_AMP_OFFSET + OffsetOf(RS_TFMX_AMP\SubSong) + TFM_OFFSET) : WriteByte(hF, *TFMX\SubSong) ; Default SubSong
- FileSeek(hF, OffsetOf(RS_TFMX\StartPos) + TFM_OFFSET) : WriteData(hF, @RS_TFMX\StartPos [*TFMX\SubSong], SizeOf(Word)) ; $100
- FileSeek(hF, OffsetOf(RS_TFMX\EndPos) + TFM_OFFSET) : WriteData(hF, @RS_TFMX\EndPos [*TFMX\SubSong], SizeOf(Word)) ; $140
- FileSeek(hF, OffsetOf(RS_TFMX\Tempo) + TFM_OFFSET) : WriteData(hF, @RS_TFMX\Tempo [*TFMX\SubSong], SizeOf(Word)) ; $180
- EndIf
- EndIf
- EndSelect
- Case #ID_FR10, #ID_FR12, #ID_FR4E, #ID_FR78 ; Really FRED Song? (*.fred)
- FileSeek(hF, $40) ; Min. Offset
- For i = 0 To $80
- If ReadWord(hF)&$FFFF = #ID_FRSS ; ID SubSongs?
- \NumSongs = ReadByte(hF) ; always $60 -> 6 Songs so we set it to 15 (#MAX_FRED)
- \NumSongs = #MAX_FRED-1
- \SubSong - 1
- If \SubSong <= \NumSongs
- \SubSong << 4 ; Nibblebyte to max. $F0
- WriteByte(hF, \SubSong)
- EndIf
- Break
- EndIf
- Next
- ; *** NSF
- Case #ID_NESM
- If ReadWord(hF) = $011A
- \NumSongs = ReadByte(hF)
- If \SubSong <= \NumSongs
- WriteByte(hF, \SubSong)
- EndIf
- EndIf
- ; *** GBS
- Case #ID_GBS1
- \NumSongs = ReadByte(hF)
- If \SubSong <= \NumSongs
- WriteByte(hF, \SubSong)
- EndIf
- EndSelect
- CloseFile(hF)
- EndIf
- EndWith
- RETURN_ERR(#EAMP_OK)
- EndProcedure
- ProcedureCDLL Amp_GetSubSong(*File)
- ;***************************************************************************
- ; Get actual subsong of format: *.sid;*.mdat;*.tfm;*.tfx;*.nsf;*.gbs;*.fred
- ; --------------------------------------------------------------------------
- ; *File: @Ptr to full Path + Filename
- ; --------------------------------------------------------------------------
- ; Return: Number of actual subsong or < #NULL if error
- ;***************************************************************************
- With RS_AMPMASTER
- If Amp_IsFile(*File) = #False : RETURN_ERR(#EAMP_OPEN_FILE) : EndIf
- Protected hF, i, TFM_OFFSET
- \SubSong = #Null
- hF = OpenFile(#PB_Any, PeekS(*File))
- If hF
- \ID = ReadLong(hF)
- Select \ID
- Case #ID_PSID ; *.sid
- FileSeek(hF, OffsetOf(RS_PSID\startSong))
- \SubSong = ReadWord(hF)
- \SubSong = UINT16(\SubSong)
- Case #ID_TFMX ; mdat.*
- i = ReadLong(hF)
- Select i
- Case #ID_SONG, #ID_2001, #ID_TMOD ; Really TFMX-Song?
- If i = #ID_TMOD : TFM_OFFSET = $14 : EndIf ; Merged MDAT + SMPL?
- FileSeek(hF, #TFMX_AMP_OFFSET+TFM_OFFSET)
- If ReadLong(hF)= #ID_AMP0 ; You must! have called Amp_CountSubSongs() first (creates AMP0 tag)
- \NumSongs = ReadByte(hF)
- \SubSong = ReadByte(hF) + 1
- EndIf
- EndSelect
- Case #ID_FR10, #ID_FR12, #ID_FR4E, #ID_FR78 ; Really FRED Song? (*.fred)
- FileSeek(hF, $40) ; Min. Offset
- For i = 0 To $80
- If ReadWord(hF)&$FFFF = #ID_FRSS ; ID SubSongs?
- \NumSongs = ReadByte(hF)
- \SubSong = ReadByte(hF) : \SubSong = (\SubSong >> 4) & #MAX_FRED + 1
- Break
- EndIf
- Next
- Case #ID_NESM ; *.nsf
- If ReadWord(hF)= $011A ; Really NSF-Song?
- \NumSongs = ReadByte(hF)
- \SubSong = ReadByte(hF)
- EndIf
- Case #ID_GBS1 ; *.gbs
- \NumSongs = ReadByte(hF)
- \SubSong = ReadByte(hF)
- EndSelect
- CloseFile(hF)
- EndIf
- ProcedureReturn \SubSong
- EndWith
- EndProcedure
- ProcedureCDLL Amp_CountSubSongs(*File)
- ;******************************************************************
- ; Calculate subsongs of *.sid;*.mdat;*.tfm;*.tfx;*.nsf;*.gbs;*.fred
- ;******************************************************************
- With RS_AMPMASTER
- If Amp_IsFile(*File) = #False : RETURN_ERR(#EAMP_OPEN_FILE) : EndIf
- Protected hF, i, TFM_OFFSET
- Protected RS_TFMX.RS_TFMX
- \NumSongs = #Null
- hF = OpenFile(#PB_Any, PeekS(*File)) ; read/write
- If hF
- \ID = ReadLong(hF)
- Select \ID
- Case #ID_PSID ; *.sid
- FileSeek(hF, OffsetOf(RS_PSID\songs))
- \NumSongs = ReadWord(hF)
- \NumSongs = UINT16(\NumSongs)
- Case #ID_TFMX
- i = ReadLong(hF)
- Select i
- Case #ID_SONG, #ID_2001, #ID_TMOD ; Really TFMX (Custom) - Song? *.mdat(7), *.tfm, *.tfx
- If i = #ID_TMOD : TFM_OFFSET = $14 : EndIf ; Skip merged MDAT + SMPL header of *.tfm?
- FileSeek(hF, TFM_OFFSET)
- If ReadData(hF, @RS_TFMX, SizeOf(RS_TFMX)) = SizeOf(RS_TFMX)
- FileSeek(hF, #TFMX_AMP_OFFSET+TFM_OFFSET)
- If ReadLong(hF) <> #ID_AMP0 ; Create AMP0 Tag?
- \NumSongs = 1 ; always 1 song!
- For i = 1 To 31 ; Calculate real NumSongs[2..32]
- If (RS_TFMX\StartPos[i] Or RS_TFMX\EndPos[i]) And RS_TFMX\StartPos[i]<>$FF01 ; Code end of songs?
- If (RS_TFMX\StartPos[i-1]<>RS_TFMX\StartPos[i] Or RS_TFMX\EndPos[i-1]<>RS_TFMX\EndPos[i]) ; no similar songs
- \NumSongs + 1
- EndIf
- EndIf
- Next
- FileSeek(hF, #TFMX_AMP_OFFSET+TFM_OFFSET) ; Hardcoded Tag RSET
- ;i = #ID_AMP0
- WriteLong(hF, #ID_AMP0) ; ID-TAG
- WriteByte(hF, \NumSongs) ; Number of avail songs (1-32)
- ;i = #Null
- WriteByte(hF, #Null) ; Default SubSong[0-31] always NULL at first time
- WriteData(hF, @RS_TFMX\StartPos,SizeOf(Word)) ; Default StartSong[0]
- WriteData(hF, @RS_TFMX\EndPos, SizeOf(Word)) ; Default EndSong[0]
- WriteData(hF, @RS_TFMX\Tempo, SizeOf(Word)) ; Default Tempo[0]
- Else ; AMP0-Tag already exist!
- \NumSongs = ReadByte(hF)
- \SubSong = ReadByte(hF)
- EndIf
- EndIf
- EndSelect
- Case #ID_FR10, #ID_FR12, #ID_FR4E, #ID_FR78 ; Really FRED Song? (*.fred)
- ; FileSeek(hF, $40) ; Min. Offset
- ; For i = 0 To $80
- ; If ReadWord(hF)&$FFFF = #ID_FRSS ; ID SubSongs?
- ; \NumSongs = ReadByte(hF)
- ; \NumSongs = UINT8(\NumSongs) + 1
- ; Break
- ; EndIf
- ; Next
- ; *** NOTE:
- ; That is constant crap, but no info of variable header! There are not always
- ; subsongs, or/and wrong calculated by in_oldskool.dll!
- \NumSongs = #MAX_FRED ; please check the songinfo
- Case #ID_NESM
- If ReadWord(hF) = $011A
- \NumSongs = ReadByte(hF)
- \SubSong = ReadByte(hF)
- EndIf
- Case #ID_GBS1
- \NumSongs = ReadByte(hF)
- \SubSong = ReadByte(hF)
- EndSelect
- CloseFile(hF)
- EndIf
- ProcedureReturn \NumSongs
- EndWith
- EndProcedure
- ;-
- ;- *** Intern time-handling ***
- ProcedureCDLL Amp_SetLength(Milliseconds.i)
- RS_AMPMASTER\MusicLength = Milliseconds
- EndProcedure
- ProcedureCDLL Amp_GetPlayTime()
- ; return played time in ms
- With RS_AMPTIME
- If RS_AMPMASTER\IsPlay
- \msPlay = MA_GetTime() - \msStart
- EndIf
- ProcedureReturn \msPlay
- EndWith
- EndProcedure
- ProcedureCDLL Amp_GetStopTime()
- ; return rest of time until stop
- With RS_AMPTIME
- If RS_AMPMASTER\IsPlay
- \msStop = RS_AMPMASTER\MusicLength - (MA_GetTime() - \msStart)
- If \msStop < #Null
- \msStop = #Null
- EndIf
- EndIf
- ProcedureReturn \msStop
- EndWith
- EndProcedure
- ProcedureCDLL Amp_GetPercent()
- ; return percent of played time
- With RS_AMPTIME
- If RS_AMPMASTER\IsPlay
- \msPercent = 100.0 / (RS_AMPMASTER\MusicLength * 0.001) * ((MA_GetTime() - \msStart) * 0.001)
- If \msPercent < #Null
- \msPercent = #Null
- ElseIf \msPercent > 100
- \msPercent = 100
- EndIf
- EndIf
- ProcedureReturn \msPercent
- EndWith
- EndProcedure
- ;-
- ;- *** Quick replay ***
- ProcedureCDLL Amp_Play(*File, Volume.i)
- Protected t$, i$, i
- With RS_AMPMASTER
- If Amp_IsFile(*File) = #False : RETURN_ERR(#EAMP_OPEN_FILE) : EndIf
- Amp_Init()
- ; get all avail in_libs for format
- t$ = PeekS(Amp_GetAmpInDllsStrAll(*File))
- ; try until replay song by one of given in_libs
- For i = 1 To CountString(t$, ";")
- ; out_wave_audio.dll doesn't play mp3
- If StrStrI_(*File, @".mp3")
- Amp_SetOutDll(@"out_wave_gpl.dll")
- Else
- Amp_SetOutDll(@"out_wave_audio.dll")
- EndIf
- Amp_SetAmpPath(0)
- SetCurrentDirectory(\Path$)
- ; try first/next in_lib
- i$ = StringField(t$, i, ";")
- Amp_SetInDll(@i$)
- If Amp_Open() = #EAMP_OK
- \Volume = Volume
- If Amp_MusicPlay(*File) = #EAMP_OK
- Break
- EndIf
- EndIf
- Next
- ProcedureReturn \ErrorN
- EndWith
- EndProcedure
- ProcedureCDLL Amp_QuickPlay(*File, *Path)
- ;If Amp_IsFile(*File) = #False : RETURN_ERR(#EAMP_OPEN_FILE) : EndIf
- Protected t$, RetVal
- With RS_AMPMASTER
- Amp_Init()
- Amp_GetAmpInDllStr(*File)
- If Len(\InDll$) = #Null : RETURN_ERR(#EAMP_NO_INDLL) : EndIf
- Amp_SetAmpPath(*Path)
- SetCurrentDirectory(\Path$)
- If Amp_Open() = #EAMP_OK And Amp_MusicPlay(*File) = #EAMP_OK
- Amp_MusicSetVolume(#DAMP_VOLUME)
- t$ = RSet(StrU((\MusicLength/(1000*60*60))),2, "0") + ":" + ; HH:
- RSet(StrU((\MusicLength/(1000*60))%60),2, "0") + ":" + ; MM:
- RSet(StrU((\MusicLength/1000)%60), 2, "0") ; SS
- If (\MusicLength%1000) ; ,TTT -> Rest milliseconds?
- t$ + "," + RTrim(StrU(\MusicLength%1000), "0")
- EndIf
- t$ = "File:" + #TAB$ + GetFilePart(\MusicFile$)+ #CR$ + #CR$ +
- "Plugin:" + #TAB$ + GetFilePart(\InDll$) + #CR$ +
- #TAB$ + \InInfo$ + #CR$ + #CR$ +
- ;"Plugout:" + #TAB$ + GetFilePart(\OutDll$) + #CR$ +
- ; #TAB$ + \OutInfo$ + #CR$ + #CR$ +
- "Time:" + #TAB$ + t$
- Else
- t$ = PeekS(Amp_GetErrorStr(\ErrorN))
- EndIf
- Amp_VersionStr(0)
- MA_MsgBox(\WindowID, t$, \Version$)
- RetVal = \ErrorN
- Amp_Free()
- ProcedureReturn RetVal
- EndWith
- EndProcedure
- ProcedureCDLL Amp_MusicBox(*File, iFlags.i)
- Protected t$, RetVal
- If *File : t$ = PeekS(*File) : EndIf
- RetVal = AmpPlayer::AmpBox(t$, iFlags)
- ProcedureReturn RetVal
- EndProcedure
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement