Hacks

xrayspx's picture

Playlists

Music: 

Dr. Dre - Nuthin' But a G' Thang

I had a request to share some playlist management stuff so I thought I should explain myself. I've got a significant CD collection, and a somewhat-significant collection of TV shows. This is fine on its own, but lots of media is pretty worthless without well curated playlists that you really don't have to think about. So I built Spotify, MTV and Syndicated TV.

* NOTE: If you have a better way to do any of this let me know and I'll fix it. I particularly have the sense, which is not backed up by my testing, that "sort -R" isn't great.

Music's easier so we'll start there. I use Strawberry to manage my music. This was all running under Clementine and aside from some DB schema changes, the scripts are portable between them.

Until relatively recently I was never a big fan of "star" or "heart" ratings, but Clementine/Strawberry will store this metadata in the MP3 itself so I should be able to quickly recover if I lose my music database. In the app I have a few Smart Playlists like 3-Stars, 3 Stars + (This is 3, 4 and 5 star tracks), 4-Stars, 4-Star + and 5 Stars. To use 4 Star as an example, the rules look like this:

Match every search term (AND)
Rating - Greater than - 3.5 Stars
Rathing - Less than - 5 Stars
Ratin - Not Equals - 5 Stars
Length - Greater Than - 8 Seconds

That results in a playlist of 8423 songs with ratings between 4 and 4.99 stars. There was a bug in Clementine which I got fixed where ratings could exceed 5, so I'm a little careful to deal with weirdo cases, but it's pretty simple. I also have a bunch of manually selected playlists, so like an '80s one, '90s, and "Barn Radio". Barn Radio is our catch-all for the ubiquitous music we heard from the late '70s through late '80s. For Natalie that was largely with her dad in the dairy barn, for me it was the music of my 2 hours on the bus every day.

Anyway, I have all these .m3us stored in a folder along with my MP3s called "playlists_base". These are used by a nightly playlist generator that pulls ~200 tracks and makes daily playlists running 8 or 10 hours each. The reason for this is that streaming software such as Airsonic-Advanced kind of chokes on massive playlists. It could be Airsonic itself, it could be populating the mobile client, I don't really know or care, other than to say it works great with list sizes under about 1000 tracks or so, so I keep them shorter.

The x-Star playlists are all built from the database like this 4 Star + playlist below. You can see it do a couple of different Star Rating DB queries, dump out the tracks to $playlist_tmp.m3u, then cat that file and do a random sort to generate the final version. It's pretty easy to adjust the mix based on ratings, so if I wanted to weight high-rated tracks I could do that by adjusting how many tracks of the 200 are returned by each search:


#!/bin/bash

rm /Volumes/Filestore/CDs/playlists/4\ Stars\ +.m3u

i=1

while [ $i -le 100 ]
do

### Switching from Clementine to Strawberry ###
#       file=$(sqlite3 /var/tmp/clementine.db "select filename from songs where rating > "0.9" order by random() limit 1;" | awk -F "file://" '{print $2}')
        file=$(sqlite3 /var/tmp/strawberry.db "select url from songs where rating > "0.9" order by random() limit 1;" | awk -F "file://" '{print $2}')

        ### Clementine data encodes special characters and accent marks and stuff so I'm using
        ### Joel Parker Henderson's urldecode.sh to undo that: https://gist.github.com/cdown/1163649

        data=$(/home/xrayspx/bin/urldecode.sh "$file")
        if [ -f "$data" ]
        then
                ### Have to escape leading brackets because grep treated it as a range and would allow duplicates ###
                ### Can't do that in "data" because \[ isn't in the filename so they'll fail ###

                escaped=$(echo "$data" | sed 's/\[/\\[/g')
                #echo "$escaped"

                ### Avoid duplicates
                match=$(grep -i "$escaped" /var/tmp/4-star-tmp.m3u)
                if [ -z "$match" ]
                then
                        echo "$data" >> /var/tmp/4-star-tmp.m3u
                        ((i++))
                fi
        fi
done

i=1

while [ $i -le 100 ]
do
### Switching from Clementine to Strawberry ###
#        file=$(sqlite3 /var/tmp/clementine.db "select filename from songs where rating >= "0.8" and rating          file=$(sqlite3 /var/tmp/strawberry.db "select url from songs where rating >= "0.8" and rating 

        ### Clementine data encodes special characters and accent marks and stuff so I'm using
        ### Joel Parker Henderson's urldecode.sh to undo that: https://gist.github.com/cdown/1163649

        data=$(/home/xrayspx/bin/urldecode.sh "$file")
        if [ -f "$data" ]
        then
                ### Have to escape leading brackets because grep treated it as a range and would allow duplicates ###
                ### Can't do that in "data" because \[ isn't in the filename so they'll fail ###

                escaped=$(echo "$data" | sed 's/\[/\\[/g')
                #echo "$escaped"

                ### Avoid duplicates
                match=$(grep -i "$escaped" /var/tmp/4-star-tmp.m3u)
                if [ -z "$match" ]
                then
                        echo "$data" >> /var/tmp/4-star-tmp.m3u
                        ((i++))
                fi
        fi
done

cat /var/tmp/4-star-tmp.m3u | sort -R > /Volumes/Filestore/CDs/playlists/4\ Stars\ +.m3u

rm /var/tmp/4-star-tmp.m3u

Those Star Rating lists are called at the beginning of my overall static playlist script, but the Barn playlist and other manually selected ones are built from the "playlists_base" directory. I basically just edit those .m3us in place with Strawberry as we add CDs. They just the files, do a random sort and pull the top 200. This will use any .m3u in .../playlists_base/ and make a daily file from it:


#!/bin/bash

#scp xrayspx@pro:~/.config/Clementine/clementine.db /var/tmp/

### Switching between Clementine and Strawberry ###
#cp /Volumes/Filestore/CDs/playlists_base/clementine.db /var/tmp/

cp /Volumes/Filestore/CDs/playlists_base/strawberry.db /var/tmp/

/home/xrayspx/bin/3-star-playlist.sh
/home/xrayspx/bin/4-star-playlist.sh
/home/xrayspx/bin/5-star-playlist.sh
/home/xrayspx/bin/get-the-led-out.sh

ls /Volumes/Filestore/CDs/playlists_base/*.m3u > /Volumes/Filestore/CDs/playlists_base/m3us.txt

while IFS= read -r file
do

        filename=$(echo $file | awk -F "/Volumes/Filestore/CDs/playlists_base/" '{print $2}')

        echo Filename: $file

        rm "$file.full"
        rm "$file.scratch"
        rm "/Volumes/Filestore/CDs/playlists/$filename"

        ###Testing a change since Strawberry creates playlists without EXTINF lines ###
#        array=`grep EXTINF "$file" | sort | uniq`
        array=`grep -v EXTINF "$file" | sort | uniq`

        printf '%s\n' "${array[@]}" | sort -R > "$file.full"
        head -n 200 "$file.full" > "/Volumes/Filestore/CDs/playlists_base/$filename.scratch"

        n=0
        while IFS= read -r extinfo
        do
#       echo $extinfo
                term=`echo $extinfo` # | cut -d "," -f 2-`
#       echo $term

 ###Testing a change since Strawberry creates playlists without EXTINF lines ###
 # grep -A 1 -m 1 "$term" "$file" >> "/Volumes/Filestore/CDs/playlists/$filename"

        grep -m 1 "$term" "$file" >> "/Volumes/Filestore/CDs/playlists/$filename"
        done 

        rm "$file.full"
        rm "$file.scratch"

done 

rm /var/tmp/clementine.db
rm /var/tmp/strawberry.db

For TV shows it's a bit more complicated. I've got individual scripts for things like Sitcoms, Saturday Morning Cartoons, Buddy-Cop shows, Nick-at-Nite, etc. Each script uses a text file which just lists the relative path to the directories I want to randomize. I just read in that text file then scan each directory and build an array that again I sort -R and dump in an m3u. You'll see a couple of my conventions here, like the "dvd_extras" folders I use for any extras that I want to keep but don't want to have show up in the mix, as well as a bunch of other crap I grep out.

This script references "./.sitcoms.txt", which looks like this:


./Archer (2009)
./30 Rock
./Absolutely Fabulous
./Alexei Sayle's Stuff


#! /bin/bash

array=$(
while read line
do
        find "$line" -type f;
done < .sitcoms.txt
)

printf '%s\n' "${array[@]}" | sort -R | grep -v -w "batch" | grep -v dvd_extras | grep -v "./$" | grep -v "\.m3u" | grep -v -i ds_store |
 grep -v "\.nzb" | grep -v "\.nfo" | grep -v "\.sub" | grep -v "\.sfv" | grep -v "\.srt" | grep -v -i "\.ifo" | grep -v -i "\.idx" |
 sed 's/^/..\//' > ./1\ -\ Playlists/Sitcoms.m3u

This dumps out to a folder called "1 - Playlists" inside my TV Shows directory, just so it shows up first. There's a folder in there for Blocks as well, in which I create blocks of 10 random episodes of a bunch of shows. This is built to replicate like TBS/TNT/USA in the evening where you just sit and watch a block of whatever is on. In practice I do this wrong and tend to be too picky about these and just watch blocks until I've worked my way through a whole series and wind up tired of it forever.

One thing I do for things like Nick at Nite and overall Sitcom lists and stuff is that I mix in commercials. I don't do this very well though, I just treat my directory of commercials like any other TV show. I'd rather do "pull a TV show, toss in two commercials, repeat", but I'm not there yet I guess.

The last type of lists I build are for music videos. I break this into a few different playlists, one overall catchall that pulls in all videos, a playlist for MTV 120 Minutes, and one for "Arcade / Pizzeria" music. Basically the ubiquitous music you'd hear in a pizza shop or arcade in the '80s or '90s. I do the same commercial thing here as well.

Example:


#! /bin/bash

array=`find ../120\ Minutes -type f;
find ../../../Commercials -type f`

printf '%s\n' "${array[@]}" | sort -R | grep -v dvd_extras | grep -v "./$" | grep -v "ERRORS$" | grep -v "\.sh" | grep -v "\.m3u" |
 grep -v -i ds_store | grep -v ".nzb" | grep -v ".srt" > 120\ Minutes.m3u

xrayspx's picture

What Have I Done: Atari Edition

Music: 

The Ramones - Somebody Put Something in my Drink

Yesterday we went out and collected what was left of the Atari collection we bought, so today we set up pretty much everything in one place. This is why we need to build furniture:

This collection comes to us from a man I was in an Atari computer club with back in the '80s, when I was an Overly-Enthusiastic 'Tween pirate. So while I don't have my personal childhood 8-bit and ST computers anymore, this is actually stuff I remember. I specifically remember the ICD enclosure with the Apple sticker stuck on it for example. The ST actually was lovingly packed in a suitcase with custom foam for the machine, Spectre GCR and external floppy. However when we got it home the foam utterly disintegrated all over our dining room, so that's all being replaced just in case we ever take it anywhere again, but I can definitely remember that case being lugged into meetups back in the day as well.

There are also lots of things I've never seen in person before, like the Atari-branded tablet, light pen or the Indus GT drive. Apparently you can retire quite comfortably off the sale of an Indus GT, at least according to eBay weirdos. I don't know, I just remember they looked real cool in magazine ads.

It should be noted that all those boxes of disks, and the other boxes of stuff not pictured, contain nearly all fully licensed commercial software and manuals. That's why I haven't posted any shots of ST demos and cracked game intros and stuff. There aren't any :-) Everything is legal and has manuals, which is great. One of the big issues I had when I was a kid is that yeah, I had tons of games, but no idea how half of them worked, not a problem for Jumpman, but big problem for SCRAMM or Silent Service or MULE, at least I never knew how to play them. While this definitely wasn't a "Gamers" computer, it's really going to be interesting to stick Natalie in front of Calamus or PageStream and show her the state of the art for 1988 design software. Spectrum 512 has already left us both stumped. I've got some re-learning to do for sure.

Natalie was super excited playing with the drawing tablet and I guess I might have to get a CRT just so we can try the light pen out too. We're also looking forward to projects with the AtariLab temperature and light modules, which just have a really interesting history.

My loose plan is to get a GoTek so as not to have to deal with physical disks as much, and a SCSI to SD that can live in that ICD enclosure (along with probably 15 Raspberry Pis!) so that everything is gainfully employed once its new home is ready. To use the Spectre GCR I'll need high resolution mode, which should be achievable with a VGA converter. Color requires a monitor to support a 15Khz refresh rate (or use of an expensive scan doubler), but monochrome should work just fine. I'm waiting eagerly for CheckMate1500Plus.com to start selling their "ultimate" retro computing monitors to actually solve that problem once and for all.

Once we get the new storage built we'll have much more room to get in and start opening stuff up on the bench and start some repairs.


Inventory





On the 8-bit side, inventory-wise, we've got:
130XE
XE Game System
XEGS Light Gun
1010 Tape Drive
1050 Disk Drive
Indus GT Disk Drive
CX80 Trackball
CX77 Touch Tablet
CX75 Light Pen
AtariLab Light Module
AtariLab Temperature Module

Of that, the XEGS seems to be totally fine, while the 130XE tests bad on a bunch of its RAM, so that will be a project. I don't know whether I'll just replace the 64x1 DIPs that are in there now or go for some over-the-top modern upgrade that might be easier to source. It's also likely got a bad keyboard membrane, but I have a spare to replace that on hand.











On the ST side:
Atari 1040 ST
SC1224 Color monitor
SF-314 Floppy Drive
ICD FA-ST 2x SCSI disk enclosure
Spectre GCR Mac Emulator
There's also an internal PC emulator mod that I've not tested yet
Gravis analog joystick

The external floppy at the very least has a bad power switch, and doesn't seem to do anything. There are a total of 4 SCSI drives spread between two enclosures, but none of them spun up immediately either, so some work to do there. The Atari mouse doesn't work (yet!), so we got a DE9 to USB adapter so we can use modern mice. However that Gravis stick will work as a mouse, and was crucial to getting the machine up and tested.

There's one broken key slider stem that can be seen in the picture, we have the key and got a whole bag of replacement sliders so that's handled.

The external mouse & joystick switch box kind of resolves the problem of those ports being buried under the machine.

xrayspx's picture

Fall Project Time

Music: 

REM - The Wrong Child

I recently started bringing in a truly special collection of Atari hardware. I was expecting to pick up an ST and some software, and when we arrived found not only that that ST had loads of peripherals and neat stuff to test out, but lots of 8-bit hardware and an XE Game System as well. I actually had to do this in trips just to make sure I had somewhere rational to store all of it while we inventory it and do any repairs and cleanup needed before we start trying to see what other more serious collectors might want to take in. But honestly how could I pass this up an XEGS for this room?

We really only need to make a stand for the 2600 that will let you see and use both systems. All the power and A/V stuff routes to that shelf so we can just fire them up in place and start playing.

But what this really spawned is a project to start building furniture in the office. Natalie has this habit of doing projects while I'm out of town on business as a surprise for when I get back, so in 2015, before the full house renovation, while I was on a trip to a datacenter for a week Natalie built this bookshelf. At the same time she uncovered the awesome tile floor in the office which had been hidden under the crappiest industrial carpeting for all these years.

However we're reached a tipping point with that thing. The shelves are 12" deep which is great for a bookshelf but not so great for cramming a bunch of computer equipment into. You can see it's way too narrow to comfortably fit that scanner for instance.

The goal is to build something deeper which can comfortably store an ST, Mac Classic, and some other small home computers as well as just bulk storage of Crap in My Office. At the moment all my network hardware, switches, firewalls and storage are buried under my main desk. Tidy and out of the way, but a hassle to get to if I need to plug new stuff in or actually work on anything. I don't want to be 70 years old crawling around on the floor to add a network drop, so we're going to get that stuff out of there. We also need just "Bulk Computer Storage" for larger systems like a Mac Pro, KayPro II. My desk and repair bench has been getting a little crowded lately, so I'm hoping a good amount of that stuff can move as well. Some of the details of what we're doing are going to be a surprise, but it'll be cool, I swear. I've told Natalie my only real goal is to have somewhere to put my laptop bag. All this stacking shit is making me itchy :-)

The ST is currently taking up exactly the surface area of a small storage cabinet, which is a little cramped for purposes of troubleshooting to say the least, though a couple of toys have trickled in since I got it, like an Atari 9-pin to USB adapter for a modern mouse and a supply of replacement key switch sliders/stems.

We'll be building more ST projects to share Real Soon Now, promise. Once we get our bearings from all the work office moves and re-shuffling these shelves. My word is as good as a Tremiel promising us all Falcons By Christmas!

So I wanted to save a quick "Before" of that space before we start tearing into the project:



That Panasonic boombox works and sounds AWESOME, but barely even picks up the FM transmitter from 10 feet away because the boombox's day-job is to hide multiple WiFi routers, a network switch and a 10 port power strip, so there's like 8 WiFi antennas right up against the tuner, not ideal. Be nice to clear that up.

xrayspx's picture

Kodi Machine Screensaver Notes

Music: 

Veruca Salt - Born Entertainer

I've just spent too long messing with a small PC to replace my Raspberry Pi Kodi machine. Problem was that the system would blank the screen after 10 minutes and there's too much stuff to test, and each test takes 10 minutes. Make a change, reboot, wait 10 minutes, make another change, and so on.

The problem was the Xorg default screen blanking, and it was fixed by creating /etc/X11/xorg.conf, with only the following config in it:

Section "ServerFlags"
Option "IgnoreABI" "True"
Option "BlankTime" "0"
Option "StandbyTime" "0"
Option "SuspendTime" "0"
Option "OffTime" "0"
EndSection

I had previously tried a bunch of stuff with setterm and enabling rc.local to run from Systemd, all to no avail, so I wanted to document this one for the next time.

xrayspx's picture

Search for Certificates on Windows Systems

Music: 

Nine Inch Nails - Broken

Here are a lot of words about what's essentially a one-line CMD + Powershell script...

I've recently run into a situation where a trusted root certificate authority certificate was missing from several Windows systems in multiple locations and domains. This was causing an issue with automation which reached out to a site which had a certificate signed by that CA. I can see a good use case for this if an organization has their own CA and needs to verify that all endpoints have that CA certificate in their trust store for example.

xrayspx's picture

Mac Classic Pt. 2 - This is Fine

Music: 

Pailhead - I Will Refuse

Note: I say "We" a lot. Natalie has been doing at least as much of this work as me. She has a whole method that she likes for the tantalum caps so she pretty much installed all of those. She even discharged the CRT. We learned later that the Classic seems to bleed the CRT automatically which is nice. I'm still sticking a screwdriver back there every time though just to make sure.

Good and bad news on the Mac Classic front.

If you read in part one, we over-paid a princely sum for a Mac which "Works as intended", but which should really have been "For parts or repair" for 1/3 what we paid.

So I'm personally beholden to make this fucker run regardless of personal cost in blood or treasure at this point.

"Rookies do very tidy job and rightfully feel pleased"

We recapped the motherboard on the Mac Classic. We got a heat gun, generous with the tape all around to make sure we didn't mess up any other components, and quickly and easily got the old parts off, we cleaned the pads up with solder wick, tinned them with new solder and put in the replacement tantalum caps, applying a bit of flux and cleaning regularly along the way. No damaged pads, everything went extremely smoothly regardless of which of us held the iron. Natalie really did most of the installation of the new parts.

Before:

After:

"Rookie makes Rookie Mistake"

The eagle-eyed among you already see why my office smelled like shit all day last Saturday. Of course, tantalums don't note polarity the same way any electrolytic I've dealt with has. So we installed them all backwards.

I know I have seen at least one person mention that while doing a recap and replacing electrolytics with tantalums. In fact, in the box from the company we ordered the replacements from:

So it's not like there weren't ample people trying to get this information into my head. Oh well, happens. Here's the before & after, after the second recap:

I also took the cardboard shield off the high voltage board and saw sticky burnt electrolyte gack on the back of the board. That gack was the smell that took this machine beyond just "nicotine soaked" when you turned it on.

We've removed the high voltage board and will re-cap that in Part 3.

I'm in no position to recommend the hot air station we got, but it was just "not quite the cheapest one on Amazon". Came with some extras like a pair of side cutters and a couple pairs of tweezers, so that was helpful.

xrayspx's picture

Mac Classic - First Impression

Music: 

"Works As Intended" they said....

Unless Craigslist Guy was using a sharpie to play tic-tac-toe on the wavy checkerboard screen, we have different definitions of "intended".

Of course if the intention is that we have a project now, well then Mission Accomplished. Replacement caps are on the way. The board itself looks totally clean aside from the standard nicotine layer gooped everywhere, but no visible corrosion or damage.



xrayspx's picture

PiST

Music: 

Peter Murphy - The Sweetest Drop

*Skip to the RetroPie customization stuff*

Like every other moderately Vintage / Retro Computing person,
not to mention my whole job being what it is, I immediately bought one of those
12" IPS 16:9 Eyoyo monitors when I started seeing them pop up on some YouTube channels. Thing works great as a bench monitor, but it's kind of a weird size for use with 1980s OSes that expect 4:3. I found that Eyoyo also makes a 4:3 12" 800x600 monitor with all the same inputs so I grabbed one. Since the Atari branded monitors for the ST were 12", and I never saw any of these machines on anything much bigger than a 13" TV back in the day, this looks pretty much exactly as I remember and the correct aspect ratio makes everything feel "bigger" in the right way.

The Pi 3 seems to be completely sufficient for emulating a stock 8Mhz 68000, it just needs enough power, swapping a 750ma power supply for 2.5A made a huge speed difference in emulation. I'm not trying to make this a "modern" experience like PiMiga or anything that requires any more horespower. For software, I started with RetroPie for their package management and the fact that they've already done the work of building all their packages to run from the command line with SDL/framebuffer, plus the ease of tweaking things like the boot splash screen, etc.

Aside from that, it's really just Hatari and Amiberry. I found a 1GB ACSI disk image for the ST which is split into thirds and had a bunch of preloaded software. I've not added anything to it yet, but apparently the hero at 8bitchip has also archived over 1500 ST games and has patched them to run from a hard disk so I won't need to sort through a bunch of disk images which is great. I already spotted Oxyd in the list.

That all makes me want to get NeoDesk running, which I gather is possible though it didn't immediately work in the 5 minutes I had to spend on it. Like I said, for this machine I'm not interested in running a "modern" take like PiMiga. But "nostalgia", well, while I'd certainly love to have original ST or Amiga hardware, I really am more nostalgic for the content and getting in front of Vroom or Nebulus for 10 minutes every 2 months, and it's awesome that it's using the same desktop I spent so much time in front of.

The little boot menu I wrote just replaces the RetroPie autostart.sh file at /opt/retropie/configs/all/ with one that shows the user a menu to select the boot OS or shutdown. Windows 3.11 is a menu option, that's kind of TBD. DosBox is installed but I haven't done the full Windows install yet but it'll be fun to play Solitaire on this thing.


Little tweaks I made to RetroPie

I used RetroPie as my base rather than regular Raspbian because of their great packaging and basic customization tools. I just installed Hatari and Amiberry from the retropie_setup installer and they worked immediately at the command line. The retropie_setup tool also lets you swap out the default boot splash screen. I was expecting to just find the location of the file and swap in an Atari Fuji logo and be done with it. But they've built the tool into their setup utility, and even let you assign an MP4 so I was able to use an animated rainbow Fuji logo so it just looks awesome.

I made one edit to /boot/cmdline.txt to suppress the bootup log output, so cmdline.txt looks like this now:

console=serial0,115200 console=tty1 root=PARTUUID=8ee2ea28-02 rootfstype=ext4 fsck.repair=yes rootwait loglevel=3 quiet consoleblank=0 plymouth.enable=0

I copied /opt/retropie/configs/all/autostart.sh out of the way and replaced it with:

#!/bin/bash

/home/pi/bin/menu

That's pointing to the boot menu screen. It's really simple but really what am I trying to do here? I did add a countdown timer so it will automatically boot to an ST desktop after 20 seconds:


#!/bin/bash
# /opt/retropie/configs/all/autostart.sh

clear
echo "POMPEY PIRATES" | sed -e :a -e "s/^.\{1,$(tput cols)\}$/ & /;ta" | tr -d '\n' | head -c $(tput cols)
echo ""
echo ""
echo "Press '1' For Atari ST"
echo "Press '2' For Amiga"
echo "Press '3' For Windows 3.11"
echo "Press '9' For Bash Shell"
echo "Press '0' For Shutdown"
echo "Press 'T' For Trainer"
echo ""
echo ""

msg="Booting Atari ST in"
tput cup 12 0
echo -n "$msg"

l=${#msg}

l=$(( l+1 ))

for i in {15..01}
do
tput cup 12 $l
echo -n "$i Seconds"

read -t 1 -n 1 system 2>/dev/null

if [ "$system" = "1" ]
then
/opt/retropie/emulators/hatari/bin/hatari --timer-d 0 && reset; /home/pi/bin/menu
elif [ "$system" = "2" ]
then
/opt/retropie/emulators/amiberry/amiberry.sh && reset; /home/pi/bin/menu
elif [ "$system" = "9" ]
then
exit 0
elif [ "$system" = "0" ]
then
sudo shutdown -h now
fi

done

/opt/retropie/emulators/hatari/bin/hatari --timer-d 0 && reset; /home/pi/bin/menu


To-Do

  • I'll probably install Windows and Mini vMac just to do it
  • Add ST High Res mode
  • May add a timer to the menu to boot to the ST after some number of seconds just to make it more immersive.
  • Add a "POMPEY PIRATES" at the top and "PRESS 'T' FOR TRAINER" at the bottom for authenticity



  • xrayspx's picture

    Nixie Clock

    Music: 

    Bloodshot Bill - Mary Ann

    Natalie got me a cool nixie clock project for Christmas. We've split duties putting it all together and we just finally got it all worked out and on the shelf.

    Overall the project was pretty easy, though you can see there's one pretty badly folded in place resistor that wasn't in the directions so we had to cram it in last minute. And we had a couple of issues with certain numbers on certain tubes, but it looks great in the end.

    xrayspx's picture

    Lattice of Convenience - MP3 Playlists

    Music: 

    Underworld - Kittens

    Hopefully everyone can live in the future someday.

    We do a lot with MP3 playlists. I run Airsonic for streaming around the house and in the car, and we have a playlist-based FM transmitter setup, etc. So I have scripts which run every night and generate playlists based on star ratings and other things (GET THE LED OUT ANYONE?).

    Previously what I've done is dump the contents of a bunch of Smart Playlists in Clementine to a file and use those files to generate the randomized 200 track daily playlists. The downside to that is that every time I add music or change star ratings, I'd have to refresh these "base" files like some kind of animal. I had base playlists for "3+ stars", "4+ Stars" and "5 Stars", among others.

    Today I decided to fix all that. Clementine uses a SQLite3 database, so now I'm just querying it instead, and it seems to be working well. For example, my "5 star" playlist in Clementine results in 10800 or so tracks. The same one built from the DB ends up with a couple hundred more tracks, but is pretty close. I'm not entirely sure what the difference there is just yet, but "close enough". What it looks like to me is I probably need to enable Samba case sensitivity.

    The DB records ratings as decimal numbers from 0.0 (Zero stars) through 1.0 (5 Stars). So to build a "4-Star +" playlist, searching for rating >= "0.8", you get ratings like this:

    1
    1.10000002384186
    0.800000011920929
    0.800000011920929
    0.800000011920929
    1.10000002384186
    1.10000002384186
    0.800000011920929
    0.800000011920929
    1
    1
    1
    1

    ! Caveat: Prior to Clementine 1.4.0rc1-533-gf4e70face there was a bug where it was possible to give a song a higher than 5 star rating (higher than 1.0 in the DB) as you can see above, so know that if you have Clementine from the repositories, it's likely you have that bug. For instance in the UI, if you want to show all 5 star songs, use "Rating is Greater Than 4.5 Stars" rather than "Rating is Equal to 5 Stars".

    Now I can just have a cron job to copy the master Clementine DB once a day to my server and drop it in next to the playlist generation scripts.

    The downside to all this is speed. When using the Clementine-Generated base playlists, I could be sure all the files actually exist on disk. However while Clementine will only show you files that exist in the UI, it doesn't seem to do a very good job of cleaning the database of stale files which no longer exist. So if you move or rename files, the old DB entries stick around unless you purge it completely and start over from scratch. That means I have to test every single file as I add it to the playlist, which takes time. It takes about 5-8 seconds to generate my 200 track 5-Star M3U file.

    The 5-Star.sh script is below if you'd like to play along at home:

      


    #!/bin/bash

    rm /Volumes/Filestore/CDs/playlists/5\ Stars.m3u

    i=1

    while [ $i -le 200 ]
    do
     file=$(sqlite3 ./clementine.db "select filename from songs where rating > "0.9" order by random() limit 1;" | awk -F "file://" '{print $2}')

     ### Clementine data encodes special characters and accent marks and stuff so I'm using
     ### Joel Parker Henderson's urldecode.sh to undo that: https://gist.github.com/cdown/1163649
     
     data=$(urldecode.sh "$file")
     if [ -f "$data" ]
     then
      ### Have to escape leading brackets because grep treated it as a range and would allow duplicates ###
      ### Can't do that in "data" because \[ isn't in the filename so they'll fail ###

      escaped=$(echo "$data" | sed 's/\[/\\[/g')
      #echo "$escaped"

      ### Avoid duplicates
      match=$(grep -i "$escaped" /Volumes/Filestore/CDs/playlists/5\ Stars.m3u)
      if [ -z "$match" ]
      then
       echo "$data" >> /Volumes/Filestore/CDs/playlists/5\ Stars.m3u
       ((i++))
      fi
     fi
    done

    For the 3+ and 4+ lists, I repeat this main block, but instead each rating dumps into a text file that I randomize into an .m3u at the end. So for the 3-Star + script below, I collect 130 5-star tracks, 45 4-star, and 25 3-star, push them out to a temp file and then cat temp.m3u | sort -R > "./3 Star +.m3u". I could do all this by creating a new table in the database and stuffing tracks into that, but this was faster for me to write and it works well enough:


    #!/bin/bash

    rm /Volumes/Filestore/CDs/playlists/3\ Stars\ +.m3u

    i=1

    while [ $i -le 130 ]
    do
     file=$(sqlite3 ./clementine.db "select filename from songs where rating > "0.9" order by random() limit 1;" | awk -F "file://" '{print $2}')

     ### Clementine data encodes special characters and accent marks and stuff so I'm using
     ### Joel Parker Henderson's urldecode.sh to undo that: https://gist.github.com/cdown/1163649
     
     data=$(urldecode.sh "$file")
     if [ -f "$data" ]
     then
      ### Have to escape leading brackets because grep treated it as a range and would allow duplicates ###
      ### Can't do that in "data" because \[ isn't in the filename so they'll fail ###

      escaped=$(echo "$data" | sed 's/\[/\\[/g')
      #echo "$escaped"

      ### Avoid duplicates
      match=$(grep -i "$escaped" ./3-star-tmp.m3u)
      if [ -z "$match" ]
      then
       echo "$data" >> ./3-star-tmp.m3u
       ((i++))
      fi
     fi
    done

    i=1

    while [ $i -le 45 ]
    do
      file=$(sqlite3 ./clementine.db "select filename from songs where rating >= "0.8" and rating

      ### Clementine data encodes special characters and accent marks and stuff so I'm using
      ### Joel Parker Henderson's urldecode.sh to undo that: https://gist.github.com/cdown/1163649

      data=$(urldecode.sh "$file")
      if [ -f "$data" ]
      then
       ### Have to escape leading brackets because grep treated it as a range and would allow duplicates ###
       ### Can't do that in "data" because \[ isn't in the filename so they'll fail ###

       escaped=$(echo "$data" | sed 's/\[/\\[/g')
       #echo "$escaped"

       ### Avoid duplicates
       match=$(grep -i "$escaped" ./3-star-tmp.m3u)
       if [ -z "$match" ]
       then
        echo "$data" >> ./3-star-tmp.m3u
        ((i++))
       fi
      fi
    done

    i=1

    while [ $i -le 25 ]
    do
      file=$(sqlite3 ./clementine.db "select filename from songs where rating >= "0.6" and rating

      ### Clementine data encodes special characters and accent marks and stuff so I'm using
      ### Joel Parker Henderson's urldecode.sh to undo that: https://gist.github.com/cdown/1163649

      data=$(urldecode.sh "$file")
      if [ -f "$data" ]
      then
       ### Have to escape leading brackets because grep treated it as a range and would allow duplicates ###
       ### Can't do that in "data" because \[ isn't in the filename so they'll fail ###

       escaped=$(echo "$data" | sed 's/\[/\\[/g')
       #echo "$escaped"

       ### Avoid duplicates
       match=$(grep -i "$escaped" ./3-star-tmp.m3u)
       if [ -z "$match" ]
       then
        echo "$data" >> ./3-star-tmp.m3u
        ((i++))
       fi
      fi
    done

    cat ./3-star-tmp.m3u | sort -R > /Volumes/Filestore/CDs/playlists/3\ Stars\ +.m3u

    rm ./3-star-tmp.m3u

    Pages

    Subscribe to RSS - Hacks