Welcome to PM123!
- Welcome to PM123!
- PM123 User Interface
- Main Window
- Main Menu
- Playlist Menu
- Configuration Dialog
- ID3 Tag Editor
- Sound Visualization Plug-in
- Graphical Sound Equalizer
- Playlist Manager
- Commandline Parameters
- Drag and Drop Operations
- Skin Utility (WinAmp Skins)
- Troubleshooting
- Remote Control
- Support & Contact
- Copyright, Credits and Greetings
- Netscape Navigator Configuration
PM123 is mainly a native OS/2 PM application for playing audio MPEG 1.0, 2.0 and 2.5 Layer I, II, and III. It does so by using mpg123 engine, which is still quite fast. The interface, however, is a whole new world. The player supports:
This is PM123's main window on startup. The window has several controls and lots of status information. The main playing controls are these:
From left to right: play, pause, rewind, fast forward, open/close palylist, load a file, repeat mode, randomize playlist, next song, previous song and power off. Volume can be controlled clicking and dragging the volume bar:
While playing there are some status indicators such as:
![]() Stereo/mono indicator and bitrate |
![]() Playlist index/total |
You can right click the player to open up the main menu.
Keyboard shortcuts: We have defined some keyboard shortcuts to be used from the main window:
![]() |
Open playlist: Opens the playlist window.
Load file: Opens a single file. Load URL: Opens a file from the Internet for streaming. Load Track: Loads a CD track Recall: Displays shortcuts to 10 last used files. Edit tag: Edits the ID3 tag of the currently loaded file. Save Stream: Save a stream from the Internet Add to bookmarks: Add a MP3 to your bookmarks. Edit bookmarks: Edits your bookmarks file. Bookmarks: Display your bookmarks (favourite songs). Properties: Displays PM123's configuration dialog. Plug-ins: Gives easy access to the plug-ins' configuration dialogs. Checked plug-ins are enabled or activated. Load skin: Load a new skin into the player. Equalizer: Displays the Graphical Equalizer. Playlist Manager: Displays the Playlist Manager. Font: A submenu which allows you to select from two fonts. Size: A submenu which allows you to select the size of the player from 3 predefined sizes. Float on top: Toggles 'float on top' option, which allows PM123 to float above all windows. Hide window: Hides the player window. PM123 can be restored by selecting it from the window list. |
![]() |
Use this playlist: Activates this playlist.
Add Files: Add file(s) to the playlist. Add URL: Add HTTP files or playlists (M3Us). Add Tracks: Add CD tracks to the playlist. Clear list: Clear the whole list. Sort: This submenu has options to sort the playlist by size, playing time, filename or songname. Save list: Saves the list. Load list: Loads a saved list. Recall: This submenu has shortcuts to 10 last loaded playlists. |
![]() |
Load: Loads this file into the player. Remove from list: Removes this file from the playlist. Edit tag: Edits this file's ID3 tag. Delete tag: Removes the ID3 tag from this file. |
This proporties dialog can be accessed from the main menu. In the dialog you can configure PM123's audio engine and interface.
Behaviour
Play & load
Start playing on file load: Automatically starts playing when
you load a file
Auto 'use playlist' on add: Automatically selects "Use this
playlist" when adding files or directories to the playlist.
Auto 'play' on 'use playlist': Automatically starts playing
on "Use playlist".
Select played file: Automatically selects currently playing
file in the playlist.
Trash buffers on seek: This option provides a much faster response
on seek operations (fast forward, rewind, jump to position), but consumes
more CPU time during the seek.
Scroll
Infinite: Keeps scrolling the display forth and back until you
start feeling sick :-)
Once: Scrolls the display forth and back once.
Disable: Prevents the display from scrolling. Useful if you
are scroll-sick.
Default display
Filename: Display the filename by default
ID3 tag: Display the ID3 tag by default
File info: Display the file information by default (bitrate,
frequency, mode).
Dock playlist window to x pixels: This will allow the playlist to dock into the main window so that when then main window is moved, the playlist follows. Specify the distance in pixels to allow for docking.
Streaming audio
HTTP proxy URL: Specify your HTTP proxy here.
HTTP auth: This is your HTTP authentication string in format
username:password
Buffer size: Specifies the read ahead buffer size (useful when
plaing across a network or from a streaming source).
Fill buffer before playing: Fills the buffer (see above) before
playing.
PM123's properties dialog, page 2 of 4
Plug-Ins
This dialog is divided into two parts - one for the visual plug-ins and the second for decoder plug-ins
Enable/Disable: Enables/disables the selected plugin.
Unload: Unloads the plugin completely.
Configure: Avalaible only if the plugin is configurable. Click
this button to set plugin's settings.
Add: Add a plugin (visual plugins are skin specific, see PM123
sound visualization)
PM123's properties dialog, page 3 of 4
This dialog is also divided into two parts - in filter plugins part, you can add a filter, in output plugins part you can use a output plugins...
Enable/Disable: Enables/disables the selected plugin.
Unload: Unloads the plugin completely.
Configure: Avalaible only if the plugin is configurable. Click
this button to set plugin's settings.
Add: Add a plugin
Activate: Activate an output plugin.
There must be always one active output plug-in. With wavout plugin, you can save the music to a WAV file. WAVOUT plugin is very useful for gabbing CD audio tracks... ;-)
Last proporties dialog (page 4) is About dialog. There are some info
about PM123, author etc.
"ID3 tag editor? What's that?", you might ask. ID3 tags are way of appending some information to each MP3 file. The information contains song title, artist's name, album's name, music's style, release year and a comment. ID3 tags don't belong to the MPEG standard, but it has already become a widely spread standard among MP3 listeners. It's a good idea to add this tag to your MP3 files (if your filenames get mangled, you'll always know the songname).
PM123's ID3 tag editor window
PM123's tag editor is quite simpled. It can be invoked for the current file from the main menu or by pressing Alt+3 on the player window. You can also edit the tags of the files in the playlist by right clicking a file in the playlist and selecting Edit tag or by pressing Alt+E in the playlist. You can also remote a tag by selecting Delete tag.
PM123's Sound Visualization
plug-in
PM123 comes with a sound visualization plugin, ANALYZER.DLL
which is located in the visplug directory. The plugin is visible right
next to the volume bar. By default it shows the spectrum analyzer. Click
it once to bring up the oscilloscope, a second time to bring up the CPU
monitor and third time to disable it.
The spectrum analyzer.
Note that because the spectrum analyzer is visual plugin, it is skin specific and will not display on older PM123 skins. But you can add them easily to any skin by editing the skin's .SKN file and adding this to it:
1=visplug/analyzer.dll,x,y,size-x,size-yReplace x, y, size-x and size-y with suitable coordinates (a easy way to find out the coordinates for a certain area is to load up PMView, take a Window capture of the skin and use the 'Track info' feature). You can also use WinAmp-compatible viscolor.txt files like this:
1=visplug/analyzer.dll,x,y,size-x,size-y,viscolor.txtThe plugin will then read viscolor.txt and adapt to colors specified in it!
PM123's Graphical Sound Equalizer
PM123 users can enjoy and play with the graphical sound equalizer provided.
PM123 Graphical Equalizer window
To enable the equalizer, click on "Equalizer enabled". Now you can adjust the bands by dragging the sliders. Preamplifier slider does software amplification (useful if your soundcards amplifier is broken). You can also mute bands by clicking on the checkboxes below sliders. To restore everything back to normal, click "Default". You can also save and load equalizer profiles.
If you don't think this equalizer suits your needs well enough, you can use Samuel's Real Equalizer plugin, which provides excellent sound quality and more bands to manipulate. The plugin is provided with PM123 and is located in file realeq.dll. Install it via PM123's Properties dialog (Add filter plugin -button). You can display the configuration window by pressing the Configure button in the same dialog.
Real Equalizer plugin
Adjust FIR Order to suit your machine (at least P150 recommended for FIR order 64).
This Equalizer is a THE real thing. A full fledged FIR designed with the window method using OOURA's RDFT and a Hamming window. This equalizer can also be used with any decoders contrarily to the MPEG audio decoder! Also since it's a real EQ, it uses juice. I mean major juice. Although, with MMX, the overhead is reduced A LOT. I'm planning on using a Remez exchange algorithm instead of the window method to optimize the FIR order needed to achieve the desired result. All I know is that it can "significantly reduce the order of a FIR filter", what that exactly means, I don't know. I also don't have time to work on an IIR based filter, MMX being pretty much the savior of FIR filters on the Intel platform and because IIR filters dephase the sound (lower quality).
To come back on the filter order for the casual user, this is the number of samples processed (in addition to the current sample) to obtain a new sample. What does this means? Ok say you are playing at 44100Hz, this means there are 44100 samples passing per second in the filter also, right? Ok, so say you'd like to catch 20Hz and filter that decently. This means you will need a filter order of at least 44100/20-1 = 2204!!! With values in this range, you can make your stereo EQ jealous. Get a Pentium III or Athlon and ditch your stereo.
This also means that with a small 64 coeficient filter order, the EQ cannot process frequencies under 44100/(64+1) = ~678Hz properly. So the choice of any bands under this frequency might be irrelevant, and modifying one of the other might give the same effect (if any effect at all). The 32 middle octave bands are calculated by step of 1/3 octave as defined by the ISO standard and are as follow in Hz:
ISO Standard Frequencies (Hz) |
---|
16,0 |
20,0 |
25,0 |
31,5 |
40,0 |
50,0 |
63,0 |
80,0 |
100 |
125 |
160 |
200 |
250 |
315 |
400 |
500 |
630 |
800 |
1000 |
1250 |
1600 |
2000 |
2500 |
3150 |
4000 |
5000 |
6300 |
8000 |
10000 |
12500 |
16000 |
20000 |
The FIR order needs to be a multiple of 2 (or 16 because of MMX). The plansize is for the initial FFT and therefore needs to be a power of 2. Just leave it at 8192, that's fine, unless you are planning on playing anything way over 48000kHz.
WARNING!! If you do not "Use MMX", the FPU will be used and you might not be able to get away with 512 coeficients with the FPU. So change it to some more reasonable values such as 64 before trying it.
With MMX, it can play realtime with 768 coeficients on a P166 MMX and it can easily do 4096 with a Celeron 500!! This is pretty much as good as most professional EQs...!!
PM123's Playlist Manager
Playlist Manager is provided for browsing and managing
playlists. Note that Playlist Manager is not a replacement for the
playlist. You can add and remove lists from Playlist Manager, load lists
into the normal playlist, load single files and calculate statistics. Also
note that some of Playlist Manager's options only work with playlists saved
with PM123 1.0.
PM123 Playlist Manager window
Playlist Manager will remember the playlist added to it next time you open it. Right click on an empty space (the title, for example) to get the main menu:
Add a playlist:
Adds a new playlist to the Playlist Manager.
Statistics: Shows statistics for all playlists and files in
Playlist Manager.
Right click on a playlist to get the list menu:
Load this playlist:
Loads this playlist into PM123 playlist.
Statistics: Shows statistics for this playlist only.
Right click on a file to get the file menu:
Load this file:
Loads this playlist into PM123.
PM123 playlist files
PM123 playlist files always have the extension .LST
and they contain simply CR separated lines of the files in playlist (plus
Playlist Manager special lines starting with >). PM123 also understands
.MPL
files used by WarpAMP and M3U playlists used over the Internet.
PM123's Commandline Parameters
PM123 accepts a couple commandline parameters:
-cmd [host] command If `host' is omitted, send commands to local PM123, otherwise send commands to PM123 running on `host'. For a command listing, see PM123 Remote control. -smooth Enables the smooth scroller, which supports national characters and DBCS. Only works with the default skin. -shuffle Shuffles files added from commandline.PM123 also accepts MP3 files, URLs and playlists as commandline parameters.
(the -proxy, -auth and -48as44 options in 1.0 have been moved to the Properties notebook)
PM123 Drag and Drop Operations
You can drag and drop one or more MP3 files to PM123's main window or playlist. You can also drop one or more directories to them, and of course playlist files.
PM123's Skin Utility (WinAmp Skins)
PM123 comes with a skin utility (SKINUTIL.EXE),
which can converts WinAmp skins to
PM123 skins. Here's an example how to convert a WinAmp skin (SKIN.ZIP):
[c:\pm123] md skin [c:\pm123] cd skin [c:\pm123\skin] unzip -j c:\files\skin.zip Archive: c:/files/skin.zip inflating: Viscolor.txt inflating: Position.bmp inflating: Main.BMP inflating: Text.BMP inflating: option.bmp inflating: Cbuttons.bmp inflating: Titlebar.BMP inflating: Monoster.bmp inflating: Posbar.bmp inflating: Shufrep.bmp inflating: Volume.BMP inflating: Numbers.BMP inflating: Playpaus.bmp [c:\pm123\skin] cd .. [c:\pm123] skinutil convert skin PM123 Skin Utility (c) 1998 Taneli Leppä <rosmo@sektori.com> Processing skin/cbuttons.bmp....... Processing skin/titlebar.bmp.......... Processing skin/text.bmp: abcdefghijklmnopqrstuvwxyz_-()&.:0123456789öä ,+%[] Processing skin/posbar.bmp.. Processing skin/volume.bmp... Processing skin/shufrep.bmp:.... Processing skin/monoster.bmp:.. Processing skin/numbers.bmp:............ Processing skin/main.bmp:. Creating skin.dat... Creating skin.pak Bundling... 124 images, total 212444 bytes (207 kB). Creating skin.skn Cleaning up...There you go. You can now load skin.skn from PM123. The skin utility also created files skin.pak and skin.dat that are required if you use the skin. You can also bundle your old skins with lots of small files into two files. Run skinutil.exe without any parameters to see help.
There might be multiple reasons if you encounter this problem. Some of them are listed here. First of all, check your MP3 file. It may be broken. It might play succesfully on another player, but mpg123 may not necessarily like it. If you think it's not related to the input stream, maybe the problem is one of these:Extra effort has been put in creating a priority system that stops skipping. Samuel, who did the priority system, convinces us by saying: "I have played 2 MP3s on my P150 and watched a "dir /s" smooothly and happily scrolling in the foreground without either MP3 skipping... I think that's pretty convincing."
- You have a polling device driver (for example, a very old 2x CD-ROM or PRINT01.SYS without /IRQ switch)
- Bad CD-ROMs tend to seek the disk often. This usually takes 100% CPU and halts I/O operation until the drive completes the seek. You can try cleaning the CD.
- You have a video card that supports "automatic PCI bus retry", but your motherboard stops processing during those retries. Disable the feature (video driver).
- You have an ATI Mach64 and you are experiencing a bug in the video driver using software mouse pointers (ie. colored mouse pointers).
- You have a process that hogs all the CPU. Get a CPU monitor (we recommend CPUMon) and a process killer from hobbes.nmsu.edu.
- You have Full Window Drag enabled. It sucks 100% CPU power when you use it. On Warp 4, disable it from System / User Interface / Window Manipulation / Full Window Dragging.
- Your CPU is too slow (or overheated). We recommend you have at least a Pentium machine.
- You have outdated, old or buggy sound drivers. This is a common problem. Many sound drivers out there for OS/2 just plain suck. We have tried to test PM123 on as many drivers as we can, but some drivers are incomplete and/or buggy.
- You have a very old or just generally bad motherboard, video card or IO controller card. This is a rare problem, though.
- You have an old MPG123.DLL (or some other DLL PM123 comes with) in your LIBPATH.
- Your system doesn't support DIVE (Direct Video Extensions). Try renaming visplug\analyzer.dll to something else.
- Something is very wrong....
PM123 Remote Control
- You have a bad video driver. You should try Scitech Display Drivers which should fix all your problems. If this does not work out, we cannot help you more on this matter, but we urge you to call/mail your video driver manufacturer about this problem.
- You have a colored or animated mouse pointer that is not supported properly by your video driver. They are software mouse cursors and they don't mix very well with high performance multimedia applications that draw rapidly to the screen. SDD drivers do not exhibit this problem. Switch back to the old black and white OS/2 default mouse pointer and/or disable pointer animation. The default b/w pointer is a hardware mouse cursor. This problem is often caused by all high speed DIVE applications.
- If all fails, one way to fix this problem is to set analyzer disabled by default (Properties -> Plug-Ins -> analyzer.dll -> Configure). Of course you won't see the cool graphics then.
PM123 can be remotely controlled via a named pipe, \PIPE\PM123. Named pipes were chosen because of their excellent features. Quoting from the Control Program Programming Guide and Reference: "Named pipes enable related or unrelated processes on either the same computer system or different systems to communicate with each other. Any process that knows the name of a pipe can open and use a named pipe. In addition, named pipe data can be transparently redirected across a network, such as a local area network (LAN)".
To remote control PM123 on the same computer, you can use either the built-in "echo" command, or the PM123 executable itself. PM123 understands a set of commands that are written to the pipe. For example,
[c:\usr\pm123] pm123 -cmd volume 80 [c:\usr\pm123] echo *volume 80 > \pipe\pm123These commands will set the volume to 80%.
[c:\usr\pm123] pm123 -cmd add d:\music\test.mp3 [c:\usr\pm123] echo *add d:\music\test.mp3 > \pipe\pm123These commands will add the file d:\music\test.mp3 to the playlist.
If you use echo, remember to prepend any commands sent to it with a * character. PM123 currently understands the following commands (optional parameters are enclosed in parenthesis):
play file | Starts playing. If file was specified, it will be first loaded and playback will be started. |
stop | Stop playback. |
pause on|off | Pauses or unpauses the playback. |
next | Selects the next song in playlist. |
previous | Selects the previous song in playlist. |
rewind | Toggles rewind of the currently playing file. |
forward | Toggles fast forward of the currently playing file. |
jump n | Jump to n seconds in the currently playing file. |
volume n | Sets volume to n% (scale 0-100, of course). And returns previous volume setting. |
load file | Loads a file into. Plays it too, if 'auto play on load' is set. |
shuffle | Toggles shuffling. |
repeat | Toggles repeat. |
mono on|off | Toggles mono mode on. |
downmix on|off | Toggles downmixing 2 to 1. |
autouse on|off | Toggles 'auto use playlist on add'. |
playonload on|off | Toggles 'auto play on load'. |
playonuse on|off | Toggles 'auto play on playlist use'. |
float on|off | Toggles 'float on top'. |
font 1|2 | Selects font 1 or font 2. |
size regular|small|tiny | Selects the player size. |
hide | Hides the player window. |
add file1;file2;file3 | Adds file(s) to playlist. Multiple files must be separated with ';' characters. |
use | Use the playlist. |
clear | Clears the playlist. |
dir directory | Add directory to the playlist (non-recursive). |
rdir directory | Add directory to the playlist (recursive). |
status tag|file|info | Returns the information currently displayed in the scroller or returns nothing if "no file loaded". |
Now for the cool part. You can control PM123 over your OS/2 Local Area Network. Just use \\SERVER\PIPE\PM123. \\SERVER is the name of the computer PM123 runs on. For example,
[c:\usr\pm123] pm123 -cmd \\mycomputer volume 80 [c:\usr\pm123] echo *volume 80 > \\mycomputer\pipe\pm123 [c:\usr\pm123] pm123 -cmd \\mycomputer add d:\music\test.mp3 [c:\usr\pm123] echo *add d:\music\test.mp3 > \\mycomputer\pipe\pm123Will do the same as examples above, but from a different computer. Easy, isn't it?
Support & Contact
Support is not provided to anybody, so please do not contact us for
problems as neither of us is using OS/2 anymore. Of course, we can always
work on contract. In this case, please do contact us.
Samuel Audet <guardia@step.polymtl.ca> (http://step.polymtl.ca/~guardia/)
Taneli Leppä <rosmo@sektori.com>
Web sites: | http://sektori.com/pm123 |
http://hobbes.nmsu.edu/pub/os2/apps/mmedia/sound/players/ | |
http://www.step.polymtl.ca/~guardia/pm123.php |
Copyright, Credits and Greetings
Rosmo's greetings go out to: Sektori.com folks, dink
(check out his cool Z! MP3 player), Olli 'MrWizard' Maksimainen, Adrian
'ktk' Gschwend (Netlabs rules!), ml, Eirik 'Ltning' Overby, tSS,
PartyGirl, Kerni, NuKe, WinAmp authors for inspiration, #os2finnin
kanta-asiakkaat, #os2prog'ers (now #codepros no?), Sinebrychoff and all
MP3 enthuastics.
Samuel's greetings: Mom, Miho, Sophie, Gerry, Marc, Olli Maksimainen, Mads Orbesen Troest (Leech it!), Eirik Overby (made some cool skins!), dink, nuke (EverBlue ready now?? :), Adrian Gschwend (aka ktk), GryGhost, Julien Pierre (who helped me with MMOS/2 before), Cow_woC, Sander van Leeuwen, Achim Hasenmueller (lou!! WHAT? Odin not ready yet? :) and of course Michael Hipp and Oliver Fromme!!
Finally, thanks to Filip Molcan for updating this manual for pm123 1.1 beta 4!
Please read first the important information in the COPYRIGHT and COPYING files that have been copied below.
Original mpg123 decoder written/modified by:
with help and code from:
Graphical User Interface for pm123 by:
Generalized Bitmap Module by:
Ooura Fourier Transformation Library:
I have replaced all double precision floats to single precision. It gives an awful e-07 precision instead of e-17, but it's faster and e-07 is by far enough for my needs.
You can find the original code and documentation at http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html
COPYING: License for the mpg123 plug-in
This license covers ONLY mpg123.dll, http123.dll and the related source files. Copyright (c) 1995-1999 by Michael Hipp, all rights reserved. Copyright (c) 1998-2003 by Samuel Audet, all rights reserved. Original mpg123 decoder written/modified by: Michael Hipp <Michael.Hipp@student.uni-tuebingen.de> Oliver Fromme <oliver.fromme@heim3.tu-clausthal.de> with help and code from: Samuel Audet <guardia@step.polymtl.ca>: OS/2 port MPEG Software Simulation Group: reference decoder package Tobias Bading: idea for DCT64 in subband synthesis from maplay package Jeff Tsay and Mikko Tommila: MDCT36 from maplay package Philipp Knirsch <phil@mpik-tueb.mpg.de>: DCT36/manual unroll idea Thomas Woerner <..> (SGI Audio) Damien Clermonte <..> (HP-UX audio fixes) Stefan Bieschewski <stb@acm.org>: Pentium optimizations, decode_i586.s Martin Denn <mdenn@unix-ag.uni-kl.de>: NAS port Niklas Beisert <nbeisert@physik.tu-muenchen.de> MPEG 2.5 tables <mycroft@NetBSD.ORG> and <augustss@cs.chalmers.se>: NetBSD Kevin Brintnall <kbrint@visi.com> BSD patch Tony Million: win32 port Steven Tiger Lang: advanced shuffle Henrik P Johnson: HTTP auth patch and more .... Current distribution site for new test versions is the CVS repository. http://www.mpg123.org/ has more information about how to acces the CVS repository. You can get the latest release from http://www.mpg123.org/ DISTRIBUTION: This software may be distributed freely, provided that it is distributed in its entirety, without modifications, and with the original copyright notice and license included. You may distribute your own seperate patches together with this software package or a modified package if you always include a pointer where to get the original unmodified package. In this case you must inform the author about the modified package. The software may not be sold for profit or as "hidden" part of another software, but it may be included with collections of other software, such as CD-ROM images of FTP servers and similar, provided that this software is not a significant part of that collection. Precompiled binaries of this software may be distributed in the same way, provided that this copyright notice and license is included without modification. USAGE: This software may be used freely, provided that the original author is always credited. If you intend to use this software as a significant part of business (for-profit) activities, you have to contact the author first. Also, any usage that is not covered by this license requires the explicit permission of the author. DISCLAIMER: This software is provided as-is. The author can not be held liable for any damage that might arise from the use of this software. Use it at your own risk.COPYRIGHT: License for the rest of PM123
This license covers the entirety of the PM123 source file distribution, except GBM which is left into the public domain, and the mpg123 plug-in (including http123.dll) which is left under the license found in the file named COPYING. Copyright 1997-2003 Samuel Audet <guardia@step.polymtl.ca> Taneli Leppä <rosmo@sektori.com> Copyright 2004-2005 Dmitry A.Steklenev <glass@ptv.ru> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.