Wednesday, March 10, 2021

Integration Testing

I've remained committed to the gluqlo clock for months now, running it all day and night on the zipit as my replacement alarm clock radio. So maybe it's about time I integrated more stuff. Like the music. That's already pretty decent. I can use the alt-home key combo to return to the gmenu2x screen and pull up an internet radio stream in the ziptuner. Then maybe set a sleeptimer and alt-arrow back to the clock screen. The default ebindkeys OnPlay and OnStop scripts provide rudimentary controls via the Play and Stop buttons, even when the clock app is on-screen. Same for the side mounted volume control buttons. Nice, but there's always something more...

I only have a 2GB bleeding edge Openwrt SD card in the alarm clock zipit.  So no space has been available for any music from my personal stash that I meticulously converted from my super awesome record collection. And that got me thinking... Plenty of people have hooked up their zipits to network media players in the past. Maybe it was high time for me to do the same. With that in mind, I launched the python simpleHTTPserver in the music folder on my laptop, and it worked well enough to play some music via wifi on my chromebook. That's a good sign. So I whipped up a script to auto generate album playlists for every folder in the entire music directory tree.  Sadly, I found less success with that on the chromebook than I expected. No can do the playlists?  Oh well. The zipit's my real target anyhow. And it seems mplayer on the zipit can make use of the wifi playlists.

There's issues though -- mplayer runs out of memory on large ogg files, and I need to check if it can handle any of the large mp3 or flac files in the collection. Meanwhile gmu 0.10.1 supports streaming for mp3s and opus, and new source code is available to extend that to the other codecs.  So I tested gmu on a few large mp3s, and it works, but has some limitations.  Mplayer can fetch and use remote .pls files with relative web paths, and it allows spaces in the URLs. Gmu needs a local .pls file with absolute web paths containing %20 instead of spaces in the URLs.  Not a big deal, but then the marquee scroller up top shows the %20 substitutions instead of spaces, which is a bit ugly. It'd be nice if gmu did the %20 substitution for me, or perhaps displayed the TITLE tag in the scroller instead of the URL.

Must tweak my playlist creator script to cut the track numbers from the TITLE tags.

Also gmu fails to refresh most bits on return from other ttys via ALT-arrows. Actually, only the top blue bar with the scrolling status got redrawn.  I got some more to display by cycling through the playlist with the up and down arrow keys.  I’m not sure if it gets an SDL refresh event or somesuch, but it’d be nice if there was some way to trigger a full screen redraw.  Otherwise I normally prefer to keep the stingy redraws, limited to things that are actually changing on-screen in order to maintain the lowest possible cpu usage.  Which reminds me, I still need to dig into the gluqlo code and put it's screen refresh routines on a diet.

 

If you read between the lines you can see the gmu log messages bleeding thru.

The final piece of this puzzle was the front end. For a while I considered hacking the ziptuner, but it turns out the links browser works adequately for searching on the web server for album playlists. You can config it to launch an audio player either in the foreground or background. But I chose to simply save a playlist in a convenient location and quit links before starting the audio, to conserve memory for the playback task.

I wonder if the node server has an option to skip the file permissions on the left.

In my opinion the node.js simple http-server seems a bit smoother than the python one, so I settled on that for now. It passes a unique pls+xml mime ID for playlists that I was able to capitalize on with a new association in the ~/.links/links.cfg file.

    association "music playlist" "application/pls+xml" "getpls %" 21 1

To pull all of this together I created some new glue scripts in /usr/local/bin, and tweaked the existing onPlay and onStop scripts. And then added some new Find and Play gmenu2x apps to work together with the glue scripts and flesh it all out.  Still need to dig up some new icons.  I'm thinking maybe some jukebox icons -- one focused on the jukebox menu for Find, and one with musical notes coming out for Play.  I'm sure the internet already has something like that.


I got pretty lazy with the icons...

For the new scripts I simplified things by always saving the fetched playlist as /tmp/__album.pls and then keeping a permanent __album.pls softlink in the gmu directory that points to the one in /tmp.  There's more work to do, but eventually I should have some new zipit goodies to share here...

 

Update March 20, 2021

Progress is slow, but I did manage to improve the playlist creator script so it strips out the file number prefixes and file extension suffixes when creating TITLE entries in the playlist files.  Looks much cleaner on the gmu playlist screen.
 
 Still need to fix the marquee scroller text up top
 
I also remembered how to pull the new gmu 0.10.2 RC1 sources into the byzantine openwrt build system and compile it.  However the new executable segfaults on the first song in the playlist. Stack overflow in one of the threads, so some debug is required.  Perhaps it's an issue with musl version of libc used on the zipit?  I need to refresh my debug skills and dig into the code.  That should be fun.
 
 
Update March 28, 2021
 
After a few sporadic nights of intense debugging failure I finally found the problem.  The gmu notify frontend is really meant for popup notifications in X11, which is unavailable on a zipit running openwrt.  So the zipit notification thread simply crashed gmu whenever the song track info was updated from embedded tags in the music file.  I suspect notify didn't build in the 0.10.1 release for some reason, and thus was unavailable to muck things up previously.  Once I disabled it in the zipit build configuration for 0.10.2 everything ran just fine.   Perhaps someday I might revisit what sort of notification would be meaningful on a zipit.  Probably not though...
 
Oh well, at least some good came out of the debugging sessions.  In my struggles to remember how to debug properly, I was reminded of various tricks from the good old days.  Like how to run gmu without the SDL display, so it can get along better with the clock.  Simply launch gmu with -p frontends/gmuhttp.so and it'll operate with only the web server frontend, which can be controlled conveniently with gmuc in a remote ssh session.  It can tell gmu to do things like gmuc -u play (or pause) on the command line, or run an ncurses gui for more visual tasks.  Like this.
 
I don't know how to screenshot from the chrome book, but you get the idea...
 
I suspect I may want to toss dtach into the mix for the gmu web server startup, especially if I want to make it fully remote control capable from an ssh session on my chrome book.  But I think that's my end goal.  Leave the gluqlo clock app running pretty much always and control the music remotely from a comfy chair.  So that's my new focus for now.  
 
The first task is to clean up the clock app to not be such a cpu hog.  Gmenu2x got a cpu hog fix a while back and so gmu runs in the background just fine with the gmenu2x app screen (pictured above somewhere) running.  A clock app only needs to update once a minute, so it shouldn't be difficult to fix as well.  But my confidence took a hit in the debug sessions, so who knows...

Also I should do some more testing with the gmu control web page.  I had to disable the gmuhttp.DisableLocalPassword setting to get it to work, but it's pretty nice once you do that.

If only the file browser tab could browse for playlist files from the webserver on my laptop then my work here would be done, I think...

Update April 5, 2021
 

Turns out the clock app was an easy fix.  Simply replace SDL_WaitEvent with an SDL_PollEvent call and include a quarter second SDL_Delay when no event is available.  Runs at less than 1% cpu now, as expected.  The SDL wait and the SDL timer functions appear to be busy loops of some sort on the zipit.  Same for the pthread cond_wait functions.  Must be something odd in the musl libc implementation we're using.  Maybe an openwrt musl update would help?

Anyhow, that let the music play, even with gmu running in the background behind the clock.  However gmu still needed work as it was hogging over 70% of the cpu.  I got it down to 60%  by eliminating the SDL timer init whenever I excluded the sdl frontend with a -p frontends/gmuhttp.so command line option.  Then I realized I could save another 10% by eliminating all frontends with a -p dummy option.  

There's gmu.bin at 52% up top, gluqlo at 0% in the middle, and dtach down below.

But all that effort left me with no interface to control it with.  Until I realized the code was already handling the SIGINT and SIGTERM signals as a way to do a clean shutdown.  So I expanded that to include SIGSTOP, SIGUSR1, and SIGUSR2 to provide basic pause, prev, and next functionality via signals sent by the killall command.  Then I created a half dozen simple scripts in /usr/local/bin and recycled the media app buttons from IZ2S to run them.  Looks pretty functional...

I'm undecided about that ambiguous looking pause/play icon with the bar and arrow.

After a round of testing I realized I sorely missed the "now playing" screens from the web and gmuc frontend interfaces that I'd eliminated in the lean and mean setup.   So I added a handler for the unused SIGSYS signal to dump some now playing text to a file in /tmp.

It's simple, but it works.

I also found a convenient spot in the code to fix all the %20 text in the "now playing" song title from the web playlists.  You can see the result on the PLAYING line of the gmuinfo text above, and also in the marquee scroller on the SDL GUI.  Yes, you can actually read it now.  I also tweaked the code to skip the current song and playlist autosave options whenever a playlist is passed on the command line.  That makes so much more sense for my purposes.   To add the finishing touch I gave the gmuinfo script a ziptuner msgbox dialog style makeover, because I like it, and it was easy -- only 3 more lines of script code.

That purple border really hits the spot.

I think I'm getting to the point where some goodies should be made available.  So expect something of that nature shortly...


And, just like that...gmu is now on github, so I forked and added my patches.

I also made a pre-release executable tarball just in case anyone is desperate to try it.

And I stashed a substitute playlist fetcher script in my scriptuner repo.  It's a bit nicer than repurposing the links browser for that job.