INTRODUCTION TO WINAMP THROUGH $COMNOTE to non-scripters or scripters who don't like $com: Feel free to completely ignore this very lengthy post.
In response to the request, here is a fairly complete translation from the help page (the URL is in the FIRST STEPS section) to how you'd use it in mIRC script. I have not translated all of the featured, obviously, but from what I
have translated, you should be able to easily use the other features as you see need them. Furthermore, I have translated all of the ones I felt most people would need to use. This is also an excellent tutorial on how to translate such documentation into a mIRC COM script. Although I downloaded the source of the dll as well, I didn't need to, nor did I use it while I wrote this article.
FIRST STEPS The home page for the COM object this article deals with is
Gen_Scripting and contains all the function calls and their expected syntaxes. First, the COM dll must be registered with Windows. Download the dll from
Gen_Scripting 1004, then unzip it into C:\Program Files\WinAmp\Plugins\. Next, the COM object must be registered with Windows. This need only be done once, installing the COM object dll.
/comreg "C:\Program Files\WinAmp\Plugins\gen_scripting.dll" As with any new COM object you are playing with, it's usually best to type these commands in a separate window within mIRC so you can see what is returned or what mIRC responds with, before quieting the commands with . inside a script. When you
//echo -a $com() commands, you'll get back either a 0 (command failed for some reason) or a 1 (it
appeared to work - although it might not have done what you thought it did); inside your script, of course, you'll use the NULL Command:
!.echo -q $com to throw away that 0 or 1.
Note that when I need to retain values between command lines in this article, I use
//set -u60 %variablename value. This is to give you 60 seconds to type in the next command(s) at the command line before the variable expires and is removed. In a real script, you would probably want to use
var %variablename = $com(WinAmp).result for that.
I would suggest that you open a custom window in which to type the commands that follow so that all the output is in a single place, a window you can log or not as you see fit.
/window -Ek @WinAmpNotice that I've used a multiline editbox in this window definition. This is so that you can paste in multiple command lines at a time and then hit enter to do them all at once, pretty much minimizing the /set -u issues as described before. The -k is just habit, I prefer my window buttons without the leading @ since it's already in the icon.
CREATING THE COM OBJECT Since you'll only ever be using a single such COM object at any given time, there is no need to bother with adding $ticks to its name to make it a unique object name. I suggest using either
objWinAmp,
oWinAmp or just
WinAmp as the object name. I will use
WinAmp in all of my examples in this article.
Also, since those who use WinAmp tend to leave it running while their computer is on, it can safely be assumed that mIRC can create the COM object in the on START event and remove it in the on EXIT event, though that part's really unnecessary as mIRC is releasing any memory it used anyway.
To create an object from this COM dll, you use the command:
/comopen WinAmp gen_scripting.WinAmp .
* Opened Com 'WinAmp' (gen_scripting.WinAmp) CHECKING IF WINAMP IS RUNNING According to the help page, this dll doesn't work if WinAmp is not already running. So, the first task any script that uses this COM object needs to do is see if WinAmp is already running and, if it is not running, to start it. To do this, we can simply use the WinAmp.GetVersion method.
Remember that methods use a third parameter of 1, parameter gets use a 2 and parameter sets use a 4. Some methods apparently require both method and parameter get (so you add 1 + 2 and use 3), and some even use both method and parameter set (1 + 4 so you use 5).//echo -a * GetVersion: $com(WinAmp, GetVersion, 1) $com(WinAmp).result* GetVersion: 0
This means that WinAmp isn't running, since the $com failed; the script will have to start it. Since I don't particularly care about seeing the WinAmp interface for the purposes of this article (as I want to programmatically control it from within mIRC), I'll use the WScript.Shell (WSH) Run method so I can use the intWindowStyle of 7. (Displays the window as a minimized window. The active window remains active.)
/comopen WSH WScript.Shell
[color:#000060] * Opened Com 'WSH' (WScript.Shell) //echo -a * Run WinAmp: $com(WSH, Run, 1, *bstr, "C:\Program Files\WinAmp\winamp.exe", i1, 7) [/color]
* Run WinAmp: 1
/comclose WSH * Closed Com 'WSH' WinAmp will start minized and mIRC will retain the active application. Now the WinAmp.GetVersion will work:
//echo -a * GetVersion: $com(WinAmp, GetVersion, 1) $com(WinAmp).result* GetVersion: 1 10240
That shows that my WinAmp version 2.80 is running.
$base(10240,10,16) = 0x2800 which is version 2.80. This is not really important for this article, other than to show that WinAmp really is running.
CLEARING THE PLAYLIST This step can be skipped if you have a playlist you like already loaded into WinAmp, of course, but for the sake of this example, we'll start with a blank playlist and add files to it, just for the practice.
//echo -a * WinAmp.ClearPlaylist(): $com(WinAmp, ClearPlaylist, 1) * WinAmp.ClearPlaylist(): 1
CHANGING DIRECTORY This is simple and straightforward, but it does show how to set the current directory for WinAmp. Note that this is necessary if you plan on adding files programmatically. When you add files to the playlist, WinAmp must be in that directory and the files must be added without a path. This is because what is added to the playlist window is not the exact filename, but rather a combination of ID3 tags; the filename is generally hidden.
//echo -a * WinAmp.ChangeDirectory($mp3dir): $com(WinAmp, ChangeDirectory, 1, bstr, $+(",$mp3dir,")) * WinAmp.ChangeDirectory($mp3dir): 1
ADDING FILES Suppose that I have some legal mp3s I've gathered from around the Internet, and all of them start with "Oldies - ", and all of them are within my $mp3dir, E:\MP3\. If all of those things are true and I also wish to add them to my current WinAmp Playlist, I can use $findfile()'s command parameter with my $com(WinAmp to add them all very quickly indeed.
//echo -a * FindFile: $findfile($mp3dir,Oldies*.mp3,0,1, echo -a WinAmp.PlayFile: $com(WinAmp, PlayFile, 1, bstr, $nopath($1-)) $1-) WinAmp.PlayFile: 1 E:\MP3\Oldies - Brown-eyed Girl.mp3
WinAmp.PlayFile: 1 E:\MP3\Oldies - I Can See Clearly Now.mp3
WinAmp.PlayFile: 1 E:\MP3\Oldies - Jailhouse Rock.mp3
WinAmp.PlayFile: 1 E:\MP3\Oldies - Johhny Be Good.mp3
WinAmp.PlayFile: 1 E:\MP3\Oldies - Lollipop.mp3
WinAmp.PlayFile: 1 E:\MP3\Oldies - Breaking Up Is Hard To Do.mp3
WinAmp.PlayFile: 1 E:\MP3\Oldies - Tell Laura That I Love Her.mp3
WinAmp.PlayFile: 1 E:\MP3\Oldies - Tequila.mp3
WinAmp.PlayFile: 1 E:\MP3\Oldies - Wild Thing.mp3
WinAmp.PlayFile: 1 E:\MP3\Oldies - Stand By Me.mp3
* FindFile: 10
SETTING THE PLAYLIST POSITION POINTER The WinAmp playlist is a 0-based array of filenames. That means that the first file is file 0 and the last file is WinAmp.GetPlaylistLength - 1. If I still have the above files in my playlist, GetPlaylistLength will be 10. However, if you specify a number past the end of the playlist count, the last file will be selected, so it's just as easy to skip the math in WinAmp.GetPlaylistLength - 1, and just use WinAmp.GetPlaylistLength, as shown below.
First file in the list:
//echo -a * WinAmp.SetPlaylistPosition(0): $com(WinAmp, SetPlaylistPosition, 1, i4, 0) * WinAmp.SetPlaylistPosition(0): 1
Last file in the list:
//echo -a * WinAmp.GetPlaylistLength: $com(WinAmp, GetPlaylistLength, 2) = $com(WinAmp).result
* WinAmp.GetPlaylistLength: 1 = 10
//set -u60 %LastMP3 $com(WinAmp).result
//echo -a * WinAmp.SetPlaylistPosition(0): $com(WinAmp, SetPlaylistPosition, 1, i4, %LastMP3) * WinAmp.SetPlaylistPosition(9): 1
PLAYING FILES After you have selected a file, you can use WinAmp.ButtonPlay to click the Play button, just as if you'd used the mouse (without graphically depressing the button of course).
To play the currently selected file:
//echo -a * WinAmp.ButtonPlay: $com(WinAmp, ButtonPlay, 1) * WinAmp.ButtonPlay: 1
To play the next file in the playlist:
//echo -a * WinAmp.ButtonNextTrack: $com(WinAmp, ButtonNextTrack, 1) * WinAmp.ButtonNextTrack: 1
To play the previous file in the playlist:
//echo -a * WinAmp.ButtonPreviousTrack: $com(WinAmp, ButtonPreviousTrack, 1) * WinAmp.ButtonPreviousTrack: 1
To fade out and stop:
//echo -a * WinAmp.ButtonFadeOutAndStop: $com(WinAmp, ButtonFadeOutAndStop, 1) * WinAmp.ButtonFadeOutAndStop: 1
To stop immediately:
//echo -a * WinAmp.ButtonStop: $com(WinAmp, ButtonStop, 1) * WinAmp.ButtonStop: 1
PAUSING FILES Occasionally, you need to pause the currently playing MP3. Using mIRC's built-in /splay + WMP, you have to use a variable or a #group and set/check its status to determine if you're paused or not. With this COM object, you can check directly, using WinAmp.IsPlaying. It returns 0 if it's stopped, 1 if it's playing and 3 if it's paused. You can use WinAmp.ButtonPause to toggle it, regardless of its current state. If the file is paused, WinAmp.ButtonPlay will continue playing from where it was paused; if it's currently playing, WinAmp.ButtonPlay will restart the current file.
To pause (or unpause) the currently playing file:
//echo -a * WinAmp.ButtonPause: $com(WinAmp, ButtonPause, 1) * WinAmp.ButtonPause: 1
To check if WinAmp is paused:
//echo -a * WinAmp.IsPlaying: $com(WinAmp, IsPlaying, 2) = $com(WinAmp).result * WinAmp.ButtonIsPlaying: 1 = 3
//set -u60 %Paused $com(WinAmp).result
//if (%Paused == 3) echo -a * WinAmp is paused | elseif (%Paused == 1) echo -a * WinAmp is playing | else echo -a * WinAmp is stopped * WinAmp is paused
THE EQUALIZER AND PREAMP, VOLUME AND BALANCE There are 10 "bands" (0-9) available for use in a dialog (for example) that uses 10 scroll controls, that should be initialized
range 0 63 (+20 dB to -20 dB). There is also a preamp on band 10 (same range as the equalizer) with a button on band 11 to turn it on and off, and check that button's value. Note that while you
can adjust the volume with WinAmp, mIRC's control has a much more control (
range 0 65535) than WinAmp (
range 0 255). With WinAmp.SetPanning(), you can adjust the balance, left to right, with a scroll control as well, which should be initialized
range -128 128 and probably set to WinAmp.SetPanning(0) initially to center it. Since this isn't something you're likely to do from the keyboard, this next example section is written strictly as a script section, as you might use it yourself in a real script, instead. I will stay with this format from here on too, since you probably get the idea by now.
NOTE: 0 is the
highest (all the way to the top) setting and 63 is the
lowest (all the way to the bottom) setting for the equalizer controls.
Assume that we have dialog IDs 10 through 19 as our equalizer scroll controls, and Balance is ID 20, PreAmp is 21 and a button on 22 to turn it on and off.
To check band 0's current setting, change it to halfway and then change it back:
!.echo -q $com(WinAmp, GetEqData, 2, i4, 0)
var %EQ0 = $com(WinAmp).result
!.echo -q $com(WinAmp, SetEqData, 1, i4, 0, i4, 32)
!.echo -q $com(WinAmp, SetEqData, 1, i4, 0, i4, %EQ0)Extending this to include a dialog scroll event (when you change the setting in your own script):
on *:DIALOG:MP3Player:scroll:15: !.echo -q $com(WinAmp, SetEqData, 4, i4, 5, i4, $did($did)) Obviously, the same works for the other EQ controls and the SetPanning, though the SetPanning uses a different method name.
on *:DIALOG:MP3Player:scroll:20: !.echo -q $com(WinAmp, SetPanning, 4, i4, $did($did)Note: while I was playing with SetPanning, setting it to -128 or +128 both shunted the sound all to the left speaker. I'm unsure why that would be.
CURRENTLY PLAYING FILE INFORMATION Many MP3 players display a current position with a scroll control and with the number of elapsed seconds (2:42). To get this iinformation from within mIRC, you use $insong.pos; then you just adjust the scroll control's position based on the value returned and update the time. Moving the scroll control manually moves to different points in the song using /splay seek. All this is possible using the WinAmp COM object as well (which is the major reason I favor it - I have never seen a $dll version that allows this much control over WinAmp and the ability to retrieve as much data about WinAmp's state.
$insong.fname as $WinAmp.fname:
alias WinAmp.fname {- !.echo -q $com(WinAmp, GetPlaylistPosition, 2)
!.echo -q $com(WinAmp, GetPlaylistFile, 2, i4, $com(WinAmp).result)
return $com(WinAmp).result
}/splay seek 1000 as /WinAmp.seek 1000 (in milliseconds):
alias WinAmp.seek !.echo -q $com(WinAmp, SetTrackPositionMilliseconds, 4, i4, $1)
$insong.pos as $WinAmp.pos:
alias WinAmp.pos {- !.echo -q $com(WinAmp, GetTrackPositionMilliseconds, 2)
return $com(WinAmp).result
}$insong.length as $WinAmp.length (in milliseconds):
alias WinAmp.length {- !.echo -q $com(WinAmp, GetTrackLengthSeconds, 2)
return $calc($com(WinAmp).result * 1000)
}Note:
$sound($WinAmp.fname).length is more accurate. You can also add 1 to
$com(WinAmp).result before multiplying by 1000 to simulate rounding up.
$WinAmp.channels:
alias WinAmp.channels {- !.echo -q $com(WinAmp, GetTrackChannels, 2)
return $com(WinAmp).result
} CONCLUSION Apart from $WinAmp.channels, using the above aliases, you can write yourself a simple $MyInsong.Fname to check a variable or hash table or group (or whatever you like) that determines which player is selected, WMP or WinAmp, and requests the information from the correct source, transparent to the rest of your script. For example, if you have a variable named %MP3Player.Player that is set to WinAmp at the moment:
alias MyInsong.fname return $iif(%MP3Player.Player == WinAmp,$WinAmp.fname,$insong.fname) This means that the only changes you have to make throughout your script to get the right file for $insong.fname in either player is to switch all $insong.fname's to $MyInsong.fname everywhere (other than in that alias, of course). The same thing applies to the other commands and identifiers, of course, so it's not just automatic, but it's certainly not hard to do, either.
If you have made it all the way to the bottom of this and understood at least some of it, then I praise you for your perserverence, if for nothing else. I also hope you also find this information useful, either directly in an MP3 script you want to get busy writing or indirectly in some other COM script you have in mind but had questions about.
Happy scripting.