[Windows Mobile Apps and Games] thx1200:
Localization

Spanish: http://xdaforums.com/showpost.php?p=8917098&postcount=53

Avian Play is ready to be localized to your native language! I need translators though. In the "Languages" folder under the application folder is where each language will be stored. Avian Play is structured such that all files in the language folder will be loaded for that language. This allows plugins to put their own language files in those folders, without interfering with Avian Play. All language strings are loaded into a single dictionary. To avoid collisions, plugin developers should prefix all their language strings (see shoutcast.ini for example). If a language string is not found in your language (maybe a new plugin or new features have new strings that are not yet translated) it will always default back to the English translation. So the "English" folder is the default language.

Skinning

Avian Play was designed so that the user can customize the layout of the application. Eventually, Avian Play will be fully widgetized (although maybe not on the WM platform). For the time being, the title information is on top, the control surface or list is in the middle, and the menus and tabs are at the bottom. Skin designers can, however, give Avian Play a brand new look by developing new images and editing a skin.ini file. To make a new skin, start in the Skins folder, and copy the contents of Default. Then edit the images and edit the colors in skin.ini to suit your taste. Please upload the results. Users can then extract the skin into your own custom named folder and select the skin from within Avian Play. Get creative! My skin isn't that hot. ;-)

AVPL

I know nobody really wants yet another playlist format, but I had to develop one because no current playlist format supports multiple URL sources for a single stream, despite that being extremely common. To support all of Avian Play's playlist functionality, you should use AVPL formatted files. You can create AVPL files from within the internal playlist editor, or by hand, as it is just a simple INI file. In the future, the AVPL will also support direct queries on the database to populate the list, but this is not supported yet. The intention is for this to be an open format, and I will post the schema later on so it can be used in other applications.

Database Schema

FileLibrary:

Column Name Type Length Nullable Unique Description
Key int No Yes Identity Column - Primary Key
AddedDate datetime No No Date/Time the file was added to the DB
Album nvarchar 100 No No Album Name
AlbumArt image No No Album Art (scaled to approx 480x480)
AlbumArtist nvarchar 100 Yes No Album Artist Name (for example, a DJ who made the compilation)
AlbumArtThumbnail image Yes No Thumbnail of Album Art (scaled to approx 64x64)
Artist nvarchar 100 No No Artist Name (artist who performed this track)
Bitrate int No No Bitrate of media file ** Currently unused **
Comments nvarchar 200 No No Extra comments in media file
Copyright nvarchar 100 No No Copyright string
FileModifyDate datetime No No Date/Time the file was last modified
FilePath nvarchar 260 No Yes Full path to media file
FileSize int No No Length of media file in bytes
Format nvarchar 25 No No Format of media file (MP3, OGG, etc.)
Genre nvarchar 50 No No Genre of media file
HasAlbumArt bit No No Does this file have album art included?
IsFavorite bit No No Is this file "favorited" by the user?
IsPodcast bit No No Is this file considered a podcast?
LastFoundDate datetime No No Date/Time the file was last found in the file system
LastPlayedDate datetime No No Date/Time the file was last played
LastPlayPosition int No No If position is tracked of the file, the last position (byte) where the file was paused
LengthSeconds int No No Length of file in seconds ** Currently unused **
MD5Hash varbinary 128 Yes No MD5 hash of the file, if MD5 hashes are being tracked
NotFound bit No No Was the file not found when the last library scan ocurred?
Rating tinyint No No User rating of the file
SkipForMetaPlaylist bit No No Should the file be skipped for embedded queries in AVPL playlists ** Currently unused **
Title nvarchar 100 No No Title of the media file (song name)
TrackNumber int No No The track number, with respect to album track order
Year int No No The year the track was released

PlaylistLibrary:

Column Name Type Length Nullable Unique Description
Key int No Yes Identity Column - Primary Key
ContainsFiles bit No No Does the playlist contain media files?
ContainsStreams bit No No Does the playlist contain streams?
FileModifyDate datetime No No Date/Time the file was last modified
FilePath nvarchar 260 No Yes Full path to playlist file
Format nvarchar 25 No No Format of playlist file (M3U, AVPL, etc.)
IsFavorite bit No No Is this file "favorited" by the user?
LastFoundDate datetime No No Date/Time the file was last found in the file system
MD5Hash binary 128 No No MD5 hash of the file, if MD5 hashes are being tracked
NotFound bit No No Was the file not found when the last library scan ocurred?
Title nvarchar 50 No No Title of the playlist file (derived from filename, but AVPL may support)

Architecture

Some people might be interested in the architecture of Avian Play. So I will describe my approach here. Avian Play consists of two processes: AvianPlay.exe and APEngine.exe. AvianPlay.exe is a managed .Net Framework app written in VB.Net. It controls the bulk of your Avian Play experience. Everything from the control surface, library, podcast management, etc., is handled here. AvianPlay.exe spawns a second process, APEngine.exe which is the audio engine. APEngine is a wrapper for the MAD MP3 audio engine. This is the same engine used in MortPlayer, GSPlayer, and many others. It is a super high quality playback engine ported to many platforms. I chose it due to how easy it is to work with and the quality of playback.

Why two processes? I tried to P/Invoke MAD from a DLL, but due to memory management issues that led to freeze-ups, I realized I needed a larger barrier between the managed and unmanaged code. It took me a while, but I finally realized that I could avoid memory management issues by using two processes and using the registry for string-based IPC. The registry is very high performance on Windows Mobile, due to it being used for state notification via SHNAPI. So, by settings up registry callbacks on both processes, the application and audio engine are able to communicate successfully, with no memory management or other issues. The biggest disadvantage to this approach is that WM has a limit of 32 processes, and Avian Play will use two. I'm sorry, but there was no way around this! Attached to this thread is a Visio I made to map out how the application is structured.