Winamp Configuration for International Folk Dance Music Management

Many International Folk Dance groups use a music player and library developed by Neil Rosen for the MIT folkdance club called MITPlayer, which is now maintained by Murray Spiegel of New Jersey folk dancing and hosted here. I dislike the need to create a database manually with MITPlayer. I have a massive collection of folk dance/world music (> 11,000) that I am constantly adding to and promoting individual songs from listening to dancing, and many of the dances have multiple recording choices. I wanted all dance and tune information to be self-contained within the ID3 metadata tags of each music file and have the player program continually self-populate and update a database without human intervention. Winamp monitors files for additions, deletions, and changes and automatically updates the library database. Winamp’s Media Library provides a powerful, advanced database query language and allows searches to be preconfigured into “Smart Views.” Each Smart View configured for Fort Collins folk dance pulls the subset of tunes from the database tagged with “FCTNFD” and, in addition to sorting by dance name and/or country, provides options for slicing and dicing into groups such as favorites, skill levels, types of dances, etc. Lastly, Winamp allows you to build a complex, custom title string to display on the player and playlist. I need all that stuff, so I chose Winamp over MITPlayer, and I did my own international folk dance tweaks to the Winamp configuration for TNFD in Fort Collins and repurpose some ID3 tags for folk-dance specific information.

Tuesday Night Folk Dancing’s Winamp Setup

Winamp was once the top MS Windows media player with many volunteer coders contributing to the plug-in infrastructure. However, with sell-offs, bankruptcies, and stupid corporate moves, Winamp essentially died at version 5.66 in 2013. There is a new version to fix some Windows 7/10/11 incompatibilities, but I haven’t tried the latest. Early post-5.666 versions messed up the media library features, so I have stuck with 5.666, which still works with old Windows NT machines.

Here’s a detailed Winamp installation and configuration document and ZIPs of Winamp 5.666 + essential add-ons and configuration files that TNFD uses:

Winamp Required Components

You have to install Winamp in a non-protected Windows directory, since it is not formally Windows 7/10/11 compatible. Some plug-ins and features store options in the program directory instead of the AppData path. So install your Winamp in something like C:\Programs\Winamp\

These are the original web locations of the components contained in Winamp5666-Base-Install.zip

Excess Winamp Plugings

There are some plug-ins that get installed but are not useful and some that want connect to the Internet or a USB player, so I delete them from the C:\Programs\Winamp\Plugins\ directory:

  • ml_bookmarks.dll, ml_devices.dll, ml_nowplaying.dll, ml_online.dll, ml_pmp.dll, ml_wire.dll
  • pmp_activesync.dll, pmp_android.dll, pmp_ipod.dll, pmp_njb.dll, pmp_p4s.dll, pmp_usb.dll, pmp_wifi.dll

    Under the Hood of TNFD’s Winamp Preferences & Title Configuration

    The text document below needs some updating, but it’s my programmer’s notes for Winamp config, if you care about what’s under the hood (needs updating).

    Fort Collins Tuesday Night [International] Folk Dancers
    Winamp Media Library Tag Formatting & Program Preferences
    ============================================================
    C:\Users\username\AppData\Roaming\Winamp\winamp.ini
    ============================================================
    Winamp Preferences | General Preferences | "Prevent the mouse wheel from altering the volume"
    
    Winamp Preferences | Media Library | "Save ratings to file for compatible formats (default: off)
    Winamp Preferences | Media Library | Local Library | Watch Folders
    	C:\FolkDance\MUSIC
    	C:\FolkDance\VIDEO
    	√ Rescan folders at startup
    
    Winamp Preferences | Skins | Modern Skins | Font Rendering | Font Mapper | uncheck "Keep bitmap font in strings that contain only 7-bit characters"
    
    Winamp Preferences | Plug-ins | General Purpose | Nullsoft Notification Area Control vn.x [gen_tray.dll]
    	√ Enable Nullsoft Notification Area Control
    		√ Previous, Play/Pause, Stop, Next Track
    
    ============================================================
    TITLE FORMATTING:
     How titles of dances are constructed from ID3 tags
    ============================================================
    
    Titles display format for player and playlist:
    
    Use this setting for updating tag info without performing a library scan:
    Winamp Preferences | Titles | Advanced Title Formatting | "Read metadata when file(s) are played or viewed in the playlist editor"
    
    Winamp Preferences | Titles | Advanced Title Formatting | "Use advanced title formatting when possible"
    
    Default value:
    titlefmt=[%artist% - ]$if2(%title%,$filepart(%filename%))
    
    Add dance name and country, if the tags are present:
    Format:  DANCE - COUNTRY: ARTIST - TITLE
    Tags:    COMPOSER - ALBUMARTIST: ARTIST - TITLE
    Unique Artist Example:
    	Ajde Jano - Serbia: Talitha MacKenzie - Ajde Jano (Come on, Jano) - Spiorad (Spirit)
    Unknown Artist w/ unique Title & Album Example: (sho, hide 
    	COMPOSER - ALBUMARTIST
    	Karagoúna - Greece - Karagoúna [classic] - [Evansville FD]
    
    If there is no composer AND albumartist tag, use the normal title formatting
    
    Winamp has a default option to automatically copy albumartist from artist, if albumartist is empty.
    
    (If ALBUMARTIST == ARTIST then "" else [%composer% - ][%albumartist%:  ])
    
    ******************************************
    pseudo logic:
    //need to update this logic
    If (ALBUMARTIST != "") {
    	If (ALBUMARTIST == ARTIST) {
    		If (TITLE != COMPOSER) "%title% - "
    		"%artist%[ - %album%]"
    	}
    	else { // has unique album artist
    		"%albumartist%: [%artist%]"
    		If (TITLE != COMPOSER)  " - %title%"
    		[ - %album%]
    	}
    	If (TITLE != "") {
    		"%title%"
    	}
    	else {
    		$filepart(%filename%)
    	}
    	"[ - %artist%][ - %album%]"
    }
    If (PUBLISHER begin "FCTNFD") {
    	" {" rightsubstring(%publisher%",7) "}"  
    
    ***********************************
    LAST KNOW WORKING:
    titlefmt=
    
    $puts(DEFAULT,$if2(%title%,$filepart(%filename%))[ - %artist%][ - %album%])$if(%composer%,$if(%albumartist%,%composer% - %albumartist%$if(%artist%,$IfStrEqual2(%albumartist%,%artist%,$IfStrEqual2(%title%,%composer%,[: %album%],: %title%[ - %album%]),: %artist%[ - %title%][ - %album%]),$IfStrEqual2(%title%,%composer%,[: %album%],: %title%[ - %album%])),$get(DEFAULT)),$get(DEFAULT))$IfStrEqual($left(%publisher%,6),FCTNFD, {$right(%publisher%,$sub($len(%publisher%),7))})
    
    
    Backup copy:
    [%composer% - ]$if(%albumartist%,$IfStrEqual2(%albumartist%,%artist%,$IfStrNotEqual(%title%,%composer%,%title% - )%artist%[ - %album%],%albumartist%: [%artist%]$IfStrNotEqual(%title%,%composer%, - %title%)[ - %album%]),$if2(%title%,$filepart(%filename%))[ - %artist%][ - %album%])$IfStrEqual($left(%publisher%,6),FCTNFD, {$right(%publisher%,$sub($len(%publisher%),7))})
    
    Function Reference:
    
    $if
    Parameters: (a, then, else)
    Returns: If a contains at least one valid, non-empty field, then is evaluated and returned, otherwise the else parameter is. Note that $if(A,A,B) is equivalent to $if2(A,B)
    
    $if2
    Parameters: (a, else)
    Returns: If a contains a valid, non-empty field, a is evaluated and returned, otherwise the else parameter is.
    
    $IfStrEqual and $IfStrNotEqual
    Parameters: (A, B, then)
    Returns: If A = B do then else nothing
    
    $IfStrEqual2 ($IfStrNotEqual2 function doesn't exist)
    Parameters: (A, B, then, else)
    Returns: If A = B do then else do else
    
    ============================================================
    Smart View in Media Library
    C:\Users\HungryHawk\AppData\Roaming\Winamp\Plugins\gen_ml.ini
    
    query9_name_utf8=Folk Dance
    query9_val_utf8=type = "0" AND publisher BEGINS "FCTNFD"
    query9_mode=327948
    query9_meta=metF5FD.vmd
    query9_image=101
    
    :: metF5FD.vmd is an ini file for view pane settings. 
    
    ============================================================
    Filename formatting:
    
    COUNTRY - DANCE [- original ARTIST of recording, if know][- original Album of recording, if know][- original TITLE of recording, if know]
    Serbia - Ajde Jano - Talitha MacKenzie - Ajde Jano (Come on, Jano)
    
    ============================================================
    Folk Dance mp3 Tag Format:
    
    ?	TITLE: If the song title is different than the dance name (and it is known), insert the dance name at the beginning and add parenthesis () around the original song title, e.g. "Dospatsko (Hopa!)"
    
    	ARTIST: (unchanged from original song tag, if known)
    
    	ALBUM: (unchanged from original song tag, if known)
    
    	GENRE: "Folk Dance/COUNTRY" e.g. "Folk Dance/Serbia"
    
    	COMMENT: Dance instruction hints to jog the memory
    
    ## Add standardized COUNTRY tag (but it's still called %albumartist% in the Media Library)
    	ALBUMARTIST: --> COUNTRY: Country of origin of dance, e.g. "Serbia"
    
    ## Add standardized DANCE_NAME tag (but it's still called %composer% in the Media Library)
    	COMPOSER: --> DANCE_NAME: Standardized name of dance (to allow grouping of multiple title options of the same dance) e.g. "Ajde Jano"
    
    ## Add identification tags to allow Smart View query to show only folk dances
    	PUBLISHER: "FCTNFD"[/Fav][/Person who introduced dance to FCTNFD], e.g. "FCTNFD/Fav/Diane M."
    
    		FCTNFD[/<Skill>]/<Special_Tags>][/<Teacher>]
    
    	Skill:
    		/EZ		Easy/Beginning
    		/Int	Intermediate
    		/Adv	Advanced
    
    	Generation:
    		/G1		1st Generation = No choreography. Dance not restricted to only one tune, e.g. Čoček, lesnoto.
    		/G2		2nd Generation = Choreographed to a specific tune using steps prevalent in the country of origin.
    		/G3		3rd Generation = Highly choreographed, performance-oriented, using old world and new world movements.
    
    
    	Special Tags:
    		/Fav	Favorite
    		/LD		Last Dance
    		/LQ	Low Quality recording (search for better)
    	
    	Teacher:
    		/DianaS
    		/DianeM
    		/MargaritaK
    		/Deryl
    		/KenM
    		/DavidP
    		/DeborahC
    
    FCTNFD/EZ/G1/LD
    
    ## Add category identifier to allow further search refinement.
    	CATEGORY: (aka: CONTENTGROUP/Grouping:) <Dance type and energy level>
    		Circle1 - Gentle
    		Circle2 - Moderate
    		Circle3 - Lively
    		Couple
    		Hambo
    		Line Dance
    		Reel
    		Waltz
    
    The RATING tag is editable in the Winamp  Media Library view or separate tag editing software.
    Set Winamp Preferences | Media Library | "Save ratings to file for compatible formats (default: off)
    External tag editing software "RATING WMP" (Windows Media Player)
    *	RATING: Difficulty (1-5, or 0 or empty for unrated) 1=Easy, 3=Intermediate, 5=Difficult. 2 and 4 not used.
    
    These tags don't matter:
    	TRACKNO, DISC, YEAR...
    
    ============================================================
    
    Documentation from the Media Library Smart View
    You can enable more powerful views using the custom query language.
    
    The basic format is:
    
    <field> <comparison> [value] [<logic operator> <field> <comparison> [value] [...]]
    
    Field names:
    	TYPE: 0 for audio files, 1 for video files
    	FILENAME: Full filename (including path (export: Filepath)
    	LENGTH: Length, in seconds (or hh:mm:ss)
    *	ARTIST: Artist
    *	ALBUM: Album
    *	ALBUMARTIST: Band/orchestra/accompaniment
    *	TITLE: Title
    	TRACKNO: Track number of file
    *	GENRE: Genre
    	YEAR: Year
    *	COMMENT: Comment
    *	COMPOSER: Composer
    	DISC: Disc number of a CD set
    	FILESIZE: File size, in kilobytes
    	FILETIME: Last known file date/time on disk
    	LASTUPD: Date/time of file imported to library or modified in library
    	LASTPLAY: Date/time of last play
    *	RATING: Rating value (1-5, or 0 or empty for unrated)
    	PLAYCOUNT: Number of plays
    *	PUBLISHER: Publisher or record label
    	DIRECTOR: Film director (for videos)
    	PRODUCER: Film or Record producer
    *	CATEGORY: Category
    	REPLAYGAIN_ALBUM_GAIN: ReplayGain Album Gain
    	REPLAYGAIN_TRACK_GAIN: ReplayGain Track Gain
    	BITRATE: Bitrate (in KBPS)
    	TRACKS: Total number of tracks on the disc
    	DISCS: Total number of discs in the set
    	ISPODCAST: 1 for a podcast episode, 0 otherwise
    	PODCASTCHANNEL: The name of the channel for a podcast
    	PODCASTPUBDATE: Date/time when the podcast was published
    	LOSSLESS: Shows lossless audio formats, e.g. lossless=1
    
    Comparison operators:
    	'=': String or integer equals value
    	'!=': String or integer does not equal value
    	'<': String or integer is less than value
    	'>': String or integer is greater than value
    	'<=': String or integer is less than or equal to value
    	'>=': String or integer is greater than or equal to value
    	HAS: String contains value
    	NOTHAS: String does not contain value
    	LIKE: String is similar to value ("the" and whitespace are ignored)
    	BEGINS: String begins with value
    	BEGINSLIKE: String begins like value
    	ENDS: String ends with value
    	ISEMPTY: (no comparison value required) TRUE if <field> is empty
    	ISNOTEMPTY: (no comparison value required) TRUE if <field> is not empty
    
    Values:
    	"strings with spaces" or strings_without_spaces
    	integers can be "32" or just 32
    	integers for LENGTH can be a plain integer (seconds), or mm:ss or hh:mm:ss
    	date/timestamps should be [datetime data], which can be either an absolute
    	  or relative time. i.e.: [3 weeks ago], [18:15],  [05/30/2003],
    	  [yesterday noon], [3 days ago 5 pm], [now], [5 mn before may 30th], etc.
    
    Logic operators:
    	&&, &, or AND: boolean AND two comparisons
    	||, |, or OR: boolean OR two comparisons
    	!, or NOT: prefix this to an expression for the boolean NOT of that expression
    
    Examples:
      all video files: type = 1
      audio by Air longer than 4 minutes: type = 0 & artist = "air" & length > 4:00
      all files on drive C: filename BEGINS C:
      high rated items that haven't been played lately: rating > 3 & lastplay < [1 week ago]
      newly added items that haven't been played yet: lastupd >= [yesterday] & playcount <= 0
    
    Note that you can also use this syntax in the search field of views. Simply prefix a '?' or 'query:' to your search string