<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Index out of Bounds &#187; flac</title>
	<atom:link href="http://www.jonathanfritz.ca/tag/flac/feed" rel="self" type="application/rss+xml" />
	<link>http://www.jonathanfritz.ca</link>
	<description>the personal portfolio of Jonathan Fritz</description>
	<lastBuildDate>Mon, 12 Dec 2011 03:22:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Filling a Zune from Linux</title>
		<link>http://www.jonathanfritz.ca/software/filling-a-zune-from-linux</link>
		<comments>http://www.jonathanfritz.ca/software/filling-a-zune-from-linux#comments</comments>
		<pubDate>Sat, 02 Jan 2010 04:35:03 +0000</pubDate>
		<dc:creator>Jon</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Music]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[banshee]]></category>
		<category><![CDATA[fill]]></category>
		<category><![CDATA[flac]]></category>
		<category><![CDATA[kubuntu]]></category>
		<category><![CDATA[lame]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[mp3]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[sun virtual box]]></category>
		<category><![CDATA[sync]]></category>
		<category><![CDATA[virtual machine]]></category>
		<category><![CDATA[windows xp]]></category>
		<category><![CDATA[zune]]></category>

		<guid isPermaLink="false">http://www.jonathanfritz.ca/?p=187</guid>
		<description><![CDATA[Thinking that I was up for a challenge, I decided to spend the day figuring out how to put the music in my Banshee library onto a Microsoft Zune. Since my library contains a good number of FLAC files that I&#8217;ve ripped in from my CD collection, my solution called for a caching system that [...]]]></description>
			<content:encoded><![CDATA[<p>Thinking that I was up for a challenge, I decided to spend the day figuring out how to put the music in my Banshee library onto a Microsoft Zune. Since my library contains a good number of FLAC files that I&#8217;ve ripped in from my CD collection, my solution called for a caching system that converts the FLAC files to mp3s and stores them so that the playlist can be changed without having to re-convert the FLAC files into something that the Zune can play on every sync. My weapons of choice for the project were a Windows XP instance running inside of Sun Virtual Box, and 126 lines of perl script.</p>
<p>The Steps:</p>
<ol>
<li>Create a WinXP VM that has the Zune software installed and can see two shared folders on my Linux machine:
<ol>
<li>My normal Music folder, which contain my entire collection</li>
<li>The cache folders, which contain all of the FLAC files in my collection, but converted to mp3 so that the Zune can play them</li>
</ol>
</li>
<li>Open the Banshee database, located at ~/.config/banshee-1/banshee.db</li>
<li>Select all of the FLAC files in the playlist that we&#8217;d like to put on the Zune</li>
<li>For each, check if it has been converted and cached
<ol>
<li>If so, simply add the path to the cached copy of the track to an m3u file in the cache folder</li>
<li>If not, convert the track, and then add the path to the cached copy of the track to an m3u file in the cache folder</li>
</ol>
</li>
<li>Select all of the mp3 files in the playlist that we&#8217;d like to put on the Zune</li>
<li>Put those in a separate m3u file that is located in the Music folder.</li>
<li>Boot up the Zune software on the VM. It should autoscan it&#8217;s monitored folders, find the m3u playlists, and put them in its library</li>
<li>Sync the playlists with the Zune by dragging and dropping them to the device icon in the lower left corner of the screen</li>
</ol>
<p>As previously mentioned, steps 2 through 6 were accomplished by way of a perl script that I can run as often as I like:</p>
<blockquote><p>#/usr/local/bin/perl</p>
<p>#Requirements: libdbd-sqlite3-perl, flac, lame</p>
<p>#We need database support<br />
use DBI;</p>
<p>#Database path &#8211; change this to reflect your user environment<br />
my $dbpath = &#8220;dbi:SQLite:dbname=/home/jon/.config/banshee-1/banshee.db&#8221;;</p>
<p>#Playlist name &#8211; change this to reflect the playlist that you want to export<br />
my $plistname = &#8220;Favorites&#8221;;</p>
<p>#Cache Path &#8211; the path to the directory where you&#8217;ve been caching converted FLAC files<br />
my $cachepath = &#8220;/home/jon/Storage/mp3Cache/&#8221;;</p>
<p>#Music Path &#8211; the path to the folder where your music collection is actually stored<br />
my $musicpath = &#8220;/home/jon/Music/&#8221;;</p>
<p>#Connect to the database &#8211; no username/password<br />
my $dbh = DBI-&gt;connect($dbpath,&#8221;",&#8221;",{RaiseError =&gt; 1, AutoCommit =&gt; 0});</p>
<p>if(!$dbh) {<br />
print &#8220;Could not connect to database $dbpath&#8221;,&#8221;\n&#8221;,&#8221;Exiting&#8221;;<br />
exit;<br />
}</p>
<p>#Pull the list of FLAC files for conversion and caching<br />
my $flac = $dbh-&gt;selectall_arrayref(&#8220;SELECT sme.TrackID, ct.Title, car.Name AS &#8216;Artist&#8217;, ca.Title AS &#8216;Album&#8217;, ct.Uri, ct.Duration AS &#8216;Length&#8217; FROM corealbums AS ca, coreartists AS car, coresmartplaylistentries AS sme INNER JOIN coretracks AS ct ON sme.TrackID = ct.TrackID WHERE sme.SmartPlaylistID = (SELECT `SmartPlaylistID` FROM `coresmartplaylists` WHERE `Name` = &#8216;$plistname&#8217;) AND ca.AlbumID = ct.AlbumID AND car.ArtistID = ct.ArtistID AND ct.MimeType LIKE &#8216;%flac&#8217;&#8221;);</p>
<p>#open the m3u file to write the cached items to<br />
open my $m3u, &#8216;&gt;&#8217;, $cachepath.$plistname.&#8217;_cached.m3u&#8217; or die &#8220;Error trying to open cache m3u playlist for overwrite. Do you have write permissions in $cachepath ?&#8221;;<br />
print $m3u &#8220;#EXTM3U\r\n\r\n&#8221;;    #note windows \r\n here</p>
<p>#add /music to $cachepath so that files are in a subdirectory, away from the m3u file<br />
$cachepath = $cachepath.&#8221;music/&#8221;;<br />
if( ! -e $cachepath ) {<br />
`mkdir &#8220;$cachepath&#8221;`;<br />
}</p>
<p>#loop through the files and check if they need to be cached<br />
foreach my $i (@$flac) {<br />
my ($trackid, $title, $artist, $album, $uri, $length) = @$i;</p>
<p>#correct the uri by removing the file:// prefix and reverting the uri escaping<br />
$uri = substr $uri, 7;<br />
$uri =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;</p>
<p>#fix time into seconds<br />
$length = int($length/1000);</p>
<p>#check if the flac file has already been converted and cached at cachepath<br />
#if not, convert it and put it at cachepath.<br />
my $path = $cachepath . $artist . &#8216;/&#8217; . $album . &#8216;/&#8217; . $title . &#8216;.mp3&#8242;;<br />
if( ! -e $path ) {<br />
#file dne, convert it<br />
print &#8220;\nTrack: $title by $artist has not yet been cached, converting&#8230;&#8221;,&#8221;\n&#8221;;</p>
<p>#make sure that the file actually exists before attempting to convert it<br />
if( ! -e $uri ) {<br />
print &#8220;WARNING: Track $title by $artist does not exist at $uri&#8221;,&#8221;\n&#8221;;<br />
} else {</p>
<p>#ensure that cache album/artist directories exist<br />
my $partpath = $cachepath.$artist;<br />
if( ! -d $partpath ) {<br />
`mkdir &#8220;$partpath&#8221;`;<br />
}<br />
$partpath = $partpath.&#8217;/&#8217;.$album;<br />
if( ! -d $partpath ) {<br />
`mkdir &#8220;$partpath&#8221;`;l<br />
}</p>
<p>#do the conversion &#8211; we&#8217;re chaining flac and lame here, reading in the flac file from $uri, and putting the resulting mp3 at $path<br />
`flac -cd &#8220;$uri&#8221; | lame -h &#8211; &#8220;$path&#8221;`;<br />
}<br />
}</p>
<p>#add the track to the m3u file &#8211; note that these entries are relative to the location of the m3u file in the root of $cachepath<br />
#the paths use a backslash and a \r\n newline so that they work correctly on windows<br />
print $m3u &#8220;#EXTINF:$length,$artist &#8211; $title\r\n&#8221;;<br />
print $m3u &#8216;\\music\\&#8217;.$artist.&#8217;\\&#8217;.$album.&#8217;\\&#8217;.$title.&#8217;.mp3&#8242;,&#8221;\r\n\r\n&#8221;;<br />
}</p>
<p>#close the m3u file in the cachepath directory<br />
close $m3u;</p>
<p>#TODO: scan the m3u file and delete any files that aren&#8217;t in it from the cache directory</p>
<p>#Pull the list of MP3 files and dump them into an m3u file<br />
my $flac = $dbh-&gt;selectall_arrayref(&#8220;SELECT sme.TrackID, ct.Title, car.Name AS &#8216;Artist&#8217;, ca.Title AS &#8216;Album&#8217;, ct.Uri, ct.Duration AS &#8216;Length&#8217; FROM corealbums AS ca, coreartists AS car, coresmartplaylistentries AS sme INNER JOIN coretracks AS ct ON sme.TrackID = ct.TrackID WHERE sme.SmartPlaylistID = (SELECT `SmartPlaylistID` FROM `coresmartplaylists` WHERE `Name` = &#8216;$plistname&#8217;) AND ca.AlbumID = ct.AlbumID AND car.ArtistID = ct.ArtistID AND ct.MimeType LIKE &#8216;%mp3&#8242;&#8221;);</p>
<p>#open the m3u file to write the cached items to<br />
open my $m3u, &#8216;&gt;&#8217;, $musicpath.$plistname.&#8217;.m3u&#8217; or die &#8220;Error trying to open music folder m3u playlist for overwrite. Do you have write permissions in $musicpath ?&#8221;;<br />
print $m3u &#8220;#EXTM3U\r\n\r\n&#8221;;    #note windows \r\n here</p>
<p>#loop through the files and check if they need to be cached<br />
foreach my $i (@$flac) {<br />
my ($trackid, $title, $artist, $album, $uri, $length) = @$i;</p>
<p>#correct the uri to become a windows file path<br />
$uri = substr $uri, 7;            #remove file:// prefix<br />
$uri =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;    #correct uri encoding<br />
$uri =~ s/$musicpath//g;            #remove musicpath prefix<br />
$uri =~ s/\//\\/g;                #change forward slashes to backslashes<br />
$uri = &#8216;\\&#8217;.$uri;                #add the leading backslash</p>
<p>#fix time into seconds<br />
$length = int($length/1000);</p>
<p>#add the track to the m3u file &#8211; note that these entries are relative to the location of the m3u file in the root of $cachepath<br />
#the paths use a backslash and a \r\n newline so that they work correctly on windows<br />
print $m3u &#8220;#EXTINF:$length,$artist &#8211; $title\r\n&#8221;;<br />
print $m3u $uri,&#8221;\r\n\r\n&#8221;;<br />
}</p>
<p>#close the m3u file and the database connection<br />
close $m3u;<br />
$dbh-&gt;disconnect;</p></blockquote>
<p>Sorry for the horrible formatting.</p>
<p>The only snag that I hit during the entire process was really my fault &#8211; I have a tendency to overcomplicate things, and did so on this project by initially writing the script to output a *.zpl file instead of a *.m3u file. That didn&#8217;t work at all, and I ended up simplifying the script greatly by just outputting an *.m3u file and hoping for the best.</p>
<p>On the off chance that the Zune jukebox software refuses to properly update its playlists after you change the *.m3u files, first try deleting them from the application, and then restarting it. If that doesn&#8217;t work, you can write a Windows batch script with code similar to the following:</p>
<blockquote><p>del /q &#8220;C:\Documents and Settings\Jonathan\My Documents\My Music\Zune\Playlists\*&#8221;<br />
xcopy &#8220;\\Vboxsvr\mp3cache\Favorites_cached.m3u&#8221; &#8220;C:\Documents and Settings\Jonathan\My Documents\My Music\Zune\Playlists&#8221;<br />
xcopy &#8220;\\Vboxsvr\music\Favorites.m3u&#8221; &#8220;C:\Documents and Settings\Jonathan\My Documents\My Music\Zune\Playlists&#8221;</p></blockquote>
<p>This script deletes all files from the Zune playlists directory, and then copies each of the *.m3u files that we created with the above perl script directly into the Zune playlists directory. This should force the application to get it&#8217;s act together.</p>
<p>Overall, I&#8217;m happy with this patchwork job. It allows me to use the Zune on Linux, which is great because the Zune really is a beautiful piece of hardware. Now if only the libmtp guys could get it working natively, without a WinXP VM&#8230;</p>
<p>This piece originally appeared at <a href="http://thelinuxexperiment.com/guinea-pigs/jon-f/filling-a-zune-from-linux/" target="_blank">The Linux Experiment</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonathanfritz.ca/software/filling-a-zune-from-linux/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Reinventing the Wheel: A Better Media Player</title>
		<link>http://www.jonathanfritz.ca/software/reinventing-the-wheel-a-better-media-player</link>
		<comments>http://www.jonathanfritz.ca/software/reinventing-the-wheel-a-better-media-player#comments</comments>
		<pubDate>Sun, 22 Nov 2009 17:42:22 +0000</pubDate>
		<dc:creator>Jon</dc:creator>
				<category><![CDATA[Music]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[blackberry]]></category>
		<category><![CDATA[cross platform]]></category>
		<category><![CDATA[flac]]></category>
		<category><![CDATA[itunes]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[juce]]></category>
		<category><![CDATA[last.fm]]></category>
		<category><![CDATA[m3u]]></category>
		<category><![CDATA[media monkey]]></category>
		<category><![CDATA[media player]]></category>
		<category><![CDATA[meta-data]]></category>
		<category><![CDATA[mp3]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[pls]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[project]]></category>
		<category><![CDATA[rating]]></category>
		<category><![CDATA[sfml]]></category>
		<category><![CDATA[smart playlist]]></category>
		<category><![CDATA[Songbird]]></category>
		<category><![CDATA[streaming]]></category>
		<category><![CDATA[subsonic]]></category>
		<category><![CDATA[sync]]></category>
		<category><![CDATA[visual studio]]></category>
		<category><![CDATA[windows media player]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://www.jonathanfritz.ca/?p=157</guid>
		<description><![CDATA[As I&#8217;ve posted in the past, I am a picky media player user. I&#8217;ve tried most every free player under the sun, along with some not so free solutions and have yet to be entirely satisfied with any of the available products. To that end, I&#8217;ve started to think about the possibility of writing my [...]]]></description>
			<content:encoded><![CDATA[<p>As I&#8217;ve posted in the past, I am a picky media player user. I&#8217;ve tried most every free player under the sun, along with some not so free solutions and have yet to be entirely satisfied with any of the available products. To that end, I&#8217;ve started to think about the possibility of writing my own media player. The following are some of the considerations that I&#8217;ve been mulling over:</p>
<p><strong>Base Requirements:</strong></p>
<ul>
<li>Playback of both mp3 and flac files. Support for other formats could be added as required by me or other users, possibly with us of some sort of plugin engine.</li>
<li>Some kind of a rating system, preferably with a high level of granularity. I&#8217;m not married to the standard 5-stars idea, and may explore alternative ideas, including tagging.</li>
<li>Truly smart playlists that allow for the standard global AND/OR rules, as well as more advanced expressions that support brackets and branching logic.</li>
<li>Smart importing from existing iTunes, Songbird, Media Monkey, and Windows Media Player libraries, various playlist formats, and other types of media collections.</li>
</ul>
<p><strong>Feature Wish List:</strong></p>
<ul>
<li><em>Blackberry Sync</em>: When not at home, I listen to music from a flash card on my Blackberry Curve. The device can be filled with media by simply dumping it all on the media card, which appears as a removable drive. As previously mentioned, I listen to a mix of mp3 files and lossless flac files. When dumping these files to the Blackberry, I would like to see one thread dedicated to converting the flac files to mp3s, while another thread actually fills the device, resulting in a sync process that is not significantly slowed by media conversions. Additionally, since I have hard drive space to spare, I would like to cache some or all of the resulting mp3 files so that they don&#8217;t have to be converted again on the next sync. I would also like to see the ability to import files from the Blackberry to the library so that I could pick up media on the go and bring it home with me.</li>
<li><em>Library Export/Backup</em>: With a library of 10K+ tagged and rated songs, losing the library of meta data about my music would be a traumatic experience indeed. To solve my paranoia over losing this data, I would like to implement the export of single playlists and entire libraries to all of the major playlist formats, as well as to a structured XML document, similar to the one that iTunes maintains. Some kind of automated backup feature like the one that iTunes has would also be nice.</li>
<li><em>Online Integration:</em> I currently report all of my song plays to last.fm, which is an excellent resource for discovering new music. I would like my media player to link in with last.fm and other online resources, but am also open to developing my own online resource that lets users to easily compare and organize their collections, correct their meta data, and actively discover new music that other users have rated.</li>
<li><em>Library Sharing/Streaming:</em> We run a large network with lots of computers, and I&#8217;d like the ability to listen to my music from anywhere in the house. I really like the work that <a href="http://subsonic.sourceforge.net/" target="_blank">Subsonic</a> has done in this area, and hope to implement some or all of it&#8217;s features, while at the same time linking it into my database so that I can see my playlists and edit my meta data from anywhere in the house, and indeed, from anywhere in the world.</li>
<li><em>Cross-Platform and Open-Sourced:</em> Given all of my recent experience with Debian Linux, I&#8217;d like to see my media platform running on both Windows and Linux. This one might take me awhile to accomplish, but is definitely a goal of mine, given that I am now a confirmed Linux user who still keeps a couple of Windows platforms lying around.</li>
</ul>
<p><strong>Implementation:</strong></p>
<p>Of course, with all of these goals in mind, the next step is to consider which platform I&#8217;d like to build on. This basically comes down to a number of choices, some cross-platform, some not:</p>
<ul>
<li><em>Visual Studio .NET:</em> My development IDE of choice, Visual Studio provides extremely quick GUI creation and a great number of useful libraries that cut out a lot of the nitty gritty time consuming base code necessary for a project as large as a media player. Additionally, the Windows Media Player control allows for drop-in playback of media, and I have a ton of example code lying around that implements most of the features listed above. Unfortunately, while .NET 2.0 is supported on Linux under the Mono platform, I don&#8217;t know how far that support goes in terms of media management and playback.</li>
<li> <em><a href="http://www.sfml-dev.org/index.php" target="_blank">SFML</a>:</em> The Simple Fast Media Library is available as libraries that are pre-compiled to run on Windows, Linux, and Mac, with support for Visual Studio, C/C++, Python, and Ruby. It includes packages for windowing, graphics, networking, and most importantly, audio capture and playback. This is a definite contender as it is open source, meaning that I could build the libraries directly into my code, and simply recompile for different platforms. Of course, the downside is that I&#8217;ll have to code in C++, and without any kind of graphical interface builder.</li>
<li><em><a href="http://www.rawmaterialsoftware.com/juce.php" target="_blank">Juce</a>:</em> Jules Utility Class Extensions is like a more featured version of SFML that provides packages for just about every conceivable task, including some serious audio libraries that support all kinds of playback, effects, and hardware accelerated features. In addition, it does audio CD reading and writing out of the box on Mac and PC platforms. If I were to strike out from Visual Studio, this would probably be my library of choice, as it can do nearly everything that VS can do, but is fully open sourced and supported on just about every available platform.</li>
<li><em>Java</em>: I have no idea how realistic this idea is. I do know that in the past, I&#8217;ve created Java apps that can play both wav and mp3 files, and stream those files over a network connection. That said, as much as I enjoy coding in Java, it is widely regarded as being slow and clunky &#8211; not exactly traits that I&#8217;d like associated with a media player that will be running all day. On the other hand, Java is not C/C++ (a huge bonus as far as I&#8217;m concerned), is fully object oriented, has decent audio support, and makes networking extremely easy. That said, programming GUI&#8217;s of any kind of complexity in Java is not a task to be taken on lightly.</li>
</ul>
<p>Well, that about sums it up. This project is definitely something that I intend to undertake in the coming months, and until then, I&#8217;ll keep thinking about my requirements and what library I&#8217;d like to use to implement it. If anybody else has experience with some useful audio libraries that they&#8217;d like to share, please do so in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jonathanfritz.ca/software/reinventing-the-wheel-a-better-media-player/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

