It is the 1727th of March 2020 (aka the 21st of November 2024)
You are 3.145.108.43,
pleased to meet you!
mailto:blog-at-heyrick-dot-eu
96.4 The Eagle, on RISC OS
When I used to live in the UK, a radio station that I listened to frequently was The Eagle (96.4FM in the Guildford area). The selection of music is fairly heavily slanted towards the '80s and I don't think I've ever heard anything that resembles rap on the station. It's sort of easy listening for the Lost Generation (GenX), though they will play new songs if they fit in the general ambience of the station.
For a long time it was blocked to people living outside of the UK. I tried it on a whim a couple of days ago and their website streamed to my iPad. I figured this was a good start to see if I could get the station playing on RISC OS.
After some poking around, I discovered that the base URL for the stream is http://str1.sad.ukrd.com/eagle, but this won't work directly with !DigitalCD because it is a redirect. The server responds with:
HTTP/1.1 302 Found
Date: Sat, 05 Mar 2016 15:23:04 GMT
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.6.17
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Location: http://fg2.sad.ukrd.com/eagle?ts=123456789
Content-Length: 0
Connection: close
Content-Type: audio/mpeg
Now, we can't just point ourselves at the fg2 server because not only does the server vary (load balancing?) but most importantly the ?ts=123456789 is actually a number valid for your connection, and a change of IP address, or not listening for a few minutes, causes the number to be invalid.
The next complication is that there is no programmatic way to alter DigitalCD's playlist entries on the fly.
As such, what we need is a little program that will run just before DigitalCD that will retrieve the connection link and modify the playlist file. Thus, when DigitalCD loads its playlist, it will be able to pick up a valid link to the station.
| Find out The Eagle's current link
Run DigitalCD:EagleFinder
And now here is the EagleFinder program itself:
REM >EagleFinder
REM
REM Find where 96.4 The Eagle is, and patch the DigitalCD playlist
REM
REM By Rick Murray, 2016/03/03
REM
REM If it works, the playlist is updated and the previous copied as "PrevPlaylist".
REM If it fails, we just exit...
ON ERROR PRINT REPORT$+" at "+STR$(ERL) : END
REM TRACE ON
DIM buffy% 4095 : REM 4K buffer
domain$ = "str1.sad.ukrd.com" : REM Domain to fetch from
path$ = "/eagle" : REM What to fetch (path)
port% = 80 : REM Port (80 = HTTP)
handle% = 0 : REM Socket handle
ip% = 0 : REM IP address
rb% = 0 : REM Resolver data block
edited% = FALSE : REM Existing entry edited?
REM Ensure Stack is loaded
SYS "XOS_SWINumberFromString", 0, "Socket_Creat" TO swi%
IF swi% <> &41200 THEN END : REM No stack loaded
REM Ensure Resolver is loaded. This is a little different because the
REM various resolvers share SWI numbers but have different names.
SYS "XOS_SWINumberToString", &46000, buffy%, 64
swi$ = FNGetStringAtAddress(buffy%, 0)
IF swi$ = "User" THEN END : REM No resolver loaded
REM Resolve the domain
REPEAT
SYS "XResolver_GetHost", domain$ TO stat%, rb% ; flag%
IF (flag% AND 1) = 1 THEN END
UNTIL stat% <> 36 : REM "EINPROGRESS"
REM ##TODO## Timeout?
IF rb% = 0 THEN END : REM Unable to resolve domain
ip% = !(!(rb%!16)) : REM Yikes!
REM Create socket
SYS "Socket_Creat", 2, 1, 0 TO handle%
IF handle% = -1 THEN END : REM Unable to connect socket (ish...)
REM Connect to the remote machine
buffy%!0 = 2 OR ((port% DIV 256) << 16) OR ((port% MOD 256) << 24)
buffy%!4 = ip%
buffy%!8 = 0
buffy%!12 = 0
SYS "XSocket_Connect", handle%, buffy%, 16, 0 TO ; flag%
IF ((flag% AND 1) = 1) THEN
SYS "Socket_Close", handle%
handle% = 0
END : REM Connection refused (most likely)
ENDIF
REM Send our request
$buffy% = "GET "+path$+" HTTP/1.0"+CHR$(10)
$buffy%+= "Host: "+domain$+CHR$(10)
$buffy%+= "Accept: */*"+CHR$(10)
$buffy%+= "User-Agent: EagleFinder/0.1; RISC OS 5"+CHR$(10)+CHR$(10)
SYS "Socket_Write", handle%, buffy%, LEN($buffy%)
REM We don't poll (as we're running prior to DigitalCD starting up)
REM so waste a second to give time for the server to reply.
SYS "Hourglass_Start", 1
t% = TIME
REPEAT : UNTIL ((t% + 100) < TIME)
SYS "Hourglass_Off"
REM Read the first 160 bytes and discard them (early HTTP header stuff)
SYS "XSocket_Read", handle%, buffy%, 160 TO size% ; flag%
REM Now read 255 bytes. This part contains what we want to look at
FOR t% = 0 TO 255 : buffy%?t% = 0 : NEXT : REM Ensure buffer is empty
SYS "XSocket_Read", handle%, buffy%, 255 TO size% ; flag%
IF ( (flag% AND 1) OR (size% = -1) ) THEN
REM Failed!
SYS "Socket_Shutdown", handle%, 2
SYS "Socket_Close", handle%
END
ENDIF
reply$ = FNGetStringAtAddress(buffy%, 0)
posn% = INSTR(reply$, "Location:")
IF (posn% = 0) THEN END : REM No "Location:" found
posn% += 10 : REM Skip "Location:"
reply$ = MID$(reply$, posn%)
$buffy% = reply$
reply$ = FNGetStringAtAddress(buffy%, 13) : REM Lame-ass way to trim line ;-)
REM PRINT reply$ : REM ^^ Server appears to reply <13><10>!
REM At this stage, reply$ will contain the "new" URL.
REM Back-up current playlist.
OSCLI("%Copy <Choices$Dir>.DigitalCD.PlayList <Choices$Dir>.DigitalCD.PrevPlayList ~C~DF~N~P~Q~S~V")
REM Don't confirm, don't delete original, force, not 'only if newer',
REM don't prompt, not quick, don't stamp, not verbose.
REM In other words, shuddup and copy it.
REM Open the files (Prev for reading from, main for writing to)
REM This is accessing Choices incorrectly (Choices: / Choices$Write)
REM because I know the file has read/write access AND I want to be
REM sure to edit the original...
in% = OPENIN("<Choices$Dir>.DigitalCD.PrevPlayList")
out% = OPENOUT("<Choices$Dir>.DigitalCD.PlayList")
REM Copy line by line, checking for "ukrd"
REPEAT
inline$ = GET$#in%
IF (INSTR(inline$, "ukrd") <> 0) THEN
REM Found, so update with it
inline$ = GET$#in% : REM Discard next line
posn% = INSTR(reply$, "eagle") : REM Find the split point
BPUT#out%, LEFT$(reply$, (posn% - 1)) : REM Line1 - domain
BPUT#out%, MID$(reply$, posn%); : REM Line2 - path + check value
BPUT#out%, "*aUKRD,f257,r128,t96.4 Eagle,v85" : REM Line2 - other stuff
edited% = TRUE
PRINT "Eagle edited."
ELSE
REM Just copy the line to the output
BPUT#out%, inline$
ENDIF
UNTIL EOF#in%
IF (edited% = FALSE) THEN
REM There wasn't a copy to edit, so append new...
posn% = INSTR(reply$, "eagle") : REM Find the split point
BPUT#out%, LEFT$(reply$, (posn% - 1)) : REM Line1 - domain
BPUT#out%, MID$(reply$, posn%); : REM Line2 - path + check value
BPUT#out%, "*aUKRD,f257,r128,t96.4 Eagle,v85" : REM Line2 - other stuff
PRINT "Eagle appended."
ENDIF
REM Close files
CLOSE#in%
CLOSE#out%
REM And the socket...
SYS "Socket_Close", hande%
REM We're done.
SYS "Wimp_CommandWindow", -1
END
:
DEFFNGetStringAtAddress(array%, term%)
LOCAL s$
s$ = ""
WHILE (?array% <> term%)
s$ += CHR$(?array%)
array% += 1
ENDWHILE
=s$
Basically, this will directly modify the playlist to either replace an older entry, or to append it if it doesn't exist. If there are any problems, it will exit without doing anything. The program will briefly flash up a message saying that the Eagle has been modified or appended, as applicable. You won't get enough time to read it, but if the screen flashes and redraws upon starting DigitalCD, you'll know the update worked.
I ought to work for you. Things are trickier for me as I'm using WiFi through a metre-and-a-half thick stone wall, so the signal can be a little flaky in rainy/damp weather, but I've been listening to the station a fair bit yesterday and today and the Vonets WiFi adaptor picks up the weak signal better than the iPad...
The Eagle is part of the UKRD group, so while I have not tested it, you may be able to modify this program for the following local stations:
2BR (Lancashire)
96.4 Eagle (Guildford)
Eagle 3 (DAB)
Escape to Cornwall (DAB)
Juice 107.2 (Brighton)
KL.FM 96.7 (Norfolk)
Minster FM (York)
Mix 96 (Alyesbury)
More Minster (DAB)
North Yorkshire Oldies (DAB)
Oldies Sussex (DAB)
Pirate FM (Redruth)
Pirate 2 (DAB)
Pirate Oldies Cornwall (DAB)
Pirate Oldies Plymouth (DAB)
Spire FM (Salisbury)
Spire - Whites Live (DAB)
Spirit FM (Chichester)
Star Radio (Cambridge)
Star Radio North East (Darlington)
Stray FM (Harrogate)
Stray Extra (DAB)
Sun FM (Sunderland)
The Bee (Lancashire)
Wessex Beats (DAB)
Wessex FM (Dorchester)
Yorkshire Coast Radio (Scarborough)
Yorkshire Coast DAB (DAB)
You can pick up the base links at http://str1.sad.ukrd.com/, with playlist details for Windows/Android/etc media players, or the raw stream for parsing with EagleFinder on RISC OS.
Observation: I've not been in the UK since early 2002 and... The Guildford Flames (ice hockey) are still kicking ass, and The Ripley Bypass (A3 near Wisley) is still a traffic disaster at rush hour. There is a Little Chef nearby, in case the traffic gets too much of a pain in the backside. Some things never change...
Your comments:
Please note that while I check this page every so often, I am not able to control what users write; therefore I disclaim all liability for unpleasant and/or infringing and/or defamatory material. Undesired content will be removed as soon as it is noticed. By leaving a comment, you agree not to post material that is illegal or in bad taste, and you should be aware that the time and your IP address are both recorded, should it be necessary to find out who you are. Oh, and don't bother trying to inline HTML. I'm not that stupid! ☺ ADDING COMMENTS DOES NOT WORK IF READING TRANSLATED VERSIONS.
You can now follow comment additions with the comment RSS feed. This is distinct from the b.log RSS feed, so you can subscribe to one or both as you wish.
This web page is licenced for your personal, private, non-commercial use only. No automated processing by advertising systems is permitted.
RIPA notice: No consent is given for interception of page transmission.